Fix bug in STV implementation

Do not allow surplus transfers to interrupt a candidate exclusion
This commit is contained in:
RunasSudo 2020-12-31 01:51:13 +11:00
parent 61506f0082
commit 29c15645b4
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A

View File

@ -191,6 +191,10 @@ class BaseSTVCounter:
Distribute surpluses, if any
"""
# Do not interrupt an exclusion
if any(cc.state == CandidateState.EXCLUDING for c, cc in self.candidates.items()):
return
# Are we distributing a surplus?
has_surplus = [(c, cc) for c, cc in self.candidates.items() if cc.state == CandidateState.DISTRIBUTING_SURPLUS]
@ -629,7 +633,7 @@ class UIGSTVCounter(WIGSTVCounter):
__pragma__('opov')
if self.options['papers'] == 'transferable':
if transferable_votes > surplus:
if transferable_votes.to_num() > surplus:
self.candidates[candidate].transfers += (num_ballots * surplus) / transferable_ballots
else:
self.candidates[candidate].transfers += num_votes.to_num()
@ -640,7 +644,7 @@ class UIGSTVCounter(WIGSTVCounter):
for ballot, ballot_value in cand_ballots:
__pragma__('opov')
if self.options['papers'] == 'transferable':
if transferable_votes > surplus:
if transferable_votes.to_num() > surplus:
new_value = (ballot.value * surplus).to_rational() / transferable_ballots.to_rational()
else:
new_value = ballot_value
@ -652,10 +656,10 @@ class UIGSTVCounter(WIGSTVCounter):
__pragma__('opov')
if self.options['papers'] == 'transferable':
if transferable_votes > surplus:
if transferable_votes.to_num() > surplus:
pass # No ballots exhaust
else:
self.exhausted.transfers += (surplus - transferable_votes)
self.exhausted.transfers += surplus - transferable_votes.to_num()
else:
self.exhausted.transfers += (exhausted_ballots * surplus) / total_ballots
__pragma__('noopov')