Just Weight and See Error


#1

Hello, I'm very new to Python and I am getting the following error when running my code shown below. Any suggestions?

Error: Oops, try again. get_average(alice) returned 339.0 instead of the expected 91.15

Code:
lloyd = {
"name": "Lloyd",
"homework": [90.0, 97.0, 75.0, 92.0],
"quizzes": [88.0, 40.0, 94.0],
"tests": [75.0, 90.0]
}
alice = {
"name": "Alice",
"homework": [100.0, 92.0, 98.0, 100.0],
"quizzes": [82.0, 83.0, 91.0],
"tests": [89.0, 97.0]
}
tyler = {
"name": "Tyler",
"homework": [0.0, 87.0, 75.0, 22.0],
"quizzes": [0.0, 75.0, 78.0],
"tests": [100.0, 100.0]
}

def average(student):
total = 0
for subject in student:
total += sum(student)
return total/len(student)

def get_average(student):
suma = 0
for key in student:
if key == "homework":
suma += average(student["homework"]) * .1
elif key == "quizzes":
suma += average(student["quizzes"]) * .3
else:
suma += average(student["tests"]) * .6
return suma


#2

Sometimes, one needs to be specific in their codes.
In this case, your else: statement seems to be also considering something else hence a larger number appears. If you change your else statement to elif key == "tests":, it works.
I'm also assuming everything is properly indented in the def get_average(student): function like this:

def get_average(student):
    suma = 0
    for key in student:
        if key == "homework":
            suma += average(student["homework"]) * .1
        elif key == "quizzes":
            suma += average(student["quizzes"]) * .3
        else: #change this to: elif key == "tests":
            suma += average(student["tests"]) * .6
    return suma

#3

Thanks for the help and quick response. My indentation is correct, not sure why when I paste it below it goes Left Justified.

I am getting closer and getting a similar error message.

Oops, try again. get_average(alice) returned 227.4 instead of the expected 91.15

lloyd = {
"name": "Lloyd",
"homework": [90.0, 97.0, 75.0, 92.0],
"quizzes": [88.0, 40.0, 94.0],
"tests": [75.0, 90.0]
}
alice = {
"name": "Alice",
"homework": [100.0, 92.0, 98.0, 100.0],
"quizzes": [82.0, 83.0, 91.0],
"tests": [89.0, 97.0]
}
tyler = {
"name": "Tyler",
"homework": [0.0, 87.0, 75.0, 22.0],
"quizzes": [0.0, 75.0, 78.0],
"tests": [100.0, 100.0]
}

def average(student):
total = 0
for subject in student:
total += sum(student)
return total/len(student)

def get_average(student):
suma = 0
for key in student:
if key == "homework":
suma += average(student["homework"]) * .1
elif key == "quizzes":
suma += average(student["quizzes"]) * .3
elif key == "tests":
suma += average(student["tests"]) * .6
return suma


#4

If you paste your code in between these sets of 3 ` marks it will give you the correct format :smiley: :

!  between these ` marks ----> ```

                              code goes here in between

!  between these ` marks ----> ```

Also read here for formatting posts:


#5

Somethings up with your def average(student): function. Did you use the same one as the previous lesson?

You don't need a for loop for that function. Function parameter should be numbers instead of student.
You need to find the total of the numbers by simply using sum(numbers) and float it so it can have decimals.
average should be the total divided by the length of numbers.

Your current average function seems to be adding everything up so you get a huge number.


#6

in this code you didnt specifically create the homework variable as directed in the instructions, however it worked . can you explain?


#7

also how are all the 3 averages being added up.?
first u added the avg of homework to suma
then seperaely added avg of quizzes to the same suma
now does the value of suma contain the sum of avg of homework and avg of quizzes


#8

I don't remember an instruction asking to create the homework variable but rather it is a key.
As for your second question, suma will contain the sum of everything you added to it so yes, it does contain the sum of avg of homework and the avg of quizzes. You're basically accumulating one variable in the loop which is suma.


#9

This is overkill, is it not?

    weights = {'homework': 0.1, 'quizzes': 0.3, 'tests': 0.6}
    suma = 0
    for key in student:
        suma += average(student['key']) * weights[key]
    return suma

That is what dictionaries were created for... Data lookup tables.


#10

Yes, I agree with you. I didn't want to completely transform the OP's code to something else if that is the approach they are going for.

I didn't suggest a less overkill way to do it. Sorry about that omission in my answer :slight_smile:

suma += average(student['key']) * weights[key]

Wouldn't this not work though? because student has no 'key' as key.

    weights = {"homework": 0.1, "quizzes": 0.3, "tests": 0.6}
    suma = 0
    for key in weights:
        suma += average(student[key]) * weights[key]
    return suma

fixed. Putting for loop as for key in student: will also include the "name" key which will throw an error.


#11

This gives context. Weights is a secondary reference with the same keys. Code needs to be readable, and giving context is how we make it readable.


#12

Then is there a way to exclude one key from the loop (for example the name key from student)? I'm just wondering out of curiosity.
Because that loop will include the name key which cannot be added as it is a string value and not an integer value. weights doesn't have the name key hence why I've used that instead.


#13

Ah! Now we're cooking with gas! I was hoping you would point that out. It means you tested it.

Since there is only the one non-list property, we can test for string type.

for key in student:
    if type(student[key]) == str: continue
    ...

Edit... Note the value, not the key needs to be tested for a string.


#14

Yea I was about to fix it while testing since it threw an error. But thanks for that. I learned something! :slight_smile:


#15

I've gone and put my foot in it... Give me a little time to sort this out and correct. Must take dog out and will get on it in the next hour. Sorry for the mess up.


#16

Nah, you didn't mess up. I was responding to your edit you made about having the value be tested for string instead of the key.


#17

Working proof of concept:

>>> def get_average(student):
    weights = {"homework": 0.1, "quizzes": 0.3, "tests": 0.6}
    total = 0
    for key in student:
        if type(student[key]) == str: continue
        total += average(student[key]) * weights[key]
    return total

>>> get_class_average(students)
83.86666666666666
>>>

#18

It finally struck me what struggles are avoided doing it this way. There is enough context around student and the objective is the weighting, so why not iterate the local variable? Then we don't need a check for string values. Never ceases to amaze me how stubbornly blind one can be when it's right there in black and white. Yes, I will defer to your approach. It's just smarter.


#19

Yeah that's what I did when using that approach.

Haha, yay. But maybe your approach could be useful in another situation. I'll still keep that in mind.
If context is unclear, I guess putting comments are always helpful.

I, on the other hand was not confident about my approach to say anything to defend it.
In the end, I learned something so thanks :slight_smile:


#20

def get_average (student):
homework = average(student["homework"])
quizzes = average(student["quizzes"])
tests = average(student["tests"])
return 0.1 * average(student["homework"]) + 0.3 * average(student["quizzes"]) + 0.6 * average(student["tests"])