Skip to content

Instantly share code, notes, and snippets.

@lgommans
Created February 2, 2022 01:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lgommans/e235dec8a19df3d4d317affa1cc39029 to your computer and use it in GitHub Desktop.
Save lgommans/e235dec8a19df3d4d317affa1cc39029 to your computer and use it in GitHub Desktop.
Not-really-tested attempt at instant-runoff voting
#!/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