Reputation: 21
I have a dictionary
alice = {
"name": "Alice",
"homework": [100.0, 92.0, 98.0, 100.0],
"quizzes": [82.0, 83.0, 91.0],
"tests": [89.0, 97.0]
}
and a function that takes the average of a list
def average(numbers):
return float(sum(numbers))/len(numbers)
I want the python function get_average(), to read through a dictionary. After that I want the function to take the average of a list in the dictionary and multiply the average of that list with a specific number (grading weights with .10 for homeworks,.30 for quizzes,or.60 for test) and give the total of the weighted homeworks, quizzes, and test. I am using a if statement to check whether the list selected from the for-loop in the dictionary is homework, quizzes, or tests.
def get_average(alice):
hw=0
qz=0
ts=0
for assignment in student:
if assignment== ["homework"]:
hw=average(assignment)*.10
if assignment==["quizzes"]:
qz=average(assignment)*.30
if assignment==["tests"]:
ts=average(assignment)*.60
return hw+qz+ts
This only returns zero. It should be 91.15
Upvotes: 2
Views: 123
Reputation: 2491
The other answers are more than adequate. I just wanted to have a bit of fun trying something different.
With this method, you can easily extend the depth of marking criteria without the function's size expanding too much with all the extra if
statements. It's also easier to edit, IMO, has less duplication going on and it's to the point.
alice = {
"name": "Alice",
"homework": [100.0, 92.0, 98.0, 100.0],
"quizzes": [82.0, 83.0, 91.0],
"tests": [89.0, 97.0]
}
def average(numbers):
return float(sum(numbers))/len(numbers)
def get_average(student):
criteria = {'homework': 0.10, 'quizzes': 0.30, 'tests': 0.60}
return sum(y * average(student[x]) for (x,y) in criteria.iteritems())
alice['average'] = get_average(alice)
print alice
Hope this helps.
Upvotes: 2
Reputation: 9427
If you're using python 3, use items()
, as iteritems()
has been removed from this version:
def get_average(alice):
tot = 0
for tests, grades in alice.items(): #iterates over keys and values
if tests == "homework":
tot += average(grades)*0.1
if tests == "quizzes":
tot += average(grades)*0.3
if tests == "tests":
tot += average(grades)*0.6
return tot
And yet another method using dict comprehension:
def get_average(alice):
tot = 0
gen = {test: average(grades) for test, grades in alice.items() if isinstance(grades, list)}
for test, grades in gen.items():
if test == "homework":
tot += grades*0.1
if test == "quizzes":
tot += grades*0.3
if test == "tests":
tot += grades*0.6
return tot
Upvotes: 0
Reputation: 8709
There are a few mistakes in your code:
assignment
iterates over keys of student i.e., 'name'
, 'homework'
etc. in get_average()
function. So compare it with string 'homework'
not with list ['homework']
.assignment
contains keys, so you need to call average
with value of that key i.e., student[assignment]
student
variable in get_average()
function, so it should be get_average(student)
rather than get_average(alice)
.Demo:
>>> def get_average(student):
... hw=0
... qz=0
... ts=0
... for assignment in student:
... # assignment iterates over keys of student i.e., 'name', 'homework' etc. So compare it with string 'homework' not with list ['homework']
... if assignment== "homework":
... # as I said assignment contains keys, so you need to call average with value of that key i.e., student[assignment]
... hw=average(student[assignment])*.10
... if assignment=="quizzes":
... qz=average(student[assignment])*.30
... if assignment=="tests":
... ts=average(student[assignment])*.60
... return hw+qz+ts
...
>>> def average(numbers):
... return float(sum(numbers))/len(numbers)
...
>>> alice = {
... "name": "Alice",
... "homework": [100.0, 92.0, 98.0, 100.0],
... "quizzes": [82.0, 83.0, 91.0],
... "tests": [89.0, 97.0]
... }
>>> get_average(alice)
91.14999999999999
Upvotes: 0
Reputation: 4955
Looping through a dictionary gives you the keys in the dict. You need to use the values for your average function. You can also loop through both keys and values at the same time with iteritems:
This should work:
for assignment, scores in student.iteritems():
if assignment=="homework":
hw=average(scores)*.10
if assignment=="quizzes":
qz=average(scores)*.30
if assignment=="tests":
ts=average(scores)*.60
return hw+qz+ts
You could also just loop through the dict and instead of scores have student[assignment], but that will require two lookups per loop iteration, so it's better to use iteritems.
Upvotes: 1