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 4th, 2012, 04:32 PM
blobman23 blobman23 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 16 blobman23 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 41 m 15 sec
Reputation Power: 0
Could anyone help me on a Python programming assignment?

Hello, I have been working on an assignment and Iv gotten stuck and can't figure out what to fix.

The assignment:

Write a program that will read an unknown number of bowlers and their bowling scores (with possible values from 1 to 300) from an external file called "bowlingscores.txt". The file will look similar to the following:
David
102
Hector
300
Mary
195
Jane
160
Sam
210

Output the bowlers’ names to an external data file called "bowlingaverages.txt". Next to each bowler's name, print a message dependent on their scores:
For perfect scores (equal to 300), output “perfect”
For those scores greater than the average score, output “above average”
For those below average, output “below average”
Your program must include at least one function (e.g., to calculate the average, to determine the appropriate message to print, etc.).



Here is what I have so far:

Code:

def bowling_scores(filename):
    infile = open(filename, "r")
    bowling_info = []
    count = 0
    for line in infile:
        parts = line.split("/n") 
        count += 1
        if count == 1 or count % 2 == 1:
            info["name"] = parts[0]
        if count % 2 == 0:
            info["score"] = int(parts[0])
        bowling_info.append(info)
    infile.close()
    return bowling_info
def bowling_avg(filename):
    outfile = open(filename, "r")
    bowling_avg = []
    for key in sorted(bowling_info):
       score = bowling_info["score"]
       avg_score = (sum(score) / len(score))
       avg = ""
       if score == 300:
           avg = "perfect"
           bowling_avg.append(avg)
       elif score > avg_score:
           avg = "above average"
           bowling_avg.append(avg)
       elif score < avg_score:
           avg = "below average"
           bowling_avg.append(avg)
    outfile.close()  
    return bowling_avg
    
outfile = open("bowling_avg.txt", "w")
for key in sorted(bowling_avg):
    outfile.write("%s %s\n" % (bowling_info[name], avg))

Reply With Quote
  #2  
Old November 4th, 2012, 05:50 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 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 3 Days 8 h 3 m 36 sec
Reputation Power: 383
I'll modify your first function to return a list of dictionaries.
Code:
def bowling_scores(filename):
    infile = open(filename, "r")
    bowling_info = []
    count = 0
    for line in infile:
        parts = line.split("\n")
        count += 1
        if count == 1 or count % 2 == 1:
            info = dict(name=parts[0])  ########## make a new dictionary
        if count % 2 == 0:
            info["score"] = int(parts[0])
            bowling_info.append(info)  ####### indent this line!
    infile.close()
    return bowling_info


I have a file named bs with your sample data.
I call your function, and display the result, and I suggest you use this list of dictionaries as the input argument to the other function. Looks like this:
Code:
>>> bi = bowling_scores('bs')
>>> import pprint
>>> pprint.pprint(bi)
 {'name': 'David', 'score': 102},
 {'name': 'Hector', 'score': 300},
 {'name': 'Mary', 'score': 195},
 {'name': 'Jane', 'score': 160},
 {'name': 'Sam', 'score': 210}]
>>> 


I'd have made a dictionary keyed by name with a list of scores as the value for each key, but your list of little dictionaries is workable. Good luck!
__________________
[code]Code tags[/code] are essential for python code!

Reply With Quote
  #3  
Old November 4th, 2012, 06:27 PM
Schol-R-LEA's Avatar
Schol-R-LEA Schol-R-LEA is offline
Commie Mutant Traitor
Dev Shed Intermediate (1500 - 1999 posts)
 
Join Date: Jun 2004
Location: Norcross, GA (again)
Posts: 1,759 Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 2 Days 3 h 38 m 3 sec
Reputation Power: 1568
Oh, this is actually pretty close, in a lot of ways. Unfortunately, it also shows a number of serious misunderstandings with how Python works, ones which newcomers often have but which you'll need to get past to finish the problem. Let's start with the bowling_scores() function. Here, the biggest issue IMHO is that you are using a list for the data, but then treating it as if it were a dictionary.

Code:
import sys

def bowling_scores(filename):
    """ A function to collect the bowling scores
        from the input file and returns it in a dictionary.
            key == player's name
            value == player's score
    """
    try:
        infile = open(filename, "r")
    except:
        print("Could not read file '{0}'. Exiting.".format(filename))
        sys.exit(-1)

    bowling_info = dict()
    count = 0
    for line in infile:
        parts = line.split("\n")
        count += 1
        if count % 2 == 1:
            name = parts[0]               # odd line, get just the player's name
        else:
            score = int(parts[0])         # even line, get the player's score
            bowling_info[name] = score    # and store it in the dictionary keyed to name
    infile.close()
    return bowling_info


This was, I think, simply a confusion over what kind of data structure you were intending to use.

Note the use of the documentation string or docstring: if you put a string, either a regular one or a triple-quote multi-line string, immediately after the declaration part of a function, it is treated as the documentation for that function. The same applies to methods, classes, and modules, in fact.

For the second function, I think you are trying to fit too much into the same function, and getting snarled as a result. I would break it up into two functions, one of which simply returns the average, the other (which calls that function) which actually does the writing to the file.
Code:
def avg_score(scores):
    """ Function which takes a dictionary of bowling player's names and scores
        and returns the average of the scores (type float).
    """
    denominator = len(scores)
    numerator = 0
    for name in scores.keys():
        numerator += scores[name]
    return numerator / denominator


def bowling_averages(scores):
    """ Function that takes a scores dictionary
        and returns a list of strings describing the score
        relative to the average score.
    """
    scoreAverage = avg_score(scores)
    scoreDescriptions = list()

    for player in sorted(scores.keys()):
        score = scores[player]
        description = ''
        if score == 300:
           description = "perfect"
        elif score > scoreAverage:
           description = "above average"
        elif score == scoreAverage:
           description = "average"
        else:
           description = "below average"
        scoreDescriptions.append('{0}: {1}'.format(player, description))

    return scoreDescriptions


Finally, you'll need to re-write the __main__ section to reflect the changes made:
Code:
if __name__ == "__main__":
    scores = bowling_scores("bowlingscores.txt")
    descriptions = bowling_averages(scores)

    try:
        outfile = open("bowlingaverages.txt", "w")
    except:
        print("Could not open file 'bowling_averages.txt'. Exiting.")
        sys.exit(-1)

    for line in descriptions:
        print(line)
        outfile.write(line + '\n')
    outfile.close()

(NB: None of this is tested code, so I may well have made a mistake myself. Test it out careful before you submit anything.)
__________________
Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
#define KINSEY (rand() % 7) λ Scheme is the Red Pill
Scheme in ShortUnderstanding the C/C++ Preprocessor
Taming PythonA Highly Opinionated Review of Programming Languages for the Novice, v1.1

FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov

Last edited by Schol-R-LEA : November 4th, 2012 at 06:41 PM.

Reply With Quote
  #4  
Old November 4th, 2012, 06:41 PM
blobman23 blobman23 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 16 blobman23 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 41 m 15 sec
Reputation Power: 0
I appreciate everyone's help! I'm learning a lot. I have to keep in mind that sometimes when I look at code written by people that have been doing this much longer than I have, I can't just copy what yalls code says. I have to truly sit down and learn what yall are saying, because I have to then take the concept of it and simplify it into a more beginner level code. Otherwise, my instructor would just think I copied someone and didn't learn anything.

I made some revisions, and this is the error I am getting:

line 35, in <module>
for key in sorted(bowling_avg):
TypeError: 'function; object is not iterable

My code reads:

Code:
def bowling_scores(filename):
    infile = open(filename, "r")
    bowling_info = []
    count = 0
    for line in infile:
        parts = line.split("/n") 
        count += 1
        if count == 1 or count % 2 == 1:
            info = dict(name=parts[0])
        if count % 2 == 0:
            info["score"] = int(parts[0])
            bowling_info.append(info)
    infile.close()
    return bowling_info
def bowling_avg(filename):
    outfile = open(filename, "r")
    bowling_avg = []
    for key in sorted(bowling_info):
       score = bowling_info["score"]
       avg_score = (sum(score) / len(score))
       avg = ""
       if score == 300:
           avg = "perfect"
           bowling_avg.append(avg)
       elif score > avg_score:
           avg = "above average"
           bowling_avg.append(avg)
       elif score < avg_score:
           avg = "below average"
           bowling_avg.append(avg)
    outfile.close()  
    return bowling_avg
    
outfile = open("bowling_avg", "w")
for key in sorted(bowling_avg):
    outfile.write("%s %s\n" % (bowling_info[name], avg))
   

Reply With Quote
  #5  
Old November 4th, 2012, 08:52 PM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 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 3 Days 8 h 3 m 36 sec
Reputation Power: 383
Perhaps my post was too subtle.

Where you have

for key in sorted(bowling_avg):

bowling_avg is a function. You didn't call the function to get its return value. How do we know? Of course the error message says so. I find that printing the type and value of the object in doubt right before the error helps.

print(str(type(bowling_avg)));print(str(bowling_avg))# new line 35
for key in sorted(bowling_avg):

That might help you understand a little bit.
Your bowling_avg function needs a string argument, which it uses to open a file for read access with the unlikely named variable "outfile" but you don't use outfile except to close it later. As scholar-LEA says, close but there's a lot of misunderstanding in there.

As I said before, passing the list of little dictionaries created by bowling_scores into bowling_avg makes a lot more sense. And as Scholar-LEA said, you'll need to change your main code to actually call bowling_scores. Defining a function doesn't invoke that function. You need to call the function, just like you knew to do with
open(filename, "r")

Reply With Quote
  #6  
Old November 4th, 2012, 09:16 PM
blobman23 blobman23 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 16 blobman23 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 41 m 15 sec
Reputation Power: 0
Thanks, I see what your saying. Ill work on it some more and ill post what I come up with. I appreciate it.

Reply With Quote
  #7  
Old November 5th, 2012, 09:01 PM
blobman23 blobman23 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2012
Posts: 16 blobman23 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 41 m 15 sec
Reputation Power: 0
ok this is what I have come up with. I' afraid that I have gotten too lost and will have to just start fresh. What do you think?

Code:
def bowling_scores(filename):
    infile = open(filename, "r")
    bowling_info = []
    count = 0
    for line in infile:
        parts = line.split("/n") 
        count += 1
        if count == 1 or count % 2 == 1:
            name = parts[0]
        else:
            score = int(parts[0])
            bowling_info[name] = score
    infile.close()
    return bowling_info

def avg_score(scores):
    denominator = len(scores)
    numerator = 0
    for name in scores.keys():
        numerator += scores[name]
    return numerator / denominator
    
def bowling_averages(scores):

   
    scoreAverage = avg_score(scores)
    scoreDescriptions = list()

    for player in sorted(scores.keys()):
        score = scores[player]
        description = ''
        if score == 300:
           description = "perfect"
        elif score > scoreAverage:
           description = "above average"
        elif score == scoreAverage:
           description = "average"
        else:
           description = "below average"
        scoreDescriptions.append('{0}: {1}'.format(player, description))

    return scoreDescriptions

    
scores = bowling_scores("bowlingscores.txt")
descriptions = bowling_averages(scores)    
outfile = open("bowling_avg.txt", "w")
for line in description:
    outfile.write(line + "/n" )
outfile.close()

Reply With Quote
  #8  
Old November 6th, 2012, 09:01 AM
b49P23TIvg's Avatar
b49P23TIvg b49P23TIvg is offline
Contributing User
Dev Shed Loyal (3000 - 3499 posts)
 
Join Date: Aug 2011
Posts: 3,353 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 3 Days 8 h 3 m 36 sec
Reputation Power: 383
I think that you need to actually let python process your program. You'll soon start to learn how to use the python error messages.

I checked only Hector, your output was correct for Hector.

Anyway, you're program is now pretty close, I fixed it with small changes, and marked the lines I changed with comments. Please run your original program and try to figure out why the changes I made were important.

Also, I'm quite sure I can create an input file that will produce different answers when run on python2 versus python3. It may be subtle but in your next program you'll probably ask why 3/2 is 1.

Also, 1%2 is 1.

Also, your program limitation (based on the way I modified it) is one game per player. That might be given in the problem statement. Or you could call this a feature, saying that only the last entry per player is counted and therefor the input is particularly easy to edit.

Also, that's all the alsos.
Code:
import sys

def bowling_scores(filename):
    infile = open(filename, "r")
    bowling_info = dict()                    # was list()   #[]
    count = 0
    for line in infile:
        parts = line.split("/n")
        count += 1
        if count == 1 or count % 2 == 1:
            name = parts[0]
        else:
            score = int(parts[0])
            bowling_info[name] = score
    infile.close()
    return bowling_info

def avg_score(scores):
    denominator = len(scores)
    numerator = 0
    for name in scores.keys():
        numerator += scores[name]
    return numerator / denominator

def bowling_averages(scores):
    scoreAverage = avg_score(scores)
    scoreDescriptions = list()
    for player in sorted(scores.keys()):
        score = scores[player]
        description = ''
        if score == 300:
           description = "perfect"
        elif score > scoreAverage:
           description = "above average"
        elif score == scoreAverage:
           description = "average"
        else:
           description = "below average"
        scoreDescriptions.append('{0}: {1}'.format(player, description))
    return scoreDescriptions

if 'linux' in sys.platform:
    filename = '/tmp/bs'
else:
    filename = "bowlingscores.txt"

scores = bowling_scores(filename)

descriptions = bowling_averages(scores)
outfile = open("bowling_avg.txt", "w")
for line in descriptions:                 # descriptions was singular
    outfile.write(line + "\n" )           # was  "/n"
outfile.close()

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPython Programming > Could anyone help me on a Python programming assignment?

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