From 29c15645b46aa0b3e502228622d6067695954af3 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Thu, 31 Dec 2020 01:51:13 +1100 Subject: [PATCH] Fix bug in STV implementation Do not allow surplus transfers to interrupt a candidate exclusion --- pyRCV2/method/base_stv.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pyRCV2/method/base_stv.py b/pyRCV2/method/base_stv.py index 089306e..aadb8a0 100644 --- a/pyRCV2/method/base_stv.py +++ b/pyRCV2/method/base_stv.py @@ -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')