fathalpert
fathalpert

Reputation: 21

if comparison from dictionary lists

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

Answers (4)

Eithos
Eithos

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

buydadip
buydadip

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

Irshad Bhat
Irshad Bhat

Reputation: 8709

There are a few mistakes in your code:

  1. 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'].
  2. as I said assignment contains keys, so you need to call average with value of that key i.e., student[assignment]
  3. You are iterating over 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

austin1howard
austin1howard

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

Related Questions