0

I recently started learning Python and am busy going through the Codecademy tutorial for it. I just completed the tutorial where you create a program that determines averages of marks from dictionaries. Heres the current 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]
}

class_list = [lloyd, alice, tyler]

def average(numbers):
    total = sum(numbers)
    total = float(total)
    total = total / len(numbers)
    return total
def get_average(student):
    homework = average(student["homework"])
    quizzes = average(student["quizzes"])
    tests = average(student["tests"])
    return homework * 0.1 + quizzes * 0.3 + tests * 0.6
def get_class_average(students):
    results = []
    for student in students:
        results.append(get_average(student))
    return average(results)
print get_class_average(class_list

But what I want to do as an extension is make it more user friendly by making the program ask the user to input lloyd in the first line as well as input all the values in the dictionary. Furthermore I'd like to make it so that the program generates a new dictionary every time the user inputs the name of the dictionary for example the lloyd on the first line. Then fill in class_list with all of the dictionaries. Lastly I want to make it so the user can also input the weightings of the marks in the line:

return homework * 0.1 + quizzes * 0.3 + tests * 0.6

I'm having trouble doing this so any help would be much appreciated.

PuppetCode
  • 41
  • 1
  • 2
  • 10
  • 1
    This doesn't look like it necessarily has anything to do with dictionaries. It looks to me like your question is, "How do I take user input in Python?" – Two-Bit Alchemist Nov 06 '15 at 20:44
  • Possible duplicate of [python: getting user input](http://stackoverflow.com/questions/3345202/python-getting-user-input) – Two-Bit Alchemist Nov 06 '15 at 20:45
  • Refer : http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/io.html –  Nov 06 '15 at 20:45
  • I've tried using input() and raw_input() but it just returns errors – PuppetCode Nov 06 '15 at 20:49
  • @PuppetCode If you tried using that and got errors, why did you not copy them and ask a question about it here, instead of obfuscating that fact and asking a completely unrelated question? – Two-Bit Alchemist Nov 06 '15 at 20:55
  • Sorry but I doubt the way I was using them was correct in any sense so I thought it would be even more obfuscating if I had posted them. But what I was saying in the comment is that I do know of the input functions so the [python: getting user input](http://stackoverflow.com/questions/3345202/python-getting-user-input) doesn't help me much. – PuppetCode Nov 06 '15 at 20:59

2 Answers2

2

You can't generate dynamic variable names, but you dont need to anyways. Just use while for the input and then add to the list

cancel = False
class_list = []

while (True):
    name = input("Give the name of the user you want to add: ")
    homework = [int(i) for i in input("Homework marks (seperated by spaces): ").split(" ")]
    quizzes = [int(i) for i in input("Quiz marks (seperated by spaces): ").split(" ")]
    tests = [int(i) for i in input("Test marks (seperated by spaces): ").split(" ")]

    class_list.append({
        "name": name,
        "homework": homework,
        "quizzes": quizzes,
        "tests": tests
    })

    cont = input("Want to add another? (Y/N)")
    if cont == "N":
        break;

print(class_list)

The [int(i) for i in...] are called "list Comprehensions. They iterate over the list of String Numbers making them INtegers ( with int() ).

weidler
  • 676
  • 1
  • 6
  • 22
  • Whenever I have to input using this code I have to put the input in "" and I get en error because the numbers that I input are strings and not integers. – PuppetCode Nov 06 '15 at 21:17
  • Then you use Python 2.x and have to use raw_input() – weidler Nov 06 '15 at 21:31
  • Thanks, switched to Python 3 but still get an error saying: Traceback (most recent call last): File "test.py3", line 36, in print(get_class_average(class_list)) File "test.py3", line 34, in get_class_average results.append(get_average(student)) File "test.py3", line 27, in get_average homework = average(student["homework"]) File "test.py3", line 22, in average total = sum(numbers) TypeError: unsupported operand type(s) for +: 'int' and 'str' – PuppetCode Nov 06 '15 at 21:38
  • Looks a bit chaotic but i guess its because the splitted inputs of the marks are strings. Ill edit a possible solution in the answer above. – weidler Nov 06 '15 at 21:44
  • Do you know anyway to input the weightings in this line: return homework * 0.1 + quizzes * 0.3 + tests * 0.6 – PuppetCode Nov 06 '15 at 21:59
  • Just add more raw_inputs() that ask for the desired weight and store them in variables. Then use those variables in the equation. All of that can be done inside of the function such that its only asked for if the function is called. – weidler Nov 06 '15 at 22:01
-2

Maybe you should create a simple class?

class Student:
    def __init__(self, name, homework, quizzes, tests):
        self.name = name
        self.homework = homework
        self.quizzes = quizzes
        self.tests = tests

and use function like this for input:

def input_student():
        name = input("Enter name")
        homework = [float(h) for h in input("Enter homework results separated by a space:)]
        # same for quizzes and tests
        class_list.append(Student(name, homework, quizzes, tests))

If you don't want to create a class, you can do the same thing with a dictionary (assigning to d["name"] instead of name etc, where d is your dictionary object)

trolley813
  • 874
  • 9
  • 15