python-vote-core icon indicating copy to clipboard operation
python-vote-core copied to clipboard

STV dies with a tie

Open andymckay opened this issue 11 years ago • 2 comments

Traceback (most recent call last):
  File "test.py", line 28, in <module>
    pprint(STV(counts).as_dict())
  File "/Users/andy/sandboxes/dsf/python-vote-core-20120423.0/pyvotecore/stv.py", line 30, in __init__
    super(STV, self).__init__(ballots, tie_breaker=tie_breaker, required_winners=required_winners)
  File "/Users/andy/sandboxes/dsf/python-vote-core-20120423.0/pyvotecore/abstract_classes.py", line 76, in __init__
    super(MultipleWinnerVotingSystem, self).__init__(ballots, tie_breaker)
  File "/Users/andy/sandboxes/dsf/python-vote-core-20120423.0/pyvotecore/abstract_classes.py", line 59, in __init__
    super(FixedWinnerVotingSystem, self).__init__(ballots, tie_breaker)
  File "/Users/andy/sandboxes/dsf/python-vote-core-20120423.0/pyvotecore/abstract_classes.py", line 36, in __init__
    self.calculate_results()
  File "/Users/andy/sandboxes/dsf/python-vote-core-20120423.0/pyvotecore/stv.py", line 73, in calculate_results
    if ballot["ballot"][0] in round["winners"]:
IndexError: list index out of range

I'm trying to reproduce this with a simple data set and not succeeding yet. Our dataset goes through a few rounds and would get to a point like this:

            {'loser': 'F',
             'tallies': {'C': 6.0, 'F': 3.0, 'I': 5.0, 'K': 8.0}},
            {'loser': 'I', 'tallies': {'C': 8.0, 'I': 5.0, 'K': 9.0}},
            {'loser': 'K',
             'tallies': {'C': 11.0, 'K': 11.0},
             'tied_losers': set(['C', 'K'])},

This is our current data set:

[{'ballot': ['K'], 'count': 1},
 {'ballot': ['K', 'H', 'I', 'C', 'G', 'D', 'E', 'F', 'J'], 'count': 1},
 {'ballot': ['C', 'E', 'J', 'K', 'F', 'H', 'I', 'G', 'D'], 'count': 1},
 {'ballot': ['K', 'H', 'I', 'F', 'G', 'D', 'J', 'E'], 'count': 1},
 {'ballot': ['C', 'K', 'E', 'I', 'G', 'H', 'F', 'J', 'D'], 'count': 1},
 {'ballot': ['K', 'I', 'H', 'F', 'G', 'E', 'D', 'J', 'C'], 'count': 1},
 {'ballot': ['K', 'H', 'I', 'D', 'C', 'G', 'F', 'E', 'J'], 'count': 1},
 {'ballot': ['K', 'I', 'H'], 'count': 1},
 {'ballot': ['I', 'F', 'H', 'C'], 'count': 1},
 {'ballot': ['C', 'K', 'F'], 'count': 1},
 {'ballot': ['H', 'I', 'C', 'E', 'G', 'F', 'D', 'J', 'K'], 'count': 1},
 {'ballot': ['K', 'H', 'I', 'F', 'E', 'C', 'D', 'G', 'J'], 'count': 1},
 {'ballot': ['F', 'C', 'I', 'K', 'D', 'G', 'J', 'E', 'H'], 'count': 1},
 {'ballot': ['F', 'K', 'I', 'C', 'H', 'D', 'G', 'E', 'J'], 'count': 1},
 {'ballot': ['E', 'F', 'C', 'H', 'I', 'D', 'G', 'J', 'K'], 'count': 1},
 {'ballot': ['I', 'H', 'K', 'F', 'G', 'D', 'C', 'E', 'J'], 'count': 1},
 {'ballot': ['C', 'H', 'I', 'J', 'K', 'G', 'F', 'E', 'D'], 'count': 1},
 {'ballot': ['J', 'C', 'H', 'I', 'K', 'G', 'F', 'D', 'E'], 'count': 1},
 {'ballot': ['K', 'C', 'I', 'H', 'J', 'G', 'F', 'D', 'E'], 'count': 1},
 {'ballot': ['C', 'K', 'J'], 'count': 1},
 {'ballot': ['I', 'C', 'H', 'F', 'G', 'K', 'J', 'D', 'E'], 'count': 1},
 {'ballot': ['H', 'I', 'K', 'F', 'G', 'C', 'J', 'E', 'D'], 'count': 1}]

andymckay avatar Oct 04 '14 15:10 andymckay

Thanks Andy. I'm actually in the middle of rewriting the entire library to be PyPy compatible. I'll add this ballot set to the set of tests!

bradbeattie avatar Oct 04 '14 15:10 bradbeattie

Out of curiosity what do you do propose to do in this case? Just declare it a tie?

andymckay avatar Oct 04 '14 18:10 andymckay