def voting_borda(rank_ballots):
\'\'\'(list of list of str) -> tuple of (str, list of int)
The parameter is a list of 4-element lists that repre
This does not do EXACTLY what you were asking for, it returns a tuple with two values: winner's name, and a dictionary of all parties and their values, instead of a list with only values. In my opinion, this is better for almost any case, and if you don't like it, you can convert it to a list.
It also takes multiple parameters instead of one list too, but you can change that by simply removing the *
from *args
Notice, however, if you care about speed rather than small code, this is not the best way to do it. It does work, tho.
It is also superior to your code in the manner of this allowing you to NOT use any of the parties names or amount of parties inside the function, which makes it possible to add, rename or remove parties.
def voting_borda(*args):
results = {}
for sublist in args:
for i in range(0, 3):
if sublist[i] in results:
results[sublist[i]] += 3-i
else:
results[sublist[i]] = 3-i
winner = max(results, key=results.get)
return winner, results
print(voting_borda(
['GREEN','NDP', 'LIBERAL', 'CPC'],
['GREEN','CPC','LIBERAL','NDP'],
['LIBERAL','NDP', 'CPC', 'GREEN']
))
Will result into: ('GREEN', {'LIBERAL': 5, 'NDP': 4, 'GREEN': 6, 'CPC': 3})
I found your voting simulation assignment online and added a few of the constants from it here to simplify the code for solving the problem a little (although it may not look like it with their definitions at the beginning).
The first element of the tuple returned is not exactly in the requested format -- it's a list rather than a single value -- to deal with the quite real possibility of tie votes, as illustrated with the sample data values used below for rank_ballots
. Even if there wasn't a tie, the element is return is a singleton list -- which actually is usually easier to deal with than having it vary depending on there's more than one or not.
PARTY_NAMES = ['NDP', 'GREEN', 'LIBERAL', 'CPC']
NAME_TO_INDEX = {party:PARTY_NAMES.index(party) for party in PARTY_NAMES}
INDEX_TO_NAME = {PARTY_NAMES.index(party):party for party in PARTY_NAMES}
def voting_borda(rank_ballots):
results = [0 for _ in PARTY_NAMES]
MAX_POINTS = len(PARTY_NAMES)-1
for ballot in rank_ballots:
for i,party in enumerate(ballot):
results[NAME_TO_INDEX[party]] += MAX_POINTS-i
highest_rank = max(results)
winners = [INDEX_TO_NAME[i] for i,total in enumerate(results) if total == highest_rank]
return winners, results
rank_ballots = [['GREEN','NDP', 'LIBERAL', 'CPC'],
['GREEN','CPC','LIBERAL','NDP'],
['LIBERAL', 'GREEN', 'NDP', 'CPC'],
['LIBERAL','NDP', 'CPC', 'GREEN'],]
print(voting_borda(rank_ballots))
Output:
(['GREEN', 'LIBERAL'], [5, 8, 8, 3])