Last active
September 20, 2021 09:40
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
blog article on this topic (in french) http://www.drgoulu.com/2013/12/02/repartition-proportionnelle/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added lien if n<0: return [min(x,nseats) for x in res] to handle case where votes=[0,0,..,1,0,...,0]