I was trying to write the code for an exercise, and while it works as it should, it looks terrifying and I was wondering if anyone could help me remove anything that’s not necessary, and potentially just combine some of the functions?
Here’s an example of the use of the function:
choices([['YES', 'NO', 'YES', 'YES'], ['NO', 'NO', 'YES', 'NO'], ['YES', 'YES', 'YES', 'YES']])
Each list within the list has four yes/no choices (INDICES below lists four options as well, e.g. green, red, blue, yellow; but it doesn’t have to be four). The number of lists within the list is how many people cast their votes.
i = 0
num = 0
total_num = 0
num_choices = len(INDICES)
choices_index = 0
choices_votes = []
choices_votes_num = []
index = 0
total_choices = []
winning_choice = ''
winning_index = 0
while i < len(parameter):
while num < num_choices:
for item in parameter:
choices_votes.append(item[num])
num += 1
i += 1
while total_num < len(choices_votes):
if choices_votes[total_num] == 'YES':
choices_votes_num.append(1)
total_num += 1
elif choices_votes[total_num] == 'NO':
choices_votes_num.append(0)
total_num += 1
while choices_index < len(choices_votes_num):
count = int(len(choices_votes_num) / num_choices)
total = 0
total = sum(choices_votes_num[choices_index:(choices_index + count)])
total_choices.append(total)
choices_index = choices_index + count
for score in total_choices:
winning_index = max(total_choices)
winning_choice = INDEX_TO_NAME[total_choices.index(winning_index)]
return winning_choice, total_choices
INDEX_TO_NAME is just a dictionary set up to connect indices to choices (the colours).
Basically the code is supposed to count each yes as 1 point and each no as zero points, add up the total points for each available choice, and then return the totals and the winner.
Lets start with:
Since you were using
INDICESto source your poll anyways, we can assume that the answers will always line up with the number ofINDICES.We can make use of
zipto reorganize this data:This expands the answers to arguments and recombines them to be grouped by the actual indices. So the first index is ‘red’, second is ‘green’, etc
Now we can zip again to combine them with the indices:
And we can loop over
results, simply counting the occurrences of ‘YES’:So here we have the totals. We could pass this to a call to
maxto have it tell us which one was the winner:maxwill by default look at the first index, so we can pass it akeyfunction instructing it to pull the index1instead. It shows us blue was the winner.To be more efficient, we can actually pass a generator to
max:The final single statement could be written like this:
I know this answer introduces some list comprehension and lambda (and generator), but you asked for a way to clean it up and this is an example of the tools that are available to you. Hopefully this gives you the help you needed!
Note: This answer doesn’t take into account a tie. But I am sure you can work from here to integrate these examples into your actual code