Created
November 22, 2021 17:44
-
-
Save jallspaw/4728dcc8c89b89d262cbb9828e343636 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Project 1b - Voting Booth | |
# Sadie Allspaw -- period 10 | |
#### PEER FEEDBACK | |
# No major bugs, but it didn’t specify how it counted votes entered that weren’t the candidate | |
# There are no bugs that I ran into | |
# I didn’t notice any. | |
ballot = [] # start the list off as empty | |
#### making the ballot ####### | |
# display candidaties | |
def display_candidates(): | |
option_number = 0 | |
for name in ballot: | |
# linebreaks used to make it look nicer | |
print("\noption", str(option_number + 1) + ":", ballot[option_number], "\n") | |
option_number += 1 | |
# add a candidate | |
def add_candidate(candidate): | |
ballot.append(candidate) | |
# ask the user if they want to display the current list of candidates | |
def ask_to_display(): | |
want_to_display = input("Do you want to see your current candidate list?\ny = yes, n = no\n>") | |
if ballot == []: # this is the option I would put if they didn't submit a candidate yet | |
print("Please add a candidate first") | |
elif want_to_display == "y": | |
display_candidates() # notice I don't have an 'else' because if they don't want to view the list, I'll just move onto the next thing | |
# form candidate list | |
def form_ballot(): | |
not_done = True # keep going until user says they are done | |
while not_done == True: | |
if len(ballot) >= 2 and len(ballot) < 10: | |
print(""" | |
enter 1 to add a candidate | |
enter 2 to view candidate list | |
enter 3 to move onto voting | |
""") | |
option_chosen = input("> ") | |
if len(ballot) < 10: | |
if option_chosen == "1": | |
# this distinction is only so the wording is more elegant | |
new_candidate = input("What new candidate would you like to add?\n> ") | |
ballot.append(new_candidate) | |
# if len(ballot) == 0: | |
# new_candidate = input("What do you want your first candidate to be?\n> ") | |
# else: | |
# new_candidate = input("What do you want your next candidate to be? \n> ") | |
elif option_chosen == "2": | |
display_candidates() | |
elif option_chosen == "3": | |
if len(ballot) < 2: | |
print("You must have at least 2 candidates") | |
else: | |
not_done = False | |
else: | |
print("please enter 1, 2, or 3") | |
else: | |
print("You have exceeded the limit of 10 candidates, sorry :(") | |
not_done == False | |
elif len(ballot) < 2: | |
while len(ballot) < 2: | |
print(""" | |
enter 1 to add a candidate | |
enter 2 to view candidate list | |
""") | |
option_chosen = input("> ") | |
if option_chosen == "1": | |
new_candidate = input("What new candidate would you like to add?\n> ") | |
ballot.append(new_candidate) | |
if option_chosen == "2": | |
display_candidates() | |
##### lists of votes ####### | |
# get current totals | |
# current totals -- starts off as amount of people that voted for 1st place, then adding the votes of those whose higher choice candidates were eliminated | |
def get_ini_current_total(candidate): | |
current_total = tally[ballot.index(candidate)][1] | |
return current_total | |
# these are where the votes will be stored -- this is why there is a limit of 10 candidates | |
votes_c1 = [] | |
votes_c2 = [] | |
votes_c3 = [] | |
votes_c4 = [] | |
votes_c5 = [] | |
votes_c6 = [] | |
votes_c7 = [] | |
votes_c8 = [] | |
votes_c9 = [] | |
votes_c10 = [] | |
list_of_vote_collections = [votes_c1, votes_c2, votes_c3, votes_c4, votes_c5, votes_c6, votes_c7, votes_c8, votes_c9, votes_c10] | |
# tally means that if a candidate was ranked first 3 times and 2nd 6 times then their list would look like [3, 6] | |
tally_c1 = [0, 0] | |
tally_c2 = [0, 0] | |
tally_c3 = [0, 0] | |
tally_c4 = [0, 0] | |
tally_c5 = [0, 0] | |
tally_c6 = [0, 0] | |
tally_c7 = [0, 0] | |
tally_c8 = [0, 0] | |
tally_c9 = [0, 0] | |
tally_c10 = [0, 0] | |
tally = [tally_c1, tally_c2, tally_c3, tally_c4, tally_c5, tally_c6, tally_c7, tally_c8, tally_c9, tally_c10] | |
###### voting ###### | |
# this gets the user's ranking for the candidates | |
def get_rank(rank_number): | |
for person in ballot: | |
print("What is your #" + str(rank_number), "choice?") | |
candidate_voted = input("> ") # "which candidate is your #1 choice?" | |
return candidate_voted | |
# this takes the user's rank and puts it into the dictionary for that candidate | |
def add_vote(candidate, rank): | |
if candidate in ballot: | |
list_pos = 0 | |
for person in ballot: # for each candidate in the ballot, by list position (iterate thru) | |
if candidate == ballot[list_pos]: | |
candidate_list = list_of_vote_collections[list_pos] | |
candidate_list.append(rank) | |
list_pos += 1 | |
else: | |
list_pos += 1 | |
else: | |
print("That candidate isn't in your ballot.") | |
return | |
# keep track of amount of ballots bc not every ballot needs every candidate | |
# this puts "get rank" and "add vote" together to fill out the ballot | |
def fillout_ballot(): | |
current_rank = 1 | |
still_ranking = True # equals false when they want to stop filling it out | |
while still_ranking == True: | |
for person in ballot: | |
candidate = get_rank(current_rank) | |
add_vote(candidate, current_rank) # this adds the vote to the list fot the candidate | |
current_rank += 1 | |
# this makes sure you only vote for however many candidates you have | |
if current_rank > len(ballot): | |
still_ranking = False | |
return | |
def vote(): | |
still_voting = True | |
num_of_ballots = 0 | |
while still_voting == True: | |
display_candidates() | |
fillout_ballot() | |
num_of_ballots += 1 | |
want_to_keep_voting = input("Would you like to submit another ballot?\n y = yes n = no\n> ") | |
# this makes it so that the user can submit as many ballots as they want | |
if want_to_keep_voting == "n" or want_to_keep_voting == "N": | |
still_voting = False | |
##### results ####### (smaller functions) | |
# this tallies up amount of times ranked 1st, then 2nd, and so on by using a list of lists | |
# the round tells us whether we are counting how many times they were voted first, second, third, or any other place | |
# remember : the round is the place in the list + 1, index 0 in the list corresponds to ranked first | |
c_total_c1 = 0 | |
c_total_c2 = 0 | |
c_total_c3 = 0 | |
c_total_c4 = 0 | |
c_total_c5 = 0 | |
c_total_c6 = 0 | |
c_total_c7 = 0 | |
c_total_c8 = 0 | |
c_total_c9 = 0 | |
c_total_c10 = 0 | |
current_totals = [c_total_c1, c_total_c2, c_total_c3, c_total_c4, c_total_c5, c_total_c6, c_total_c7, c_total_c8, c_total_c9, c_total_c10] | |
eliminated_candidates = [] | |
def tally_up(round_num): | |
count = 0 # keep track of which candidate we are on | |
for person in ballot: # iterate thru candidates | |
# a candidate list includes all the rankes they recieved, while the candidate tally includes all the ranks of what type they recieved | |
person_index = ballot.index(person) | |
candidate_list = list_of_vote_collections[person_index] | |
candidate_tally = tally[person_index] | |
tally[person_index][0] = person | |
# if it doesnt have for this round yet add an item thats value is 0 | |
if len(candidate_tally) < round_num + 2: | |
# add a new slot | |
candidate_tally.append(0) | |
for number in candidate_list: | |
# check if it's equal to the current round # | |
if number == round_num: | |
candidate_tally[round_num] += 1 | |
# add 1 | |
count += 1 | |
# this is to see the maximum amount of people someone voted for | |
def get_longest_ballot(): | |
list_of_ballot_lengths = [] | |
for ballot in list_of_vote_collections: | |
ballot_len = len(ballot) | |
list_of_ballot_lengths += ballot_len | |
return max(list_of_ballot_lengths) | |
# this gets the total amount of votes for one rank e.g: how many times anyone was ranked 1st, or 2nd, or 3rd, and so on... | |
def get_all_votes(): | |
all_votes = 0 | |
for total in current_totals: | |
if total != -1: | |
all_votes += total | |
return all_votes | |
# does anyone have 50% of the vote or more? | |
def have_majority(): | |
# if false: no majority | |
is_there_majority = 0 | |
all_votes = get_all_votes() | |
# does any candidate have the majority? | |
for total in current_totals: | |
if total > all_votes / 2: | |
person_with_majority = total | |
is_there_majority = 1 | |
if is_there_majority == False: | |
person_with_majority = 0 | |
return person_with_majority, is_there_majority | |
# find the candidate w the least current total | |
def find_loser(): | |
# this gets all of the current totals together in a list | |
comparing_list = [] | |
for candidate in ballot: | |
candidate_num = ballot.index(candidate) | |
current_total = current_totals[candidate_num] | |
# only add to candidates being considered if they are still in the running | |
if candidate not in eliminated_candidates and current_total >= 0: | |
candidate_num = ballot.index(candidate) | |
can_current_total = current_totals[candidate_num] | |
comparing_list.append(can_current_total) | |
if have_majority()[0] != 0: | |
# this finds the smallest of all the current totals | |
votes_loser_got = min(comparing_list) | |
candidate_num = current_totals.index(votes_loser_got) | |
loser = ballot[candidate_num] | |
else: | |
loser = 0 | |
return loser | |
# find the winner | |
def find_winner(): | |
# this gets all of the current totals together in a list | |
comparing_list = [] | |
for candidate in ballot: | |
can_current_total = current_totals[ballot.index(candidate)] | |
comparing_list.append(can_current_total) | |
# this finds the biggest of all the current totals | |
votes_winner_got = max(comparing_list) | |
candidate_num = comparing_list.index(votes_winner_got) | |
winner = ballot[candidate_num] | |
return winner | |
# take the person who was eliminated and redistribute their vote | |
def redistribute(round_num): | |
# round 1 = we are redistributing the votes from 1st place, round 2 is 2nd place, and so on... | |
eliminated = find_loser() | |
# candidate being eliminated | |
loser_num = ballot.index(eliminated) | |
list_of_votes = list_of_vote_collections[loser_num] | |
ballots_to_distribute = [] | |
# add eliminated candidate to list | |
# ballot.remove(eliminated) | |
eliminated_candidates.append(eliminated) | |
current_totals[loser_num] = -1 | |
for vote in list_of_votes: | |
if vote == round_num: | |
to_save = list_of_votes.index(vote) | |
ballots_to_distribute.append(to_save) | |
for index in ballots_to_distribute: | |
for vote_list in list_of_vote_collections: | |
current_candidate_num = list_of_vote_collections.index(vote_list) | |
if vote == round_num + 1: | |
current_totals[current_candidate_num] += 1 | |
# checking every vote in the list of votes for that candidate to see where exactly they were voted for that specific round | |
ballot_num = list_of_votes[round_num] # EX: if we are in round 1, the computer is looking through the list of rankings for that candidate and seeing where they were ranked first | |
####### vote calculation ####### (bigger functions) | |
def final_results(): | |
# keep track of rounds and whether we're still going | |
still_counting = True | |
rounds_completed = 0 | |
round_num = 0 | |
# tally up each candidate | |
for person in ballot: | |
person_num = ballot.index(person) + 1 | |
tally_up(person_num) | |
# add tally for 1st place to current total | |
place = 0 | |
for person in ballot: | |
person_num = ballot.index(person) + 1 | |
current_totals[place] += tally[place][1] | |
place += 1 | |
winner = "" | |
loser = find_loser() | |
while still_counting == True: | |
round_num += 1 | |
if rounds_completed == len(ballot) or loser == 0: | |
print("Oh no!! A winner couldn't be determined!") | |
still_counting = False | |
# if someone has the majority | |
else: | |
if have_majority()[1] != 0: | |
votes_winner_got = have_majority()[0] | |
winner = find_winner() | |
still_counting = False | |
print("round", round_num -1, "didn't yield a majority\nmoving onto round #", round_num) | |
else: | |
print("no one has the majority") | |
redistribute(round_num) | |
print(have_majority()[0]) | |
rounds_completed += 1 | |
return winner | |
# winner = final_results() | |
# if winner != "": | |
# print("and the winner is...", winner + "!!!") | |
######### putting it all together -- the main code ########## | |
print("""-- MARIO KART CHARACTER VOTING BOOTH -- | |
* with ranked choice voting * | |
By: Sadie Allspaw | |
This is a voting booth simulator. You will have the chance to create a candidate list and submit multiple ballots ranking these candidates. At the end, you will get a result of who wins. | |
NOTE: I named this Mario Kart Character Voting Booth because it was created to find the best Mario Kart character. However, it can be used to vote on any list of candidates. | |
STEP 1: CREATE YOUR LIST OF CANDIDATES | |
""") | |
form_ballot() | |
print(""" | |
STEP 2: VOTE ON YOUR CANDIDATES""") | |
vote() | |
print(""" | |
STEP 3: CALCULATE RESULTS | |
""") | |
winner = final_results() | |
if winner != "": | |
print("and the winner is...", winner + "!!!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment