Skip to main content
All projects
Python project

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

  1. Step 1: Average a list of marks

    Finish average(marks) so it returns the mean of a list of numbers.

    Show a hint

    sum(marks) / len(marks). Return 0 for an empty list so you never divide by zero.

  2. Step 2: Average every category

    Loop over the scores dictionary and print the average for each category.

    Show a hint

    for category, marks in scores.items(): gives you the name and the list together.

  3. Step 3: Apply the weights

    Multiply each category's average by its weight from weights and add the results into a running total.

  4. Step 4: Check the weights

    Weights should add up to 1 (that is, 100%). Print a warning if they don't.

    Show a hint

    Decimals aren't always exact in Python, so compare with abs(total - 1) > 0.001 rather than !=.

  5. 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 hint

    Check from the top down: if percent >= 90, then elif percent >= 80, and so on.

Starter code

It already runs. The TODO comments mark where to start.

Open in playground
main.py
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 solution
main.py
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.

Chapters that help