Grade calculator
Many classes weight their marks: homework might count for a quarter of the grade and the final exam for more. You'll average each category, weight it, add it all up and turn the result into a letter grade.
Skills you'll practise
- Dictionaries
- Functions
- Loops
- f-strings
Steps
Step 1: Average a list of marks
Finish
average(marks)so it returns the mean of a list of numbers.Show a hintHide the hint
sum(marks) / len(marks). Return 0 for an empty list so you never divide by zero.Step 2: Average every category
Loop over the
scoresdictionary and print the average for each category.Show a hintHide the hint
for category, marks in scores.items():gives you the name and the list together.Step 3: Apply the weights
Multiply each category's average by its weight from
weightsand add the results into a running total.Step 4: Check the weights
Weights should add up to 1 (that is, 100%). Print a warning if they don't.
Show a hintHide the hint
Decimals aren't always exact in Python, so compare with
abs(total - 1) > 0.001rather than!=.Step 5: Turn it into a letter
Write
letter_grade(percent)that returns A, B, C, D or F, and print the final result.Show a hintHide the hint
Check from the top down:
if percent >= 90, thenelif percent >= 80, and so on.
Starter code
It already runs. The TODO comments mark where to start.
scores = {
"homework": [92, 88, 95, 79],
"quizzes": [85, 90, 78],
"project": [94],
"final exam": [81],
}
weights = {
"homework": 0.25,
"quizzes": 0.20,
"project": 0.25,
"final exam": 0.30,
}
def average(marks):
# TODO: return the mean of the list
return 0
for category, marks in scores.items():
print(category, average(marks))
Example solution
One way to finish it. Have a go first; yours doesn't need to match.
Reveal the solutionHide the solution
scores = {
"homework": [92, 88, 95, 79],
"quizzes": [85, 90, 78],
"project": [94],
"final exam": [81],
}
weights = {
"homework": 0.25,
"quizzes": 0.20,
"project": 0.25,
"final exam": 0.30,
}
def average(marks):
if not marks:
return 0
return sum(marks) / len(marks)
def letter_grade(percent):
if percent >= 90:
return "A"
elif percent >= 80:
return "B"
elif percent >= 70:
return "C"
elif percent >= 60:
return "D"
return "F"
total_weight = sum(weights.values())
if abs(total_weight - 1) > 0.001:
print(f"Warning: the weights add up to {total_weight:.0%}, not 100%.")
final = 0
for category, marks in scores.items():
avg = average(marks)
weight = weights[category]
final += avg * weight
print(f"{category:<12} average {avg:5.1f} counts for {weight:.0%}")
print()
print(f"Final grade: {final:.1f}% ({letter_grade(final)})")
Stretch goal
Work backwards: write a function that tells you the lowest final-exam mark you'd need to finish with an A.