diff --git a/html/index.html b/html/index.html
index 3629a9e..b459932 100644
--- a/html/index.html
+++ b/html/index.html
@@ -40,7 +40,7 @@
@@ -119,7 +119,7 @@
diff --git a/pyRCV2/method/base_stv.py b/pyRCV2/method/base_stv.py
index 6bf866b..089306e 100644
--- a/pyRCV2/method/base_stv.py
+++ b/pyRCV2/method/base_stv.py
@@ -20,6 +20,8 @@ from pyRCV2.model import CandidateState, CountCard, CountCompleted, CountStepRes
from pyRCV2.numbers import Num, Rational
from pyRCV2.safedict import SafeDict
+import itertools
+
class STVException(Exception):
pass
@@ -535,11 +537,28 @@ class WIGSTVCounter(BaseSTVCounter):
def do_exclusion(self, candidate_excluded, count_card):
if self.options['exclusion'] == 'parcels_by_order':
- parcel = count_card.parcels[0]
- next_preferences, total_ballots, total_votes, next_exhausted, exhausted_ballots, exhausted_votes = self.next_preferences([parcel])
+ if len(count_card.parcels) > 0:
+ parcel = count_card.parcels[0]
+ next_preferences, total_ballots, total_votes, next_exhausted, exhausted_ballots, exhausted_votes = self.next_preferences([parcel])
+ else:
+ # TODO: Skip this entirely if this is the case
+ parcel = []
count_card.parcels.remove(parcel)
elif self.options['exclusion'] == 'parcels_by_value':
- raise Exception('Not implemented')
+ # Sort the parcels by value
+ ballots = [(b, bv) for p in count_card.parcels for b, bv in p]
+ __pragma__('opov')
+ ballots.sort(key=lambda x: x[1] / x[0].value.to_rational(), reverse=True)
+ count_card.parcels = [list(g) for k, g in itertools.groupby(ballots, lambda x: x[1] / x[0].value.to_rational())]
+ __pragma__('noopov')
+
+ if len(count_card.parcels) > 0:
+ parcel = count_card.parcels[0]
+ count_card.parcels.remove(parcel)
+ else:
+ parcel = []
+
+ next_preferences, total_ballots, total_votes, next_exhausted, exhausted_ballots, exhausted_votes = self.next_preferences([parcel])
else: # one_round
next_preferences, total_ballots, total_votes, next_exhausted, exhausted_ballots, exhausted_votes = self.next_preferences(count_card.parcels)
count_card.parcels = []
@@ -573,6 +592,9 @@ class WIGSTVCounter(BaseSTVCounter):
__pragma__('noopov')
if len(count_card.parcels) == 0:
+ __pragma__('opov')
+ count_card.transfers -= count_card.votes
+ __pragma__('noopov')
count_card.state = CandidateState.EXCLUDED
class UIGSTVCounter(WIGSTVCounter):
@@ -590,14 +612,14 @@ class UIGSTVCounter(WIGSTVCounter):
if self.options['papers'] == 'transferable':
__pragma__('opov')
- transferable_ballots = total_ballots - exhausted_ballots
- transferable_votes = total_votes.to_num() - exhausted_votes.to_num()
+ transferable_ballots = total_ballots - exhausted_ballots # Num
+ transferable_votes = total_votes - exhausted_votes # Rational
__pragma__('noopov')
for candidate, x in next_preferences.items():
cand_ballots = x[0]
- num_ballots = x[1]
- num_votes = x[2]
+ num_ballots = x[1] # Num
+ num_votes = x[2] # Rational
new_parcel = []
if len(cand_ballots) > 0:
@@ -619,11 +641,11 @@ class UIGSTVCounter(WIGSTVCounter):
__pragma__('opov')
if self.options['papers'] == 'transferable':
if transferable_votes > surplus:
- new_value = (ballot.value * surplus) / transferable_ballots
+ new_value = (ballot.value * surplus).to_rational() / transferable_ballots.to_rational()
else:
new_value = ballot_value
else:
- new_value = (ballot.value * surplus) / total_ballots
+ new_value = (ballot.value * surplus).to_rational() / total_ballots.to_rational()
new_parcel.append((ballot, new_value))
__pragma__('noopov')