Part of the Whole


#1

Hi!

I have some trouble with the result of my code. It says: "Oops, try again. get_class_average([alice]) returned 83.8666666667 instead of 91.15 as expected"

Here is my 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]
}

aclass = [lloyd, alice, tyler]

Add your function below!

def average(numbers):
total = sum(numbers)
total = float(total)
result = total / len(numbers)
return result

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

def get_letter_grade(score):
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
elif score >= 60:
return "D"
else:
return "F"

print get_letter_grade(get_average(lloyd))

def get_class_average(students):
results = []
for student in aclass:
results.append(get_average(student))
return average(results)


What do I do wrong?

Thanks for your answer!


#2

Here. You are overriding your input students with the list, aclass. So no matter if you do get_class_average(alice) or get_class_average(lloyd), your function will always be calculating the average for your list, aclass = [lloyd, alice, tyler] instead of just alice or lloyd.


#3

def get_class_average(students): """ This code need to be changed because u should pass aclass of
students"""
results = []
for student in aclass:
results.append(get_average(student))
return average(results)


def get_class_average(aclass):
results = []
for student in aclass:
results.append(get_average(student))
return average(results)


#4

No. This defeats the purpose and meaning of a function because you are locking it to only one scenario(input). Then you don't need a function. Functions are useful in that you want to do the same steps to different scenarios(inputs) such as get_class_average(alice) or get_class_average([alice, lloyd]).


#5

Hey ,actually in his code he created aclass as list of those 3 students but instead he providing student list as input,if he provides aclass as input to that function it works without any error


#6

My point is that the function should take in inputs with ANY number of students (not just 3) by speculation.

Simply having a list AND a parameter (2 different things) with the same name makes the code design extremely ugly and confusing. It also muddles context and context is just as important as a working code.

Interesting, I'll need to research about this a bit.


#7

Even I got error when I executed the code . Then i created list and inputed that list to that function. In the above code he created aclass as list.

def get_class_average(students):
results = []
for student in aclass:
results.append(get_average(student))
return average(results)


As u said in first message it is correct,but in his code he is using "students" but in students he never assigned alice,lloyd or tylor so he is getting error. He should have made a call to function as
n=[alice,lloyd,tylor]
get_class_average(n)
Then it would have work. Anyway your suggestion was also true.


#8

Hmm seems like you're missing something here. He did assign students to something. He made it his function parameter here:

def get_class_average(students):

This parameter is assumed to be a list as you are using a loop later on. The problem was that he wasn't using students at all but instead, he's using aclass in his function. He was ignoring his parameter.

You are correct in the sense that he did use aclass for a list. However, with his code, he was basically always calculating the average of the 3 students regardless of input. He needs to change that aclass to students in the loop:

for student in students:

This provides better context and less confusion.

It may not make much difference now as this is just the last bit but if you wrote a huge program and did that, it will be super hard to debug.


Still looking for an explanation as to why a list and parameter with a shared name works. I just know it's not the best solution because it muddles context.

EDIT: Found explanation thanks to a friend of mine. Function scoping was what I was looking for.


#9

Yeah you are correct ,Thank You


#10

Thank you too! It has been a nice learning experience. To be honest, I've never really thought about this naming situation. I've just always used different names for different things. But thanks to this, I was able to find out more about context and some stuff about function scoping. :slight_smile:
It's been a pleasure talking to you.


#12