I’m new in python and I’m using MOOC course to learn (and Udemy). I come across this exercise and I’m stuck with this:
Students database exercise – Part 3
I wrote this code (unfinished!), but im having problems with the add_course function. I am not able to ignore adding courses with lower grade. I tried for loops too.
Can anyone help me here? Thanks a lot!
# Write your solution here
def add_student(database: dict, name: str):
courses = []
database[name] = courses
def add_course(database: dict, name: str, course: tuple):
courses = database[name]
if course[1] == 0:
pass
elif course[0] in courses:
pass
else:
courses.append(course)
def print_student(database: dict, name: str):
if name not in database:
print(f"{name}: no such person in the database")
else:
if len(database[name]) == 0:
print(f"{name}:")
print(" no completed courses")
else:
completed_courses = len(database[name])
sum_grades = 0
print(f"{name}:")
print(f" {completed_courses} completed courses:")
for courses in database[name]:
sum_grades += courses[1]
avg_grade = sum_grades / len(database[name])
print(f" {courses[0]} {courses[1]}")
print(f" average grade {avg_grade}")
#def summary(database: dict):
# pass
if __name__ == "__main__":
students = {}
add_student(students, "Peter")
add_course(students, "Peter", ("Introduction to Programming", 3))
add_course(students, "Peter", ("Advanced Course in Programming", 2))
add_course(students, "Peter", ("Data Structures and Algorithms", 0))
add_course(students, "Peter", ("Introduction to Programming", 2))
print_student(students, "Peter")
Tried: For loops, appending to another list first.
Expected: If the course is already in the database in that specific student’s information, the grade recorded in the database should never be lowered if the course is repeated.
Resulted now: I’m getting duplicates.
0
I’m getting duplicates.
This is happening because in your add_course
function, you are checking:
elif course[0] in courses:
But this comparison will always be False
; you are not adding course[0]
to the list; you are adding course
:
courses.append(course)
You need to update your duplicate check:
elif course in courses:
Working code would look like this:
def add_course(
database: dict[str, list[tuple[str, int]]], name: str, course: tuple[str, int]
):
courses = database[name]
if course[1] == 0:
pass
elif course in courses:
pass
else:
courses.append(course)
Note that I show updated type annotations here that don’t impact the operation of your code, but they will make type checkers happy (which you should be running in your development environment if you’re bothering to use type annotations at all).
This could still result in notional duplicates if you happen to call it with the same course but different grades:
add_course(students, 'Peter', ('example course', 1))
add_course(students, 'Peter', ('example course', 2))
This would result in:
>>> students
{'Peter': [('example course', 1), ('example course', 2)]}
It doesn’t look like this is a situation you need to worry about, but if it is, you could rewrite things like this instead:
def add_course(
database: dict[str, list[tuple[str, int]]], name: str, course: tuple[str, int]
):
courses = database[name]
if course[1] == 0:
pass
elif any(
entry[0] == course[0] for student in database.values() for entry in student
):
pass
else:
courses.append(course)
This uses only the course name to determine duplicates. With this change, the above example will result in:
>>> students
{'Peter': [('example course', 1)}
2
You are adding courses as tuples to list and then search for a course name (string).
elif course[0] in courses: # here you are looking for a string in list of tuples
Instead, I suggest to store courses as dict instead of list, with key being course name and value being grade.
courses = {}
(...)
course_name, course_grade = course
courses[course_name] = course_grade
Then your search for course name should work and will be more efficient when number of courses will grow
Thanks @dankal444
I just did it and works! That’s how it looks right now.
def add_student(database: dict, name: str):
if name in database:
print("This student exists already")
database[name] = {}
def add_course(database: dict, name: str, course: tuple):
if course[1] == 0:
return
if course[0] not in database[name]:
students[name][course[0]] = course[1]
return
if course[1] > database[name][course[0]]:
database[name][course[0]] = course[1]
return
It seems like all the kode works now, but I cannot send the solution (I got errors). Can anyone see why? I tested it and it seems to work.
# Write your solution here
def add_student(database: dict, name: str):
if name in database:
print("This student exists already")
database[name] = {}
def add_course(database: dict, name: str, course: tuple):
if course[1] == 0:
return
if course[0] not in database[name]:
students[name][course[0]] = course[1]
return
if course[1] > database[name][course[0]]:
database[name][course[0]] = course[1]
return
def print_student(database: dict, name: str):
if name not in database:
print(f"{name}: no such person in the database")
else:
if len(database[name]) == 0:
print(f"{name}:")
print(" no completed courses")
else:
completed_courses = len(database[name])
sum_grades = 0
print(f"{name}:")
print(f" {completed_courses} completed courses:")
for courses, grades in database[name].items():
sum_grades += grades
avg_grade = sum_grades / len(database[name])
print(f" {courses} {grades}")
print(f" average grade {avg_grade}")
def summary(database: dict):
students = len(database)
courses_completed = 0
best_avg = 0
most_courses = ""
for student in database:
total_grade = 0
for course, grade in database[student].items():
total_grade += grade
avg_grade = total_grade / len(database[student])
if avg_grade > best_avg:
best_avg = avg_grade
if len(database[student]) > courses_completed:
courses_completed = len(database[student])
most_courses = student
print(f"students {students}")
print(f"most courses completed {courses_completed} {most_courses}")
print(f"best average grade {student} {best_avg}")
if __name__ == "__main__":
students = {}
add_student()
add_course()
print_student()
summary()
4