#Needing help with Tally and Ballot class

48 messages · Page 1 of 1 (latest)

whole ocean
#

`#include <iostream>

using namespace std;

class Ballot {
public:

Ballot() {
for (int i = 0; i < num_candidates; ++i) {
preferences[i] = 0;
}
}
private:

};

class Tally {
public:
Tally(int num_candidates, int num_ballots):
num_candidates(num_candidates), num_ballots(num_ballots) {
for (int i = 0; i < num_candidates; ++i) {
votes[i] = 0;
}
}

void resolve_vote(int ballots[][num_candidates]) {
while (no_winner_yet() && election_still_valid()) {
update_prefs(ballots);
get_losers();
eliminate_losers();
}

int winner = get_winner();
if (winner == NO_WINNER) {
  cout << "The election is inconclusive." << endl;
} else {
  cout << "The winner is: " << winner << endl;
}

}

private:
int num_candidates;
int num_ballots;
int votes[num_candidates];

void update_prefs(int ballots[][num_candidates]) {
for (int i = 0; i < num_ballots; ++i) {
int first_choice = ballots[i][0];
votes[first_choice]++;
}
}

bool no_winner_yet() {
// Logic to determine if there is a winner
return false; // Placeholder, implement your logic here
}

bool election_still_valid() {
// Logic to check if the election is still valid
return false; // Placeholder, implement your logic here
}

void get_losers() {
// Logic to determine the losers
}

void eliminate_losers() {
// Logic to eliminate the losers
}

int get_winner() {
// Logic to determine the winner
return NO_WINNER; // Placeholder for now
}
};

int main() {
int num_candidates = 0;
cin >> num_candidates;
cout << num_candidates << " Candidates (Columns for each stage of the vote)" << endl; // test
int num_ballots = 0;
cin >> num_ballots;
cout << num_ballots << " Ballots (Iterate through each row for each round)"<< endl; // test

Tally tal(num_candidates, num_ballots);
tal.resolve_vote(ballots);

return 0;
}
`

low boltBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

whole ocean
#

Currently working on this code to create an rcv style election to determine if the vote is inconclusive or stating the winner itself

#

I've got everything else down, just have to tinker with the Ballot and Tally class

#

Only issue is that I'm struggling to find a way to make my input into an array or arrays to do the actual vote counting

#

The text file input looks like this:
6 7
1 5 0 3 4 2
1 2 3 4 5 0
0 1 3 2 4 5
0 5 1 2 3 4
2 4 0 1 3 5
3 0 1 5 4 2
2 5 4 0 3 1

olive flame
#

!code

low boltBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {}
whole ocean
#

The first two numbers at the top are for looping around the supposed arrays but I just am having trouble making the arrays themself

#

Wondering if it should just be multiple arrays or one large array

olive flame
#
#include <iostream>

using namespace std;

class Ballot {
public:

  Ballot() {
    for (int i = 0; i < num_candidates; ++i) {
      preferences[i] = 0;
    }
  }
private:

};

class Tally {
public:
  Tally(int num_candidates, int num_ballots):
       num_candidates(num_candidates), num_ballots(num_ballots) {
    for (int i = 0; i < num_candidates; ++i) {
      votes[i] = 0;
    }
  }

  void resolve_vote(int ballots[][num_candidates]) {
    while (no_winner_yet() && election_still_valid()) {
      update_prefs(ballots);
      get_losers();
      eliminate_losers();
    }

    int winner = get_winner();
    if (winner == NO_WINNER) {
      cout << "The election is inconclusive." << endl;
    } else {
      cout << "The winner is: " << winner << endl;
    }
  }

private:
  int num_candidates;
  int num_ballots;
  int votes[num_candidates];

  void update_prefs(int ballots[][num_candidates]) {
    for (int i = 0; i < num_ballots; ++i) {
      int first_choice = ballots[i][0];
      votes[first_choice]++;
    }
  }

  bool no_winner_yet() {
    // Logic to determine if there is a winner
    return false; // Placeholder, implement your logic here
  }

  bool election_still_valid() {
    // Logic to check if the election is still valid
    return false; // Placeholder, implement your logic here
  }

  void get_losers() {
    // Logic to determine the losers
  }

  void eliminate_losers() {
    // Logic to eliminate the losers
  }

  int get_winner() {
    // Logic to determine the winner
    return NO_WINNER; // Placeholder for now
  }
};

int main() {
  int num_candidates = 0;
  cin >> num_candidates;
  cout << num_candidates << " Candidates (Columns for each stage of the vote)" << endl; // test
  int num_ballots = 0;
  cin >> num_ballots;
  cout << num_ballots << " Ballots (Iterate through each row for each round)"<< endl; // test

  Tally tal(num_candidates, num_ballots);
  tal.resolve_vote(ballots);

  return 0;
}
#

That code doesn't compile btw

whole ocean
#

It's incomplete

olive flame
#

I see

whole ocean
#

I was told specifically to not use any cin in the Tally class so all input that I get from the file has to be in the Ballot class

olive flame
whole ocean
#

Yes

olive flame
#

I mean you could either use a 1d-array with a custom index translater or you just use a 2d-array (or for your case you could just use a 2d-vector and basically ignore the first two numbers)

#

Something like std::vector<std::vector<int>> should do the trick I suppose

whole ocean
#

That's what I thought at first until my professor told me I am not allowed to use vectors for this

olive flame
#

Also I'm very sceptical about this line: int votes[num_candidates];

whole ocean
#

I was thinking a 2D array as well

olive flame
#

Yeah, it also doesn't even compile:

error: invalid use of non-static data member 'Tally::num_candidates'x86-64 gcc 13.2 #1
whole ocean
olive flame
whole ocean
#

Nope

#

And it's upsetting with how much easier this would be if my professor didn't put so many restrictions on this

olive flame
#

Can you do something like this for the columns?:
std::unique_ptr<int[]> (declaration) and std::make_unique<int[]>(columns) (creation)

whole ocean
#

I believe I can

olive flame
#

Okay, for the sake of readability I'd probably create a class for each row:

#include <memory>

struct Row {
    Row() : values{nullptr} {}
    Row(std::size_t size) : values{std::make_unique<int[]>(size)} {}

    /* some helper methods to set all the values or to resize */

    private:
    std::unique_ptr<int[]> values;
};
```and then you can do something similar with a `std::unique_ptr<Row[]>` to get all the rows.
#

Obviously you can and should choose better names than Row or values, but yeah this is just an example

whole ocean
#

I'll look into it

whole ocean
#

Might have found a simpler array method to use instead but still testing it

#

`int vote[ROWS][COLS];

// Read the numbers from stdin (cin)
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
cin >> vote[i][j];
}
}

// Print the vote
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
cout << vote[i][j] << " ";
}
cout << endl;
}

cout << endl;
for(int i = 0; i < ROWS; ++i)
cout << vote[i][0] << endl;

return 0;
}`

#

I think this could work

#

This code is assuming I already taken the two numbers from the top row

#

And placed them as variables as ROWS and COLS

olive flame
#

!vla

low boltBOT
# olive flame !vla
What Is a VLA, and Why Is It "Bad"?

A Variable Length Array (VLA) is an array where the size is not constant and depends on a variable.

Example
int size = rand();
int vla[size]; // VLA of type int[size]
int not_vla[10]; // regular array of type int[10]
constexpr int size = 10;
int arr[size]; // also not a VLA, of type int[10]
Why Are VLAs "Bad"?

VLAs have poor compiler support and can lead to unsafe code. The core issue with VLAs is that the compiler doesn't know the size of the stack frame. Without warning flags like -Wvla, it can be easy to create a VLA by accident, even in C++ with some compilers.

Compiler Support

:white_check_mark: available since C99
:no_entry: not available in C++ at all
:no_entry: was never supported by MSVC
:warning: optional feature since C11
:warning: supported as non-standard extension by GCC, clang

olive flame
#

Also please format your code properly

#

I.e. instead of 1 backtick please place 3

#

And preferably you even add cpp after the initial 3 backticks like e.g. so:

```cpp
int main() {
std::cout << "Hi mom\n";
}
```

to get this output:

int main() {
    std::cout << "Hi mom\n";
}
#

Also I see that you apprently have done using namespace std which is yet another bad habit

#

!wiki Why Is using namespace std Considered Bad Practice?

low boltBOT
# olive flame !wiki Why Is `using namespace std` Considered Bad Practice?
Why Is `using namespace std` Considered Bad Practice?

using namespace std will import all the symbols from std into the enclosing namespace. This can easily lead to name collisions, as the standard library is filled with common names: get, count, map, array, etc.

A key concern with using namespace std; is not what is imported now but rather what may suddenly be imported in the future.

While using namespace std; is alright for tiny projects, it is important to move away from it as soon as possible. Consider less intrusive alternatives:

// OK: *only* import std::vector
using std::vector;
// OK: namespace alias
namespace chr = std::chrono;
chr::duration x;
whole ocean
#

I'm using namespace since my professor wants us to use it in out code

whole ocean
#

Yeah I can't using std:: since my professor wants us to keep using namespace