-
-
Save lgommans/e235dec8a19df3d4d317affa1cc39029 to your computer and use it in GitHub Desktop.
Not-really-tested attempt at instant-runoff voting
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
#!/usr/bin/env python3 | |
''' | |
TODO: test me. Compare against https://petertheone.github.io/IRV/ for example (the only no-registration-required | |
tool I could quickly find online), and note that it wants an entirely different format (namely positional rather | |
than just writing down each voter's preference list in order), this took me way too long to figure out... | |
''' | |
# Hardcode to make it easier for anyone to download, | |
# re-run, and thus verify this election. | |
votes = ''' | |
C > E > D > F > A > B | |
C > B > E | |
A > C > B-D-E-F | |
A > no alternative | |
B > C > E > A > D > F | |
'''.strip() | |
import collections | |
votes_list = [] | |
for line in votes.replace('\r', '').split('\n'): | |
votes_list.append(line.strip().split(' > ')) | |
print('List of ballots containing lists of votes on each ballot, after computer interpretation:') | |
print(votes_list) | |
print('') | |
voting_round = 1 | |
while True: | |
candidates = collections.defaultdict(lambda: 0) | |
for vote in votes_list: | |
if len(vote) > 0: | |
candidates[vote[0]] += 1 | |
if len(candidates) == 1: | |
print('Only candidate in this round, and thus winner, is:') | |
print(list(candidates.keys())[0]) | |
break | |
print('Votes in round', voting_round, 'are:', dict(candidates)) | |
sorted_candidates = list(sorted(candidates, key=candidates.get, reverse=True)) | |
if sorted_candidates[-1] == sorted_candidates[-2]: | |
print('Tied result. TODO what do?') | |
break | |
least_popular = sorted_candidates[-1] | |
print('Eliminating the least popular vote:', least_popular) | |
for i in range(len(votes_list)): | |
if least_popular in votes_list[i]: | |
votes_list[i].remove(least_popular) | |
voting_round += 1 | |
print('') | |
if voting_round > 50: | |
print('Huh, 50th round already? If this is normal, please increase the check value, but I am stopping here to avoid getting an endless loop.') | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment