From 35e86a1dc1f11370473061bed3d952f9a2629761 Mon Sep 17 00:00:00 2001 From: Flynn Date: Sun, 13 Oct 2019 22:13:32 -0400 Subject: [PATCH] Webster fix (#9) * deallocate seats properly * simplify * webster test * missed conflict * black --- tests/test_apportionment.py | 4 ++++ voting/apportionment.py | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/test_apportionment.py b/tests/test_apportionment.py index 54fee9a..d97b1fd 100644 --- a/tests/test_apportionment.py +++ b/tests/test_apportionment.py @@ -11,6 +11,10 @@ def test_apportionment_values(apportionment_method, votes, seats_val): assert sum(apportionment_method(votes, seats_val)) == seats_val +def test_webster(): + assert all([a >= 0 for a in webster([2057, 2496, 2059, 181], 15)]) + + def test_adams(): assert adams([10, 1], 2) == [1, 1] diff --git a/voting/apportionment.py b/voting/apportionment.py index b9bacdd..782718f 100644 --- a/voting/apportionment.py +++ b/voting/apportionment.py @@ -183,13 +183,19 @@ def webster(votes, seats): for k in range(unallocated): assigned[divs[k]] += 1 elif unallocated < 0: - unallocated = abs(unallocated) + overallocated = abs(unallocated) # divisors that would subtract a seat from each group diffs = [ 1.0 * vote / (i + 0.5) if dec >= 0.5 else 1.0 * vote / (i - 0.5) for i, dec, vote in zip(lower, decs, votes) ] # argsort divs = [i[0] for i in sorted(enumerate(diffs), key=itemgetter(1))] - for k in range(unallocated): - assigned[divs[k]] -= 1 + # deallocate seats without bringing seat allocation below zero + div_idx = 0 + while overallocated > 0: + if assigned[divs[div_idx]] > 0: + assigned[divs[div_idx]] -= 1 + overallocated -= 1 + else: + div_idx += 1 return assigned