#!/usr/bin/python """ Shish's AV simulator. Designed primarily for readability, it misses out the corner case of tied votes. Example run: {'Mint': 22, 'Strawberry': 7, 'Fudge': 9, 'Vanilla': 15, 'Chocolate': 13} Strawberry is the least popular, removing it and re-counting {'Mint': 23, 'Vanilla': 18, 'Fudge': 10, 'Chocolate': 15} Fudge is the least popular, removing it and re-counting {'Vanilla': 22, 'Mint': 26, 'Chocolate': 18} Chocolate is the least popular, removing it and re-counting {'Vanilla': 33, 'Mint': 32} Vanilla has over 50%, it wins! Feel free to modify and redistribute under the terms of CC-BY-SA: http://creativecommons.org/licenses/by-sa/3.0/ """ def main(): all_voter_preferences = read_vote_file("votes.txt") while True: active_votes = get_highest_preferences(all_voter_preferences) votes_for_each_candidate = count_votes(active_votes) print votes_for_each_candidate # if somebody has more than 50% of the votes, they win most_popular = get_most_popular_candidate(votes_for_each_candidate) if votes_for_each_candidate[most_popular] > len(active_votes)/2: print most_popular, "has over 50%, it wins!" break # nobody has over 50%, knock out the least popular candidate least_popular = get_least_popular_candidate(votes_for_each_candidate) print least_popular, "is the least popular, removing it and re-counting\n" for voter_preferences in all_voter_preferences: remove_candidate(voter_preferences, least_popular) # # utility functions, to separate the code grind from the actual logic above # def read_vote_file(f): return [line.strip().split(",") for line in file(f).readlines()] def get_highest_preferences(voter_preferences): return [prefs[0] for prefs in voter_preferences if len(prefs) > 0] def get_most_popular_candidate(votes): return max(votes, key=votes.get) def get_least_popular_candidate(votes): return min(votes, key=votes.get) def remove_candidate(voter, lpc): while lpc in voter: voter.remove(lpc) def count_votes(raw_votes): votes = {} for vote in raw_votes: votes[vote] = votes.get(vote, 0) + 1 return votes if __name__ == "__main__": main()