Skip to content

Instantly share code, notes, and snippets.

@goulu
Last active September 20, 2021 09:40
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goulu/7531147 to your computer and use it in GitHub Desktop.
Save goulu/7531147 to your computer and use it in GitHub Desktop.
assign n seats proportionaly to votes using the https://en.wikipedia.org/wiki/Hagenbach-Bischoff_quota method
def proportional(nseats,votes):
"""assign n seats proportionaly to votes using the https://en.wikipedia.org/wiki/Hagenbach-Bischoff_quota method
:param nseats: int number of seats to assign
:param votes: iterable of int or float weighting each party
:result: list of ints seats allocated to each party
"""
quota=sum(votes)/(1.+nseats) #force float
frac=[vote/quota for vote in votes]
res=[int(f) for f in frac]
n=nseats-sum(res) #number of seats remaining to allocate
if n==0: return res #done
if n<0: return [min(x,nseats) for x in res] #to handle case where votes=[0,0,..,1,0,...,0]
#give the remaining seats to the n parties with the largest remainder
remainders=[ai-bi for ai,bi in zip(frac,res)]
limit=sorted(remainders,reverse=True)[n-1]
for i,r in enumerate(remainders):
if r>=limit:
res[i]+=1
n-=1 # attempt to handle perfect equality
if n==0: return res #done
raise #should never happen
@goulu
Copy link
Author

goulu commented Mar 14, 2014

added lien if n<0: return [min(x,nseats) for x in res] to handle case where votes=[0,0,..,1,0,...,0]

@goulu
Copy link
Author

goulu commented Mar 14, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment