0

I am trying to write a function that takes a parameter that is a list of 4-element lists that represent approval ballots for a single riding; the order of the inner list elements corresponds to the order of the parties in a list of parties called PARTY_INDICES.

The party with the most number of 'yes' votes wins.

It should return a 2-tuple where the first element is the name of the winning party and the second element is a four-element list that contains the number of yes votes for each party. The order of the list elements corresponds to the order of the parties in PARTY_INDICES.

My code is:

def voting_approval(approval):
    parties = ['NDP','GREEN','LIBERAL','CPC']
    values = [0,0,0,0]
    for decision in approval:
        for no, item in enumerate(decision):
            if item == 'Yes':
                values[no] += 1
                total = [(values) for x in zip(approval)]

    return (parties[values.index(max(values))], total)

If I try:

voting_approval([['Yes', 'No', 'Yes', 'No'],['No', 'No', 'Yes', 'No']])

it spits out:

('LIBERAL', [[1, 0, 2, 0], [1, 0, 2, 0]])

but I want the result to be:

('LIBERAL', [1, 0, 2, 0])
user1864828
  • 349
  • 1
  • 3
  • 10

5 Answers5

0

Haven't tested extensively, but you could try:

In [7]: def voting_approval(approval):
   ...:     parties = ['NDP', 'GREEN', 'LIBERAL', 'CPC']
   ...:     values = [sum(1 if i == 'Yes' else 0 for i in group) for group in zip(*approval)]
   ...:
   ...:     return (parties[values.index(max(values))], values)
   ...:

In [8]: voting_approval([['Yes', 'No', 'Yes', 'No'],['No', 'No', 'Yes', 'No']])
Out[8]: ('LIBERAL', [1, 0, 2, 0])

This zips your lists together at the beginning, sums the Yes's and creates a new list with the totals, which is then used to pull out the required info. Happy to tweak if this isn't what you were looking for.

RocketDonkey
  • 36,383
  • 7
  • 80
  • 84
0

You already have the amount of 'YES' per party stored in values. Just change your code as following.

def voting_approval(approval):
    parties = ['NDP','GREEN','LIBERAL','CPC']
    values = [0,0,0,0]
    for decision in approval:
        for no, item in enumerate(decision):
            if item == 'Yes':
                values[no] += 1

    return (parties[values.index(max(values))], values)
Diego Allen
  • 4,623
  • 5
  • 30
  • 33
0

You don't need that total var. values is already what you want.

def voting_approval(approval):
    parties = ['NDP','GREEN','LIBERAL','CPC']
    values = [0,0,0,0]
    for decision in approval:
        for no, item in enumerate(decision):
            if item == 'Yes':
                values[no] += 1

    return (parties[values.index(max(values))], values)

approvals = [
    ['Yes', 'No', 'Yes', 'No'],
    ['No', 'No', 'Yes', 'No'],
]

print voting_approval(approvals)

matt@wraith:~/Dropbox/Public/StackOverflow$ python 13638424.py 
('LIBERAL', [1, 0, 2, 0])
Matt Williamson
  • 39,165
  • 10
  • 64
  • 72
0

I formatted it so you could see your code almost getting the answer.

def voting_approval(approval):
    parties = ['NDP','GREEN','LIBERAL','CPC']
    values = [0,0,0,0]
    for decision in approval:
        for no, item in enumerate(decision):
            if item == 'Yes':
                values[no] += 1
                total = [(values) for x in zip(approval)]

    return (parties[values.index(max(values))], total)

almostAnswer = voting_approval([['Yes', 'No', 'Yes', 'No'],['No', 'No', 'Yes', 'No']])
answer = [sum(a) for (a) in zip(almostAnswer[1][0], almostAnswer[1][1])]
print answer

You had the [sum(a) for a in zip(array1,array2)] down, but you were pointing to the wrong parts of the elements contained within approval - hence the need for [1][0] and [1][1].

Ecnalyr
  • 5,792
  • 5
  • 43
  • 89
0

Essentially, if you think of each list of votes as a row in the approval list, what you want to do is tally or sum the number of yes votes that appear in the columns. A good way to do that is by transposing (or swapping the rows and columns) of this list of lists, and then total the number in of them each of the resulting rows.

Here's code showing how this is easily this is done. Note that the first item in the tuple returned is a list of party names, rather than a single value since ties are possible, as illustrated with the test values shown. I would also consider changing approval to approvals to reflect its content better.

approval = [['Yes', 'No', 'Yes', 'No'],
            ['No', 'No', 'Yes', 'No'],
            ['Yes', 'No', 'No', 'No'],]

def voting_approval(approval):
    parties = ['NDP','GREEN','LIBERAL','CPC']
    tallies = [sum(int(v =='Yes') for v in col) for col in zip(*approval)]
    most_yes = max(tallies)
    return ([party for i,party in enumerate(parties) if tallies[i] == most_yes], tallies)

print voting_approval(approval)

Output:

(['NDP', 'LIBERAL'], [2, 0, 2, 0])
Community
  • 1
  • 1
martineau
  • 119,623
  • 25
  • 170
  • 301