# How Voting Systems Work 7, Exercise 2: search seeded random profiles for a case where Jefferson gives a state more than its # upper quota (the quota rounded up). Populations are drawn at random: an assumed model. import random from math import ceil def jefferson(pops, seats): alloc = {s: 0 for s in pops} for _ in range(seats): best = max(sorted(pops), key=lambda s: pops[s] / (alloc[s] + 1)) alloc[best] += 1 return alloc random.seed(31) for attempt in range(1, 10001): pops = {name: random.randint(100, 3000) for name in ("Ardan", "Brex", "Cole", "Dunn")} pops["Eld"] = random.randint(10, 100) * 100 seats = 10 total = sum(pops.values()) alloc = jefferson(pops, seats) for s in pops: quota = seats * pops[s] / total if alloc[s] > ceil(quota): print("attempt", attempt, "populations", pops) print(f"{s}: quota {quota:.2f}, Jefferson gives {alloc[s]} (upper quota {ceil(quota)})") print("allocation", alloc) raise SystemExit print("none found") # attempt 2 populations {'Ardan': 2901, 'Brex': 277, 'Cole': 668, 'Dunn': 560, 'Eld': 7800} # Eld: quota 6.39, Jefferson gives 8 (upper quota 7) # allocation {'Ardan': 2, 'Brex': 0, 'Cole': 0, 'Dunn': 0, 'Eld': 8}