Python function to get lowest and average score - python

I am a newbie to python programming. I am working on a class homework and got the code below so far. The next step that am struggling with is to write a function the would show / print the lowest score and average score. Any direction would be much appreciated.
scores = """Aturing:Mark$86:
Inewton:Mark$67.5:
Cdarwin:Mark$90:
Fnightingale:Mark$99:
Cvraman:Mark$10:"""
students = {}
for studentdata in scores.split('\n'):
data = studentdata.split(':')
name = data[0]
students[name] = {}
for class_data in data[1:]:
if class_data:
Mark,class_score = class_data.split('$')
students[name][Mark] = class_score
def Grade_Show(student,Mark):
if student in students:
if Mark in students[student]:
print "Student %s got %s in the assignment %s" % (student,students[student][Mark],Mark)
else:
print "subject %s not found for student %s" % (Mark,student)
else:
print "student %s not found" % (student)
#do some testing
Grade_Show("Inewton","Mark")

Testing with: scores = {'alex': 1, 'dave': 1, 'mike': 2};
Firstly, to find the lowest score, use the min() function.
So:
min_keys = [k for k, x in scores.items() if not any(y < x for y in scores.values())]
print('Lowest score:', str(min(scores.values())) + '.', 'Achieved by: ')
for student in min_keys:
print(student)
Output:
Lowest score: 1. Achieved by:
alex
dave
Secondly, assuming you are looking for the mean average, you would do this:
print('The average score was:', str(sum(scores.values()) / len(scores)))
Output:
The average score was: 1.3333333333333333
Hope I helped!- All you need to do now is create a function containing that code, with a parameter called data. That way you can have multiple dictionaries to represent different classes or tests. You would replace all instances of score in the code with data.
Also, the 'minimum score' code could be easily modified to give the maximum score. Finally, depending on the size of your program you could store the output in a variable rather than using a print statement so you can recall it later. This would also mean that you should return the result, not print it.

The next step that am struggling with is to write a function the would
show / print the lowest score and average score.
Step 1:
Can you iterate through your data structure (students) and print only the scores? If you can do that, then you should be able to run through and find the lowest score.
To find the lowest score, start with some imagined maximum possible value (set some variable equal to 100, for example, if that's the highest possible) and iterate through all the scores (for score in score..., etc.), testing to see if each value you get is lower than the variable you created.
If it is lower, make the variable you created equal to that lower value. After that, it will continue iterating to see if any new value is less than this new 'lowest' value. By the time it reaches the end, it should have provided you with the lowest value.
One tricky part is making sure to print both the name and lowest value, if that's what the question requires.
Step: 2
To solve the average problem, you'll do to something similar where you iterate over the scores, add them to a new data structure and then figure out how to take an average of them.

Related

Dictionary in python for implementing the 37% Rule

I am trying the famous 37% rule from the book- "Algorithms to live by" by Brian Christian.
The 37% Rule basically says that when you need to screen a range of options in a limited amount of time - be they candidates for a job, new apartments, or potential romantic partners - the best time to make a decision is when you've looked at 37% of those options.
At that point in a selection process, you'll have gathered enough information to make an informed decision, but you won't have wasted too much time looking at more options than necessary. At the 37% mark, you're in a good place to pick the best of the bunch.
A common thought experiment to demonstrate this theory - developed by non-PC math guys in the 1960s - is called "The Secretary Problem."
The program is running but I wanted to start to consider selecting the candidates after 37% of the candidates. Since I am using dictionary, I do not get to access the elements after a specified number of candidates. How can I make this possible?
import matplotlib.pyplot as plt
# for visualising scores
def initiate(candidates):
print("Total candidates are : ",len(candidates))
lookup_num=int(len(candidates) *0.37)
#finds 37% of the candidates
average=lookup(candidates)
# returns average of lookup phase
chosen=select_cad(candidates,lookup_num,average)
# selects a candidate based on lookUp average
print("The chosen candidate is : {} ".format(chosen))
def lookup(candidates):
average_score=0
for cands,score in candidates.items():
average_score+=score
average_score=int(average_score/len(candidates))
print("The average score in lookup is : ",average_score)
#return the average score to average local variable
return average_score
def select_cad(candidates,lookup_num,average):
for cands,score in candidates.items():
if(score>average):
return cands
else:
continue
print("Something went wrong!")
quit
candidates={"Husain":85, "Chirag":94 ,"Asim":70,"Ankit":65 ,"Saiteja":65 ,"Absar":75 ,"Premraj":70 ,"Sagar":75 ,"Himani":75 ,"Parth":76 ,"Sumedha":70 ,"Revati":65 ,"Sageer":65 ,"Noorjahan":60 ,"Muzammil":65 ,"Shifa":56 , "Dipti":65 , "Dheeraj":70 }
initiate(candidates)
plt.bar(range(len(candidates)), list(candidates.values()), align='center', color='green')
plt.xticks(range(len(candidates)), list(candidates.keys()))
plt.show()
How can I make it more flexible to update the average score even in selection phase?
Just read about this "Rule of 37%" so I hope I understood it correctly. I would implement something like that:
import random
def rule_of_37(candidates):
# first I date random 37% of the candidates
who_i_date = random.sample(list(candidates), int(len(candidates)*.37))
print("I meet those 37% of the candidates", who_i_date)
# then I calculate their average score
average = sum(candidates[name] for name in who_i_date) / len(who_i_date)
print("The average score was", average)
# then I settle with the next person that has a score higher than the average (obviously I cannot re-date candidates)
# hopefully there is still someone with an higher score than average...
try:
who_i_marry = next(name
for name, score in candidates.items()
if name not in who_i_date
and score > average)
print("I end up with", who_i_marry, "who has a score of", candidates[who_i_marry])
except StopIteration:
print("I end up all alone, there was nobody left with an higher score than", average, "...")
candidates={"Husain":85, "Chirag":94 ,"Asim":70,"Ankit":65 ,"Saiteja":65 ,"Absar":75 ,"Premraj":70 ,"Sagar":75 ,"Himani":75 ,"Parth":76 ,"Sumedha":70 ,"Revati":65 ,"Sageer":65 ,"Noorjahan":60 ,"Muzammil":65 ,"Shifa":56 , "Dipti":65 , "Dheeraj":70 }
rule_of_37(candidates)
Example execution (yours may vary since the first 37% candidates are picked at random):
I meet those 37% of the candidates ['Dipti', 'Chirag', 'Revati', 'Sumedha', 'Dhe
eraj', 'Muzammil']
The average score was 71.5
I end up with Husain who has a score of 85
If you want to select the first candidates yourself instead of relying on random, you can simply replace who_i_date by your pre-selected list:
who_i_date = ['Husain', 'Chirag', 'Asim', 'Ankit', 'Saiteja', 'Absar']
But then the other 63% will be arbitrarily ordered so you may not always select the same one (unless you use Python 3.6+ which keeps dicts in order by default). If you want to date the remaining 63% in order, you have to iterate over a list of the candidates names rather than on the dict that maps names to scores.
I leave that up to you.
You can use lookup_num along with numpy to simulate what candidates are "seen" within your function and then calculate the average score. This function will randomly select lookup_num number of candidates from your dictionary (without replacement). Using that subset the average_score is calculated. The function will return the average score along with the dictionary of "seen" candidates to determine who was the best candidate from the 37% subset.
def lookup(candidates,lookup_num):
# Randomly select lookup_num candidates without replacement
seen_names = np.random.choice(candidates.keys(), size=lookup_num, replace=False)
# Create a dictionary with the scores from the seen candidates.
seen = {k: v for (k, v) in candidates.items() if k in seen_names}
# Calculate the average score for the candidates who were seen
average_score = sum([v for (k, v) in seen.items()]) / float(lookup_num)
return seen, average_score
Your code calling lookup would become:
seen, average_score=lookup(candidates,lookup_num)
With the average_score and the list of candidates who were seen you can compare that to the rest of the candidates and apply your decision criteria for choosing the best candidate.
I've updated my previous code with a few variables and used lookup_num for iterating. Still using the unordered dictionary and it works like a charm. Check it out.
import matplotlib.pyplot as plt
# for visualising scores
def initiate(candidates):
print("Total candidates are : ",len(candidates))
lookup_num=int(len(candidates) *0.37)
#finds 37% of the candidates
average, lookup_candidates=lookup(candidates,lookup_num)
# returns average of lookup phase
chosen=select_cad(candidates,lookup_num,average,lookup_candidates)
# selects a candidate based on lookUp average
print("The chosen candidate is : {} ".format(chosen))
def lookup(candidates,lookup_num):
average_score=0
count=0
lookup_candidates=[]
for cands,score in candidates.items():
if(not count>=lookup_num):
lookup_candidates.append(cands)
average_score+=score
count+=1
average_score=int(average_score/count)
print("Look Up candidates are : ",lookup_candidates)
print("The average score in lookup is : ",average_score)
#return the average score to average local variable
return average_score,lookup_candidates
def select_cad(candidates,lookup_num,average,lookup_candidates):
for cands,score in candidates.items():
if(score>average and cands not in lookup_candidates):
#because 37% rule does not allows us to go back to select a candidate from the lookup phase
return cands
#return selected candidate to chosen variable
else:
continue
print("Something went wrong!")
quit
candidates={"Husain":85, "Chirag":94 ,"Asim":70,"Ankit":65 ,"Saiteja":65 ,"Absar":75 ,"Premraj":70 ,"Sagar":75 ,"Himani":75 ,"Parth":76 ,"Sumedha":70 ,"Revati":65 ,"Sageer":65 ,"Noorjahan":60 ,"Muzammil":65 ,"Shifa":56 , "Dipti":65 , "Dheeraj":70 }
initiate(candidates)
plt.bar(range(len(candidates)), list(candidates.values()), align='center', color='green')
plt.xticks(range(len(candidates)), list(candidates.keys()))
plt.xlabel("Candidates")
plt.ylabel("Score")
plt.title("37% Algorithm")
plt.show()

Using returned outputs from one function in another in Python

new to Python - struggling with functions. - Image of code attached.
It inputs the name & scores just fine with the validation checks.
I need to use the scores input by the user and total them.
However, when I've tried to sum(score) it doesn't like it.
I can't work out how to sum the 4 total scores.
Please help :) Also would love any feedback on the style of coding etc.
Thanks in advance x
Image: Code in Python
I would rewrite the main function to be something like:
def GetStudentInput():
score = 0
for i in range (4):
print("Mrs Pearson's Class Test Score Data")
name = CheckStringInput("What's Your Name: ")
score += CheckNumericInput("What's Your Score: ")
print(score)
This eliminates the need for an extra function and avoids using a list since you don't appear to need the individual values elsewhere -- only the sum total.
In the absense of code for people to see, we have something like
def get_stuff():
for i in rnage(4):
name = input("Name?")
score = int(input("Score?"))
and another function
def TotalScore():
pass
How do we call total score?
Answer: Make sure we don't forget the user inputs and return them:
def get_stuff():
names = []
scores = []
for i in range(4):
names.append(input("Name?"))
scores.append(int(input("Score?")))
return names, scores
and take the scores in the summing function:
def TotalScore(scores):
return sum(scores)
This, of course, changes the calling code.
For example, you need to capture the returns when you call get_stuff:
names, scores = get_stuff()
total = TotalScores(scores)

What is the easiest way "pair" strings in one list with integers in another (in python)?

I'm working on a school project which has to store the names of people and their respective score on a test in a list so that I can manipulate it to find averages as well as printing out each persons score with their name. Relatively new to Python so any help is appreciated :)
I would recommend using a dictionary. This pairs keys (the name of students) to values (the score on a test). Here is an example below that gets you the output that you would want.
import math
student_scores = {}
student_scores['Rick'] = 89
student_scores['Pat'] = 79
student_scores['Larry'] = 82
score_list = []
for name, score in student_scores.items():
score_list.append(score)
print(name.title() + "'s score was: " + str(score) + '%')
sum_scores = sum(score_list)
division_scores = len(score_list)
average_score = sum_scores / division_scores
print('The average score was {0:.2f}%'.format(average_score))
I created an empty dictionary that you will use to add student names and scores to a list. So in the dictionary (student_scores) The student name 'Rick' will be a key, and the score 89 will the value. I do this for 2 additional students, pairing their name up with the score that they received.
I create an empty list called score_list. You'll use this list later to add he sum of all scores, and divide by the number of total scores to get an average score for your test.
We start a for loop that iterates over each key and value in your dictionary. For each score, we append it to the empty score list. For each name and score, we print a message showing what the student got on the test.
Now that we have appended the scores to the dictionary we can use the sum method to get the sum of all scores in your score list. We put it in a variable called sum_scores. We also get the number of scores in your list by finding the length of the list (which will be 3 in this case since I put 3 scores in it). We will store that in a variable called division_scores (since I am dividing the sum of all scores by the number of scores recorded). We create a variable called average_score which is the result of the sum of scores divided by the total number of observations.
We then print what the average score was using the .format() method. We just format the average score so that you get it to extend two decimal places {0:.2f}%.
Your output is as follows:
Rick's score was: 89%
Pat's score was: 79%
Larry's score was: 82%
The average score was 83.33%
The above answer is a great data structure for pairing strings. It'll set you on the right track for enumerating scores, averages, etc in simple cases.
Another way to store relationships is with classes (or tuples, at the bottom!) There's a rough sketch of an OOP approach below.
The most important parts are
The properties of the ExamAttempt class store the information (names, scores)
In the Exam.record_attempt method, a new ExamAttempt object is created from the ExamAttempt class and added to the list of attempts on the Exam object.
From here, you could easily add other features. You'd probably want to model a Question and Answer, and maybe a Student object too, if you're going all out. If you store questions and answers, as well as which answer each student selected, you can start doing things like throwing out questions, grading on a curve, discovering questions to throw out, etc. The OOP approach makes it easier to extend functionality like plotting all kinds of fancy graphs, export to CSV or Excel, and so on.
Not all of the code below is necessary.. it can definitely be simplified a little, or reimagined entirely, but hopefully this should give you enough to start looking down that path. Even if it seems complicated now, it's not that bad, and it's what you'll want to be doing eventually (with Python, anyway!)
class ExamAttempt:
def __init__(self, id, name, correct, total):
self.id = id
self.name = name
self.correct = correct
self.total = total
self.score = (self.correct / float(self.total))
def __repr__(self):
return "<ExamAttempt: Id={}, Student={}, Score={}>".format(self.id, self.name, self.score)
class Exam:
def __init__(self, name, questions):
self.name = name
self.attempts = []
self.questions = questions
self.num_questions = len(questions)
def __str__(self):
return "<Exam ({})>".format(self.name)
def load(self, filename):
pass
def saveAttemptsToFile(self, filename):
pass
def record_attempt(self, student_name, num_correct):
id = len(self.attempts) + 1
self.attempts.append(
ExamAttempt(id, student_name, num_correct, self.num_questions))
def get_student_attempt(self, student_name):
for att in self.attempts:
if student_name == att.name:
return att
def get_average_score(self):
return "homework"
def get_results_by_score(self):
return sorted(self.attempts, key=lambda x: x.score, reverse=True)
def get_attempts_by_name(self):
return sorted(self.attempts, key=lambda x: x.name)
if __name__ == '__main__':
questions = ['Question?' for i in range(100)] # Generate 100 "questions" = 100%
exam = Exam('Programming 101', questions)
data = [('Rick', 89), ('Pat', 79), ('Larry', 82)]
for name, correct in data:
exam.record_attempt(name, correct)
for attempt in exam.get_results_by_score():
print("{} scored {}".format(attempt.name, attempt.score))

Python: creating a dictionary that writes high scores to a file

First: you don't have to code this for me, unless you're a super awesome nice guy. But since you're all great at programming and understand it so much better than me and all, it might just be easier (since it's probably not too many lines of code) than writing paragraph after paragraph trying to make me understand it.
So - I need to make a list of high scores that updates itself upon new entries. So here it goes:
First step - done
I have player-entered input, which has been taken as a data for a few calculations:
import time
import datetime
print "Current time:", time1.strftime("%d.%m.%Y, %H:%M")
time1 = datetime.datetime.now()
a = raw_input("Enter weight: ")
b = raw_input("Enter height: ")
c = a/b
Second step - making high score list
Here, I would need some sort of a dictionary or a thing that would read the previous entries and check if the score (c) is (at least) better than the score of the last one in "high scores", and if it is, it would prompt you to enter your name.
After you entered your name, it would post your name, your a, b, c, and time in a high score list.
This is what I came up with, and it definitely doesn't work:
list = [("CPU", 200, 100, 2, time1)]
player = "CPU"
a = 200
b = 100
c = 2
time1 = "20.12.2012, 21:38"
list.append((player, a, b, c, time1))
list.sort()
import pickle
scores = open("scores", "w")
pickle.dump(list[-5:], scores)
scores.close()
scores = open("scores", "r")
oldscores = pickle.load(scores)
scores.close()
print oldscores()
I know I did something terribly stupid, but anyways, thanks for reading this and I hope you can help me out with this one. :-)
First, don't use list as a variable name. It shadows the built-in list object. Second, avoid using just plain date strings, since it is much easier to work with datetime objects, which support proper comparisons and easy conversions.
Here is a full example of your code, with individual functions to help divide up the steps. I am trying not to use any more advanced modules or functionality, since you are obviously just learning:
import os
import datetime
import cPickle
# just a constants we can use to define our score file location
SCORES_FILE = "scores.pickle"
def get_user_data():
time1 = datetime.datetime.now()
print "Current time:", time1.strftime("%d.%m.%Y, %H:%M")
a = None
while True:
a = raw_input("Enter weight: ")
try:
a = float(a)
except:
continue
else:
break
b = None
while True:
b = raw_input("Enter height: ")
try:
b = float(b)
except:
continue
else:
break
c = a/b
return ['', a, b, c, time1]
def read_high_scores():
# initialize an empty score file if it does
# not exist already, and return an empty list
if not os.path.isfile(SCORES_FILE):
write_high_scores([])
return []
with open(SCORES_FILE, 'r') as f:
scores = cPickle.load(f)
return scores
def write_high_scores(scores):
with open(SCORES_FILE, 'w') as f:
cPickle.dump(scores, f)
def update_scores(newScore, highScores):
# reuse an anonymous function for looking
# up the `c` (4th item) score from the object
key = lambda item: item[3]
# make a local copy of the scores
highScores = highScores[:]
lowest = None
if highScores:
lowest = min(highScores, key=key)
# only add the new score if the high scores
# are empty, or it beats the lowest one
if lowest is None or (newScore[3] > lowest[3]):
newScore[0] = raw_input("Enter name: ")
highScores.append(newScore)
# take only the highest 5 scores and return them
highScores.sort(key=key, reverse=True)
return highScores[:5]
def print_high_scores(scores):
# loop over scores using enumerate to also
# get an int counter for printing
for i, score in enumerate(scores):
name, a, b, c, time1 = score
# #1 50.0 jdi (20.12.2012, 15:02)
print "#%d\t%s\t%s\t(%s)" % \
(i+1, c, name, time1.strftime("%d.%m.%Y, %H:%M"))
def main():
score = get_user_data()
highScores = read_high_scores()
highScores = update_scores(score, highScores)
write_high_scores(highScores)
print_high_scores(highScores)
if __name__ == "__main__":
main()
What it does now is only add new scores if there were no high scores or it beats the lowest. You could modify it to always add a new score if there are less than 5 previous scores, instead of requiring it to beat the lowest one. And then just perform the lowest check after the size of highscores >= 5
The first thing I noticed is that you did not tell list.sort() that the sorting should be based on the last element of each entry. By default, list.sort() will use Python's default sorting order, which will sort entries based on the first element of each entry (i.e. the name), then mode on to the second element, the third element and so on. So, you have to tell list.sort() which item to use for sorting:
from operator import itemgetter
[...]
list.sort(key=itemgetter(3))
This will sort entries based on the item with index 3 in each tuple, i.e. the fourth item.
Also, print oldscores() will definitely not work since oldscores is not a function, hence you cannot call it with the () operator. print oldscores is probably better.
Here are the things I notice.
These lines seem to be in the wrong order:
print "Current time:", time1.strftime("%d.%m.%Y, %H:%M")
time1 = datetime.datetime.now()
When the user enters the height and weight, they are going to be read in as strings, not integers, so you will get a TypeError on this line:
c = a/b
You could solve this by casting a and b to float like so:
a = float(raw_input("Enter weight: "))
But you'll probably need to wrap this in a try/catch block, in case the user puts in garbage, basically anything that can't be cast to a float. Put the whole thing in a while block until they get it right.
So, something like this:
b = None
while b == None:
try:
b = float(raw_input("Enter height: "))
except:
print "Weight should be entered using only digits, like '187'"
So, on to the second part, you shouldn't use list as a variable name, since it's a builtin, I'll use high_scores.
# Add one default entry to the list
high_scores = [("CPU", 200, 100, 2, "20.12.2012, 4:20")]
You say you want to check the player score against the high score, to see if it's best, but if that's the case, why a list? Why not just a single entry? Anyhow, that's confusing me, not sure if you really want a high score list, or just one high score.
So, let's just add the score, no matter what:
Assume you've gotten their name into the name variable.
high_score.append((name, a, b, c, time1))
Then apply the other answer from #Tamás
You definitely don't want a dictionary here. The whole point of a dictionary is to be able to map keys to values, without any sorting. What you want is a sorted list. And you've already got that.
Well, as Tamás points out, you've actually got a list sorted by the player name, not the score. On top of that, you want to sort in downward order, not upward. You could use the decorate-sort-undecorate pattern, or a key function, or whatever, but you need to do something. Also, you've put it in a variable named list, which is a very bad idea, because that's already the name of the list type.
Anyway, you can find out whether to add something into a sorted list, and where to insert it if so, using the bisect module in the standard library. But it's probably simpler to just use something like SortedCollection or blist.
Here's an example:
highscores = SortedCollection(scores, key=lambda x: -x[3])
Now, when you finish the game:
highscores.insert_right((player, a, b, newscore, time1))
del highscores[-1]
That's it. If you were actually not in the top 10, you'll be added at #11, then removed. If you were in the top 10, you'll be added, and the old #10 will now be #11 and be removed.
If you don't want to prepopulate the list with 10 fake scores the way old arcade games used to, just change it to this:
highscores.insert_right((player, a, b, newscore, time1))
del highscores[10:]
Now, if there were already 10 scores, when you get added, #11 will get deleted, but if there were only 3, nothing gets deleted, and now there are 4.
Meanwhile, I'm not sure why you're writing the new scores out to a pickle file, and then reading the same thing back in. You probably want to do the reading before adding the highscore to the list, and then do the writing after adding it.
You also asked how to "beautify the list". Well, there are three sides to that.
First of all, in the code, (player, a, b, c, time1) isn't very meaningful. Giving the variables better names would help, of course, but ultimately you still come down to the fact that when accessing list, you have to do entry[3] to get the score or entry[4] to get the time.
There are at least three ways to solve this:
Store a list (or SortedCollection) of dicts instead of tuples. The code gets a bit more verbose, but a lot more readable. You write {'player': player, 'height': a, 'weight': b, 'score': c, 'time': time1}, and then when accessing the list, you do entry['score'] instead of entry[3].
Use a collection of namedtuples. Now you can actually just insert ScoreEntry(player, a, b, c, time1), or you can insert ScoreEntry(player=player, height=a, weight=b, score=c, time=time1), whichever is more readable in a given case, and they both work the same way. And you can access entry.score or as entry[3], again using whichever is more readable.
Write an explicit class for score entries. This is pretty similar to the previous one, but there's more code to write, and you can't do indexed access anymore, but on the plus side you don't have to understand namedtuple.
Second, if you just print the entries, they look like a mess. The way to deal with that is string formatting. Instead of print scores, you do something like this:
print '\n'.join("{}: height {}, weight {}, score {} at {}".format(entry)
for entry in highscores)
If you're using a class or namedtuple instead of just a tuple, you can even format by name instead of by position, making the code much more readable.
Finally, the highscore file itself is an unreadable mess, because pickle is not meant for human consumption. If you want it to be human-readable, you have to pick a format, and write the code to serialize that format. Fortunately, the CSV format is pretty human-readable, and most of the code is already written for you in the csv module. (You may want to look at the DictReader and DictWriter classes, especially if you want to write a header line. Again, there's the tradeoff of a bit more code for a lot more readability.)

Summing Only First Values When in Dictionary When Keys Correspond To Lists (Python)

I'm working in python 2.7. I have a list of teams in the following dictionary:
NL = {'Phillies': [662, 476], 'Braves': [610, 550], 'Mets': [656, 687]}
The first value in the list is the amount of runs scored the team has, and the second is the amount of runs that team has given up.
I'm using this code to determine the Pythagorean winning percentage of each team, but I would also like to be able to have the function calculate the total number of runs scored and allowed by the group as a whole.
Right now I'm using:
Pythag(league):
for team, scores in league.iteritems():
runs_scored = float(scores[0])
runs_allowed = float(scores[1])
win_percentage = (runs_scored**2)/((runs_scored**2)+(runs_allowed**2))
total_runs_scored = sum(scores[0] for team in league)
print '%s: %f' % (team, win_percentage)
print '%s: %f' % ('League Total:', total_runs_scored)
I'm not sure exactly what is going on with the sum function, but instead of getting one value, I'm getting a different value over each iteration of the team and win_percentage, and it's not the same value...
Ideally, the function would just return one value for the sum of the runs scored for each team in the dictionary.
Thanks for any help.
If you want to have the running total available, or don't want to iterate over league twice, you can do:
def Pythag(league):
total_runs_scored = 0
for team, scores in league.iteritems():
# other stuff
total_runs_scored += scores[0]
# other stuff
# runs scored by all teams up to this point
print 'League Running Total of Runs Scored: %f' % (total_runs_scored,)
# outside the loop, so total runs scored in the league.
# will be the same as the last one in the loop
print 'League Total Runs Scored: %f' % (total_runs_scored,)
Remember that inside the loop you're talking about a single team, so you don't need to do a sum to get the runs scored by that team, you instead need to add it to the runs scored by all the previous teams, that is, the scores[0] from the previous iterations of the loop.

Categories