Revision 361b3942
b/stv.py | ||
---|---|---|
68 | 68 |
_value = 1.0 |
69 | 69 |
|
70 | 70 |
def __init__(self, candidates=[]): |
71 |
self.candidates = [ x.strip() for x in candidates]
|
|
71 |
self.candidates = filter(None, candidates)
|
|
72 | 72 |
|
73 | 73 |
def add_weight(self, weight): |
74 | 74 |
self.weights.insert(0, weight) |
... | ... | |
76 | 76 |
|
77 | 77 |
def get_value(self): |
78 | 78 |
return self._value |
79 |
|
|
80 |
def random_generator(num): |
|
81 |
if not random_sequence: |
|
82 |
print "Need random from " + num |
|
83 |
sys.exit() |
|
84 |
else: |
|
85 |
return random_sequence.pop(0) |
|
86 | 79 |
|
87 | 80 |
def randomly_select_first(sequence, key, action, random_generator=None): |
88 | 81 |
"""Selects the first item of equals in a sorted sequence of items. |
... | ... | |
106 | 99 |
else: |
107 | 100 |
break |
108 | 101 |
index = 0 |
102 |
selected = collected[index] |
|
109 | 103 |
num_eligibles = len(collected) |
110 | 104 |
if (num_eligibles > 1): |
111 | 105 |
if random_generator is None: |
112 | 106 |
index = int(random() * num_eligibles) |
107 |
selected = collected[index] |
|
113 | 108 |
else: |
114 |
index = random_generator(num_eligibles) |
|
115 |
selected = collected[index] |
|
109 |
if not random_generator: |
|
110 |
print "Missing value for random selection" |
|
111 |
sys.exit(1) |
|
112 |
selected = random_generator.pop(0) |
|
116 | 113 |
logger = logging.getLogger(SVT_LOGGER) |
117 | 114 |
description = "{0} from {1} to {2}".format(selected, collected, action) |
118 | 115 |
logger.info(LOG_MESSAGE.format(action=Action.RANDOM, desc=description)) |
119 |
return collected[index]
|
|
116 |
return selected
|
|
120 | 117 |
|
121 | 118 |
|
122 | 119 |
def redistribute_ballots(selected, hopefuls, allocated, weight, vote_count): |
... | ... | |
176 | 173 |
allocated[selected][:] = [x for x in allocated[selected] |
177 | 174 |
if x not in transferred ] |
178 | 175 |
|
179 |
def count_stv(ballots, seats, rnd_gen=None): |
|
176 |
def count_stv(ballots, droop, seats, rnd_gen=None):
|
|
180 | 177 |
"""Performs a SVT vote for the given ballots and number of seats. |
181 | 178 |
|
182 | 179 |
""" |
... | ... | |
189 | 186 |
|
190 | 187 |
seed() |
191 | 188 |
|
192 |
threshold = (1 + len(ballots) / (seats + 1)) |
|
189 |
if droop: |
|
190 |
threshold = int(1 + (len(ballots) / (seats + 1.0))) |
|
191 |
else: |
|
192 |
threshold = int(math.ceil(1 + len(ballots) / (seats + 1.0))) |
|
193 | 193 |
|
194 | 194 |
logger = logging.getLogger(SVT_LOGGER) |
195 | 195 |
logger.info(LOG_MESSAGE.format(action=Action.THRESHOLD, |
... | ... | |
272 | 272 |
|
273 | 273 |
if __name__ == "__main__": |
274 | 274 |
parser = argparse.ArgumentParser(description='Perform STV') |
275 |
parser.add_argument('--ballots', nargs='?', default='sys.stdin',
|
|
275 |
parser.add_argument('-b', '--ballots', default='sys.stdin',
|
|
276 | 276 |
dest='ballots_file', help='input ballots file') |
277 |
parser.add_argument('--seats', nargs='?', default=0, |
|
277 |
parser.add_argument('-n', '--not_droop', action="store_false", |
|
278 |
dest='droop', help="don't use droop quota") |
|
279 |
parser.add_argument('-s', '--seats', type=int, default=0, |
|
278 | 280 |
dest='seats', help='number of seats') |
279 |
parser.add_argument('--loglevel', nargs='?', default=logging.INFO, |
|
281 |
parser.add_argument('-r', '--random', nargs='*', |
|
282 |
dest='random', help='random selection results') |
|
283 |
parser.add_argument('-l', '--loglevel', default=logging.INFO, |
|
280 | 284 |
dest='loglevel', help='logging level') |
281 | 285 |
args = parser.parse_args() |
282 | 286 |
logging.basicConfig(format=LOGGER_FORMAT) |
... | ... | |
284 | 288 |
ballots = [] |
285 | 289 |
ballots_file = sys.stdin |
286 | 290 |
if args.ballots_file != 'sys.stdin': |
287 |
ballots_file = open(args.ballots_file) |
|
291 |
ballots_file = open(args.ballots_file, 'U')
|
|
288 | 292 |
ballots_reader = csv.reader(ballots_file, delimiter=',', |
289 | 293 |
quotechar='"', |
290 | 294 |
skipinitialspace = True) |
... | ... | |
293 | 297 |
|
294 | 298 |
if args.seats == 0: |
295 | 299 |
args.seats = len(ballots) / 2 |
296 |
(elected, vote_count) = count_stv(ballots, int(args.seats)) |
|
300 |
(elected, vote_count) = count_stv(ballots, args.droop, args.seats, |
|
301 |
args.random) |
|
297 | 302 |
|
298 | 303 |
print "Results:" |
299 | 304 |
for result in elected: |
Also available in: Unified diff