I am designing a voting system with Python that uses the only transferable voting rule (STV), where a user can classify candidates from 1 to 4. Once a user votes, their choices are saved directly in SQLite tables called Votes of President, Faculty or Officer. The options are saved as real names of the candidates in the above tables, so I need a way to count all the votes and then find out who has come first and fourth and then present the results for each candidate.
The difficulty I am having is creating a function to reduce the repetitive code. There are a total of 4 candidates for the position of President (1 President), 12 for the positions of Officer (3 Officers) and 64 candidates for the Faculty Officers (16 Faculty Officers but 64 Candidates may apply for the positions). My code so far is shown below:
conn = sqlite3.connect("VotingDatabase.db")
c.execute("SELECT * FROM PresidentVotes")
president_votes = ()
for column in c:
president_votes.append(PresidentVotes(voting_id=column(0), student_username=column(1), first_preference=column(2),
def create_obj(name, position, faculty, voting_list):
:param name: Name of the candidate as a string
:param position: Position of the candidate as a string
:param faculty: Faculty of the candidate as a string
:param voting_list: Voting objects saved as a list
:return: Iterates through the voting list and creates an instance of the Results class
first = 0
second = 0
third = 0
fourth = 0
for column in voting_list:
if column.first_preference == name:
first += 1
elif column.second_preference == name:
second += 1
elif column.third_preference == name:
third += 1
elif column.fourth_preference == name:
fourth += 1
return Results(name, position, faculty, first, second, third, fourth)
indi_franklin = create_obj("Indi Franklin", "President", "SB", president_votes)
andrei_keely = create_obj("Andrei Keely", "President", "SB", president_votes)
esther_barracks = create_obj("Esther Barracks", "President", "ES", president_votes)
As mentioned, there are two other very similar SQLite tables that I must read from FacultyVotes and OfficerVotes with name, and again create objects from them (I have not shown there due to the space here). Below is an example of my code to find the winner for the position of president:
# global pres_first_preference
globals()("first_preference_winner") = ""
globals()("second_preference_winner") = ""
globals()("third_preference_winner") = ""
globals()("fourth_preference_winner") = ""
# If Indi Franklin was first preference
if (indi_franklin.first_preference > andrei_keely.first_preference and indi_franklin.first_preference >
esther_barracks.first_preference and indi_franklin.first_preference > ryan_hays.first_preference):
globals()("first_preference_winner") = indi_franklin
# If Andrei was first preference
elif (andrei_keely.first_preference > indi_franklin.first_preference and andrei_keely.first_preference >
esther_barracks.first_preference and andrei_keely.first_preference > ryan_hays.first_preference):
globals()("first_preference_winner") = andrei_keely
# if Ryan was first preference
elif (ryan_hays.first_preference > andrei_keely.first_preference and ryan_hays.first_preference >
indi_franklin.first_preference and ryan_hays.first_preference > esther_barracks.first_preference):
globals()("first_preference_winner") = ryan_hays
# if Esther Barracks was first preference
elif (esther_barracks.first_preference > indi_franklin.first_preference and esther_barracks.first_preference >
ryan_hays.first_preference and esther_barracks.first_preference > andrei_keely.first_preference):
globals()("first_preference_winner") = esther_barracks
# if there is a tie between two or more results go to second preference
elif (esther_barracks.first_preference == indi_franklin.first_preference or esther_barracks.first_preference ==
ryan_hays.first_preference or esther_barracks.first_preference == andrei_keely.first_preference or
indi_franklin.first_preference == ryan_hays.first_preference or ryan_hays.first_preference ==
andrei_keely.first_preference or andrei_keely.first_preference == indi_franklin.first_preference):
# If Indi Franklin was second preference
if (indi_franklin.second_preference > andrei_keely.second_preference and indi_franklin.second_preference >
esther_barracks.second_preference and indi_franklin.second_preference > ryan_hays.second_preference):
globals()("second_preference_winner") = indi_franklin
In the code above, I am working through objects (examples of how to create the objects above) are shown to find the winner. If there is no winner in a preference, then I continue with the following preference. If there is a winner, I assign the candidate object to a variable, so that I can generate the results easily.
Again, the problem with this code is that it is too repetitive: I have to create 80 objects initially for each candidate and then use these objects to find the candidates they won. I have tried to create a function for all positions, but all have a different number of candidates, therefore, different amounts of if statements. The presiding officer has four blocks of if statement to find the winner. Trying to do this with the Officers or Officers of the Faculty would be even more code!
I hope the above is clear enough and I would really appreciate any help to minimize the previous legacy program.