Adding multiple items to dictionary

Question:

def AddStudent():

    #Variable to control the loop
    again = 'y'

    #While loop that gets user input to be added to dictionary
    while again.lower() == 'y':
        student_key = input("What's the name of the student? ")

        #Ask user for number of grades
        n = int(input('How many grades do you wish to input? '))

        #Empty list where grades will be saved
        grades = []

        #for loop to add as many grades as user wishes
        for i in range(0 ,n):
            grade = int(input(f'Grade {i + 1}: '))
            grades.append(grade)
        
        #Call StudentGradeBook and send values as parameters
        StudentGradeBook(student_key, grades)
        

        
        again = input('Do you wish to add another student? (y) ')
    
    

def StudentGradeBook(name, grade_value):
    #Dictionary of the grades
    grade_book = {'Tom':[90,85,82], 'Bob':[92,79,85]}

    #Add the key and value to the dict
    grade_book[name] = grade_value

    print(grade_book)

When I add more than one name and grade list to the dict, it just replaces the third one instead of adding a 4th, 5th, etc.

This is the output:

What's the name of the student? Bill
How many grades do you wish to input? 3
Grade 1: 88
Grade 2: 88
Grade 3: 88
{'Tom': [90, 85, 82], 'Bob': [92, 79, 85], 'Bill': [88, 88, 88]}
Do you wish to add another student? (y) y
What's the name of the student? Thomas
How many grades do you wish to input? 3
Grade 1: 87
Grade 2: 88
Grade 3: 88
{'Tom': [90, 85, 82], 'Bob': [92, 79, 85], 'Thomas': [87, 88, 88]}
Do you wish to add another student? (y) n

Answers:

Every time you call StudentGradeBook you are redefining grade_book from scratch as

grade_book = {'Tom':[90,85,82], 'Bob':[92,79,85]}

Just move it outside of both function body and it will work.

def AddStudent():
    ...

#Dictionary of the grades
grade_book = {'Tom':[90,85,82], 'Bob':[92,79,85]}

def StudentGradeBook(name, grade_value):
    #Add the key and value to the dict
    grade_book[name] = grade_value
    print(grade_book)
Answered By: chc

Your StudentGradebook function is always beginning with:

grade_book = {'Tom':[90,85,82], 'Bob':[92,79,85]}

and since it neither returns the resulting modified dict nor stores it elsewhere, it’s always restarting from scratch. If you want to preserve a single student gradebook across calls, I’d recommend making it a class, and reusing an instance of said class to add new student info to, e.g. defining it like so:

class StudentGradeBook:
    def __init__(self):
       # Initial dictionary on creation
       self.grade_book = {'Tom':[90,85,82], 'Bob':[92,79,85]}

    def add_grades(self, name, grades):
       # Update with additional data
       self.grade_book[name] = list(grades)  # Shallow copy to avoid being tied to caller list

       # Optionally, if new grades for an existing student should be allowed,
       # replace the line above with:
       self.grade_book.setdefault(name, []).extend(grades)
       # which will concatenate on new grades for the name rather than replacing all grades

and using it like so:

def AddStudent(gradebook=None):  # Allow passing in an existing gradebook
    if gradebook is None:
        gradebook = StudentGradebook()  # Make a new one if it one wasn't provided

    #Variable to control the loop
    again = 'y'

    #While loop that gets user input to be added to dictionary
    while again.lower() == 'y':
        student_key = input("What's the name of the student? ")

        #Ask user for number of grades
        n = int(input('How many grades do you wish to input? '))

        #Empty list where grades will be saved
        grades = []

        #for loop to add as many grades as user wishes
        for i in range(0 ,n):
            grade = int(input(f'Grade {i + 1}: '))
            grades.append(grade)
        
        #Call StudentGradeBook and send values as parameters
        gradebook.add_grades(student_key, grades)
        
        print(gradebook.grade_book)  # Print the state so far
        
        again = input('Do you wish to add another student? (y) ')

    return gradebook  # So caller can use it if they didn't already provide one
Answered By: ShadowRanger

I suggest that you save all the inputs in a list, then you pass the list to StudentGradeBook() :

def AddStudent():
    # Variable to control the loop
    again = 'y'
    
    # Keep track of your inputs
    inputs_list = []

    # While loop that gets user input to be added to dictionary
    while again.lower() == 'y':
        student_key = input("What's the name of the student? ")

        # Ask user for number of grades
        n = int(input('How many grades do you wish to input? '))

        # Empty list where grades will be saved
        grades = []

        # for loop to add as many grades as user wishes
        for i in range(0, n):
            grade = int(input(f'Grade {i + 1}: '))
            grades.append(grade)

        # Save the inputs before calling StudentGradeBook
        inputs_list.append([student_key, grades])

        again = input('Do you wish to add another student? (y) ')

    # Call StudentGradeBook and pass the inputs as a list
    StudentGradeBook(inputs_list)


def StudentGradeBook(grades):
    grade_book = {'Tom': [90, 85, 82], 'Bob': [92, 79, 85]}
    
    grade_book.update(grades)
    
    print(grade_book)
Answered By: Aymen

You can also pass grade_book to keyword arguments in function as default value:

def StudentGradeBook(name, grade_value, grade_book={'Tom': [90, 85, 82], 'Bob': [92, 79, 85]}):

Full code:

def AddStudent():
    again = 'y'
    while again.lower() == 'y':
        StudentGradeBook(input("What's the name of the student? "), [int(input(f'Grade {i + 1}: ')) 
        for i in range(int(input('How many grades do you wish to input? ')))])
        again = input('Do you wish to add another student? (y) ')

def StudentGradeBook(name, grade_value, grade_book={'Tom': [90, 85, 82], 'Bob': [92, 79, 85]}):
    grade_book[name] = grade_value
    print(grade_book)

Output:

What's the name of the student? Bill
How many grades do you wish to input? 3
Grade 1: 88
Grade 2: 88
Grade 3: 88
{'Tom': [90, 85, 82], 'Bob': [92, 79, 85], 'Bill': [88, 88, 88]}
Do you wish to add another student? (y) y
What's the name of the student? Thomas
How many grades do you wish to input? 3
Grade 1: 87
Grade 2: 88
Grade 3: 88
{'Tom': [90, 85, 82], 'Bob': [92, 79, 85], 'Bill': [88, 88, 88], 'Thomas': [87, 88, 88]}
Do you wish to add another student? (y) n
Answered By: Arifa Chan
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.