Test instant runoff algorithm
This commit is contained in:
parent
65a19eb756
commit
049a8d0d70
|
@ -0,0 +1,82 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import psycopg
|
||||||
|
import psycopg.rows
|
||||||
|
|
||||||
|
def get_args():
|
||||||
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument("meet", type=int)
|
||||||
|
ap.add_argument("kind")
|
||||||
|
|
||||||
|
args = ap.parse_args()
|
||||||
|
return args
|
||||||
|
|
||||||
|
def get_ballots():
|
||||||
|
db = psycopg.connect(dbname="meeat", user="www-meeat")
|
||||||
|
|
||||||
|
csr = db.cursor(row_factory=psycopg.rows.namedtuple_row)
|
||||||
|
|
||||||
|
kind = args.kind
|
||||||
|
q = f"""
|
||||||
|
select {kind}.*, bod, position
|
||||||
|
from {kind} join {kind}_vote on {kind}.id = {kind}_vote.{kind}
|
||||||
|
where meet = %s
|
||||||
|
order by bod, position
|
||||||
|
"""
|
||||||
|
csr.execute(q, (args.meet,))
|
||||||
|
|
||||||
|
last_bod = None
|
||||||
|
ballots = []
|
||||||
|
for r in csr:
|
||||||
|
if r.bod != last_bod:
|
||||||
|
ballot = []
|
||||||
|
ballots.append(ballot)
|
||||||
|
last_bod = r.bod
|
||||||
|
ballot.append(r)
|
||||||
|
return ballots
|
||||||
|
|
||||||
|
def dump_ballots(ballots):
|
||||||
|
for ballot in ballots:
|
||||||
|
print ("---")
|
||||||
|
for r in ballot:
|
||||||
|
print(r)
|
||||||
|
|
||||||
|
def runoff(ballots):
|
||||||
|
count = {}
|
||||||
|
candidates = {}
|
||||||
|
for ballot in ballots:
|
||||||
|
for r in ballot:
|
||||||
|
count[r.id] = 0
|
||||||
|
candidates[r.id] = r
|
||||||
|
for ballot in ballots:
|
||||||
|
# The votes are sorted by position, so the first entry is the favourite
|
||||||
|
count[ballot[0].id] += 1
|
||||||
|
result = sorted(count.keys(), key=lambda i: count[i])
|
||||||
|
print("result of this round:")
|
||||||
|
for r in result:
|
||||||
|
print(r, count[r])
|
||||||
|
print("striking", result[0])
|
||||||
|
loser = candidates[result[0]]
|
||||||
|
new_ballots = [
|
||||||
|
[
|
||||||
|
r for r in ballot if r.id != loser.id
|
||||||
|
] for ballot in ballots
|
||||||
|
]
|
||||||
|
return loser, new_ballots
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = get_args()
|
||||||
|
|
||||||
|
ballots = get_ballots()
|
||||||
|
|
||||||
|
result = []
|
||||||
|
while max(len(b) for b in ballots):
|
||||||
|
dump_ballots(ballots)
|
||||||
|
loser, ballots = runoff(ballots)
|
||||||
|
result.append(loser)
|
||||||
|
result = reversed(result)
|
||||||
|
print("final result")
|
||||||
|
for r in result:
|
||||||
|
print(r)
|
Loading…
Reference in New Issue