8. Part of the Whole: TypeError: string indices must be integers, not str


#1



https://www.codecademy.com/courses/python-beginner-en-qzsCL/1/4?curriculum_id=4f89dab3d788890003000096


I get a strange TypeError:

Traceback (most recent call last):
File "python", line 87, in
File "python", line 83, in get_class_average
File "python", line 41, in get_average
TypeError: string indices must be integers, not str

In case the line numbers don't show up, here are the referenced lines numbers:

Line 87, at the very end:

get_class_average(student)

Line 83, in the get_class_average function:

results.append(get_average(student))

Line 41, in the get_average function:

homework = average(student["homework"])


I don't understand how line 41, here again:

homework = average(student["homework"])

can have this error, because, as shown by all the PRINT statements, line 41 seems to work just fine in the rest of the computations. . . .

(Also, as you can see from the commented print statements in the get_class_average function, I was attempting to see what was going on and debug, but then I figured that might have led to the TypeError, so I went with my understanding of exactly what the instructions asked for, but I still get the TypeError.)


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]
}

# Creates class list:
students = [lloyd, alice, tyler]

# Prints each student's data:
for student in students:
    print student["name"].upper()
    print "Homework: " + str(student["homework"])
    print "Quizzes: " + str(student["quizzes"])
    print "Tests: " + str(student["tests"])
    print

# Add your function below!

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

# Averages student's data, according to designated parameter, returning student's total wgt'd avg:
def get_average(student):
    homework = average(student["homework"])
    print student["name"].upper() + "'s homework avg: " + str(homework)
    print student["name"].upper() + "'s wgt'd homework avg: " + str(0.1*homework)
    print
       
    quizzes = average(student["quizzes"])
    print student["name"].upper() + "'s quizzes avg: " + str(quizzes)
    print student["name"].upper() + "'s wgt'd quizzes avg: " + str(0.3*quizzes)
    print
        
    tests = average(student["tests"])
    print student["name"].upper() + "'s tests avg: " + str(tests)
    print student["name"].upper() + "'s wgt'd tests avg: " + str(0.6*tests)
    print
        
    return (0.1*homework) + (0.3*quizzes) + (0.6*tests)

# Returns appropriate letter grade:
def get_letter_grade(score):
    if score >= 90.0:
        return "A"
    elif score >= 80.0:
        return "B"
    elif score >= 70.0:
        return "C"
    elif score >= 60.0:
        return "D"
    else:
        return "F"

# Prints each student's calculated stats:
for student in students:
    print student["name"].upper() + "'s Weighted Average: " + str(get_average(student))
    print student["name"].upper() + "'s Letter Grade: " + get_letter_grade(get_average(student))
    print

# Prints results, returning class avg:
def get_class_average(students):
    results = []
    for student in students:
        #print student["name"].upper() + "'s Weighted Average: " + str(get_average(student))
        #print results.append(get_average(student))
        results.append(get_average(student))
    print results
    return average(results)

print get_class_average(student)

Help?


#2

@mxcode,
You will have to use a list as an argument
like
print get_class_average([alice])
instead of you using the variable student
which represents a dictionary

print student

gives an output

 {'quizzes': [0.0, 75.0, 78.0], 'tests': [100.0, 100.0], 'name': 'Tyler', 'homework': [0.0, 87.0, 75.0, 22.0]}

#3

Sorry, I don't follow. Using your example, alice: Isn't alice a dictionary, not a list? So how is that any different from passing the variable student, which, as you mentioned, represents a dictionary as well? Also, why would there need to be square brackets around alice in the

print get_class_average([alice])

statement?

Moreover, how would using just one particular student's name lead to the average of the entire class in the get_class_average function?

Having said all that, I tried what you suggested, and it worked -- so thank you for that. I'm just having trouble understanding why it works.


#5

this is the cody your code is very unclear and bad written no offence. it should look like this as the coding explain itself and isent open for errors to occur.

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(numbers):
    total = sum(numbers) 
    total = float(total) / len(numbers)
    return total
    
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"


students = [lloyd, alice, tyler]

def get_class_average(students):
    results = []
    for item in students:
        results.append(get_average(item))
    return average(results)
    
print get_class_average(students)
print get_letter_grade(get_class_average(students))

#6

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.