Python Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesPython Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old November 21st, 2012, 05:20 PM
Softies Softies is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 1 Softies User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 h 49 m 50 sec
Reputation Power: 0
How to append the number of item frequencies in a list in Python 3.2?

Greetings, I'm new to the forums and I'm also new to programming.

The question I want to ask is how do you count the frequency of items in a list
so they add up in order with "PARTY_INDICES"? in my case that is.

This is a docstring of what I need to do:
Code:
''' (list of str) -> tuple of (str, list of int) 
votes is a list of single-candidate ballots for a single riding. 
Based on votes, return a tuple where the first element is the name of the party 
winning the seat and the second is a list with the total votes for each party in 
the order specified in PARTY_INDICES. 

>>> voting_plurality(['GREEN', 'GREEN', 'NDP', 'GREEN', 'CPC']) 
('GREEN', [1, 3, 0, 1])
''' 

Since PARTY_INDICES = [NDP_INDEX, GREEN_INDEX, LIBERAL_INDEX, CPC_INDEX]
This produces a tuple of the winning party (In this case 'GREEN') and the list of
frequencies, where [1, 3, 0, 1]


These are list of global variables, lists and dictionaries:
Code:
#  The indices where each party's data appears in a 4-element list.
NDP_INDEX = 0
GREEN_INDEX = 1
LIBERAL_INDEX = 2
CPC_INDEX = 3

# A list of the indices where each party's data appears in a 4-element list.
PARTY_INDICES = [NDP_INDEX, GREEN_INDEX, LIBERAL_INDEX, CPC_INDEX]

# A dict where each key is a party name and each value is that party's index.
NAME_TO_INDEX = {
  'NDP': NDP_INDEX,
  'GREEN': GREEN_INDEX,
  'LIBERAL': LIBERAL_INDEX,
  'CPC': CPC_INDEX
}

# A dict where each key is a party's index and each value is that party's name.
INDEX_TO_NAME = {
  NDP_INDEX: 'NDP',
  GREEN_INDEX: 'GREEN',
  LIBERAL_INDEX: 'LIBERAL',
  CPC_INDEX: 'CPC'
}


This is my work:

Code:
def voting_plurality(votes):
    my_list = []
    my_dct = {}
    counter = 0
    for ballot in votes:
        if (ballot in my_dct):
            my_dct[ballot] += 1
        else:
            my_dct[ballot] = 1

    if (my_dct):
        my_dct = my_dct.values()
        new_list = list(my_dct)
                  
    return (max(set(votes), key = votes.count), new_list)

it returns
Code:
>>> voting_plurality(['GREEN', 'GREEN', 'NDP', 'GREEN', 'CPC'])
('GREEN', [1, 1, 3])

But I want it to to also include the party with no votes and is in order with PARTY_INDICES [1, 3, 0, 1]


My code may look like nonsense, but I'm really stuck and confused

and also I cannot IMPORT anything.

Reply With Quote
  #2  
Old November 21st, 2012, 10:43 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,458 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 4 Days 6 h 26 m 43 sec
Reputation Power: 403
Write import instead of IMPORT.
__________________
[code]Code tags[/code] are essential for python code!

Reply With Quote
  #3  
Old November 22nd, 2012, 07:51 AM
Quackajack Quackajack is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2012
Posts: 39 Quackajack User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 49 m 29 sec
Reputation Power: 1
You have massively overcomplicated the code so lets go back to the requirement. At first it would seem a dictionary is the way to go and it is if you want to optimise you code. However you can do it another way.

You need to record the votes for each given party so lets start with a list of the parties in the order you want them to appear. This can be done follows:
PARTIES = [ 'NDP' , 'GREEN' , 'LIBERAL' , 'CPC' ]

In general, given any list you can count the occurrances of a value with the count method. So to find the number of times the string NDP appears in the list votes you just need:
votes.count('NDP')

You have used max to get the party with the most votes which is a clever far beyond the rest of the code. This makes me think it was copied. By using the optional key value, it is giving the item a value of the number of times it appears in the list and picking the highest value.

If I put the value in brackets it might explain better. Using you example it will give the votes list the following values:
['GREEN' (3), 'GREEN' (3), 'NDP' (1), 'GREEN' (3), 'CPC' (1)]

It will then pick one (the first occurrance I think) with the highest value, in this case GREEN. Note that this has called count on the list 5 times in just this small example so it is very inefficent for large lists. It will also fail in some circumstances which I'll come back to later.

If you are going to do this, you might as use count to get the number of votes for each party. As we have a list of the parties this can be done with the map function as follows:
map(votes.count,PARTIES)

Python 3 users will have to use list to convert this to a list but thats all you need.

This gives you a working function in just a couple of lines:
Code:
def voting_plurality (votes):
    PARTIES = [ 'NDP' , 'GREEN' , 'LIBERAL' , 'CPC' ]
    return ( max(votes,key=votes.count) ,
        list(map(votes.count,PARTIES)) )


Not that the above would be something a new coder would produce so lets look at this from a beginners point of view.

You can loop through the votes list using a for loop as you have done. Rather than create a new dictionary entry for each different vote we are only interested in counting the parties in our PARTIES list. Any other value is spolit.

If you prepopulate the dictionary with all the parties having no votes you are guarenteed to record the party even if it achieves no votes. We could do this as follows but I will use the PARTIES list in the final code:
my_dct = { 'NDP':0 , 'GREEN':0 , 'LIBERAL':0 , 'CPC':0 }

Now we have all the parties votes in a dictionary. We can just loop through the dictionary recording the party with the highest votes and building up the list.

This gives:

Code:
def voting_plurality (votes):
    PARTIES = [ 'NDP' , 'GREEN' , 'LIBERAL' , 'CPC' ]

    # create a dictionary for all the parties with no votes
    my_dct = dict()
    for party in PARTIES:
        my_dct[party] = 0

    # loop through the votes list and record the votes cast in the dictionary
    spoilt = 0
    for ballot in votes:
        if ballot in PARTIES:
            my_dct[ballot] += 1
        else: # not a valid party
            spoilt += 1

    # find the party with the highest number of votes
    # and create a list of the votes in order
    winner = ""
    max = 0
    votes_in_order = list()
    for party in PARTIES:
        if my_dct[party] > max:
            winner = party
            max = my_dct[party]
        votes_in_order.append(my_dct[party])

    return ( winner , votes_in_order )


This is probably closer to the code expected and fixes the problems you mentioned.

Now to the problem you missed. What happens if two or more parties tie? For example if the votes cast are ['GREEN', 'GREEN', 'NDP', 'NDP', 'CPC', 'NDP', 'CPC', 'CPC'] it will currently show NDP as the winner even though it will show they tied with CPC on 3 votes each. I'll leave you to fix this as I think I've done enough.

Last edited by Quackajack : November 22nd, 2012 at 10:02 AM. Reason: variable spelling error

Reply With Quote
  #4  
Old November 22nd, 2012, 10:30 AM
Quackajack Quackajack is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2012
Posts: 39 Quackajack User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 h 49 m 29 sec
Reputation Power: 1
Taking it to the next level

At the risk of confusing you, the one advantage the second method with its single iteration of the passed in votes is you are not limited to lists.

Logically the votes are likely to be stored in a text file (which I'll call votes.txt) where each vote is on a seperate line. We can't pass this straight to our function as it will include the newline at the end.

Instead we can use a generator to strip out the newline as follows:
Code:
with open("votes.txt") as f:
    mygenerator = (line.strip() for line in f)
    result = voting_plurality(mygenerator)

Reply With Quote
  #5  
Old November 22nd, 2012, 08:00 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,458 b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level)b49P23TIvg User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 4 Days 6 h 26 m 43 sec
Reputation Power: 403
Quackajack, you cheated! At least I'm pretty sure you did. You wrote
PARTIES = [ 'NDP' , 'GREEN' , 'LIBERAL' , 'CPC' ]
by hand, that is you figured it out with your brain this one case rather than writing an algorithm to use the given information.

Also, to Softie's instructor, the two dictionaries a_to_b and b_to_a don't conflict when merged into a single dictionary because the key and value data types differ.
Code:
NDP_INDEX = 0
GREEN_INDEX = 1
LIBERAL_INDEX = 2
CPC_INDEX = 3

PARTY_INDICES = [NDP_INDEX, GREEN_INDEX, LIBERAL_INDEX, CPC_INDEX]

THIS_TO_THAT = {
  'NDP': NDP_INDEX,
  'GREEN': GREEN_INDEX,
  'LIBERAL': LIBERAL_INDEX,
  'CPC': CPC_INDEX,
  NDP_INDEX: 'NDP',
  GREEN_INDEX: 'GREEN',
  LIBERAL_INDEX: 'LIBERAL',
  CPC_INDEX: 'CPC'
}

def voting_plurality(votes):
    '''
        (list of str) -> tuple of (str, list of int)
        votes is a list of single-candidate ballots for a single riding.
        Based on votes, return a tuple where the first element is the name of the party
        winning the seat and the second is a list with the total votes for each party in
        the order specified in PARTY_INDICES.

        >>> voting_plurality(['GREEN', 'GREEN', 'NDP', 'GREEN', 'CPC'])
        ('GREEN', [1, 3, 0, 1])
    '''
    return(max(set(votes),key=votes.count),[votes.count(THIS_TO_THAT[idx]) for idx in PARTY_INDICES])

Last edited by b49P23TIvg : November 22nd, 2012 at 08:43 PM.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPython Programming > How to append the number of item frequencies in a list in Python 3.2?

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap