2022-11-07 21:06:14 +01:00
|
|
|
#!/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:
|
2022-11-08 23:16:38 +01:00
|
|
|
count[r.id] = [0] * len(ballot)
|
2022-11-07 21:06:14 +01:00
|
|
|
candidates[r.id] = r
|
|
|
|
for ballot in ballots:
|
2022-11-08 23:16:38 +01:00
|
|
|
for pos, r in enumerate(ballot):
|
|
|
|
count[r.id][pos] += 1
|
2022-11-07 21:06:14 +01:00
|
|
|
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)
|