7. Sending a letter - sidetracking a little more


#1

def get_average(student):
    homework = average(student["homework"])
    quizzes = average(student["quizzes"])
    tests = average(student["tests"])
    y = 0.1 * homework + 0.3 * quizzes + 0.6 * tests
    return y
score = get_average(lloyd)
    
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(score)

This works as well as a train. But what if I wanted to make the variable 'score' a raw input? I tried

score = get_average(raw_input("Student Name:"))

However, I end up with this error: "TypeError: string indices must be integers." Any help (or tips)?


#2

can i see how you tried to implement this?


#3

Do you mean like this?

lloyd = {
    "name": "Lloyd",
    "homework": [90.0, 97.0, 75.0, 92.0],
    "quizzes": [88.0, 40.0, 94.0],
    "tests": [75.0, 90.0]
}
def get_average(student):
    homework = average(student["homework"])
    quizzes = average(student["quizzes"])
    tests = average(student["tests"])
    y = 0.1 * homework + 0.3 * quizzes + 0.6 * tests
    return y
score = get_average(raw_input("Student Name:"))
 
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(score)

#4

yes, like this. The problem is that raw_input will give us a string. while here:

score = get_average(lloyd)

lloyd is a dictionary. So we need to get from string to dictionary. How do you think this can be done?


#5

Okay. So I've tried forcing it into a dictionary as following (assuming dict() is the way to force a dictionary the same way you'd force a str() or int()):

score = get_average(dict(raw_input("Student name:")))

and

score = get_average(raw_input(dict("Student name:")))

and even
z = get_average(raw_input("Student name:"))
score = dict(z)

But no luck...


#6

you can't just cast to a dictionary

You need to match the name value of the dictionary to the input to get the dictionary


#7

I've been trying a few other things, but can't get it to work. Is the way to solve something I should've come across during the course yet? I can't seem to figure this out...


#8

do you have the students list you build in 3 put it together?

here is what i did:

x = raw_input("Student Name:").lower()
for student in students:
   if student["name"].lower() == x:
       print(get_average(student)

We can add a handle in case something invalid is entered:

x = raw_input("Student Name:").lower()
for student in students:
   if student["name"].lower() == x:
       print get_average(student)
       break
else:
    print "This student doesn't exist"

i don't know what is covered at this point, i guess only the for else not


#9

I appreciate the help so far, but i can't get your code to work. Is there no easy way to make my raw_input access the dictionary instead of treating it like a string?


#10

so here is the 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]
}
students = [tyler, lloyd, alice]
def average (numbers):
    total = sum(numbers)
    total = float(total)
    total /= len(numbers)
    return total
    
def get_average(student):
    homework = average(student["homework"])
    quizzes = average(student["quizzes"])
    tests = average(student["tests"])
    y = 0.1 * homework + 0.3 * quizzes + 0.6 * tests
    return y
x = raw_input("Student Name:").lower()
for student in students:
   if student["name"].lower() == x:
       print get_average(student)
       break
else:
    print "This student doesn't exist"
 
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(score)

i don't see why its not working? Okay, you might need to define score, but i am sure you can figure that out

no, there is not. There are things you can do, but do you want to get outside the scope of the exercise?


#11

I just got it to work by retyping everything, so I did something wrong along the way. Thank you very much and I do believe I understand the principle of what you did. If it's not too much to ask for I would indeed like to get outside of the scope of the exercise. The more knowledge the better :smiley:

EDIT: found out what went wrong. I had previously deleted the 'name' key from all the dictionaries in trying to find a solution.


#12

as you noticed its quit difficult to do the conversion from string to dictionary, guess how we can solve this? Using a dictionary:

class_dict = {"lloyd": lloyd, "tyler": tyler, "alice": alice}
x = raw_input("enter student: ").lower()
y = class_dict.get(x):
if y:
    print get_average(y)
else:
   print "Not a valid student"

#13

I was on the right track! In one of my efforts I tried something slightly similar by creating a new dictionary but couldn't get the follow up steps. Thanks a bunch! You're a genius :smiley:


#14

getting the follow up steps is difficult. Does everything i do make sense? i cleverly used the built in .get() function. That is a bit mean


#15

yes thank you, I looked up what it does :wink:


#17

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