Intermediate · Projects: put it all together · topic 32 of 50 · 30 min
Project: marks and grade calculator
Explanation
Plan before you code
A project is just a bigger problem. The trick is to plan first. Write down three things: the inputs (what data comes in), the outputs (what answers must come out) and the steps in between. Each step usually becomes one small function.
| Part | For our report card |
|---|---|
| Inputs | Each student: a name and marks in 5 subjects, each out of 100 |
| Outputs | Total, percentage, grade, PASS or FAIL, class topper, class average |
| Steps | check marks, add them, find percentage, find grade, check pass, repeat for the class |
Our grading scheme
Every school board publishes its own rules. For this project we use one simple scheme and write it down clearly, so the program and the people agree.
| Percentage | Grade |
|---|---|
| 90 and above | A |
| 75 to below 90 | B |
| 60 to below 75 | C |
| 33 to below 60 | D |
| below 33 | F |
Step 1: check, total and percentage
We keep one student's marks in a dictionary: subject name to mark. The first function checks that every mark is between 0 and 100, because a typing mistake like 870 would spoil every answer after it.
def check_marks(marks):
for subject, mark in marks.items():
if not 0 <= mark <= 100:
raise ValueError(f"{subject}: mark {mark} must be between 0 and 100")
def total(marks):
check_marks(marks)
return sum(marks.values())
def percentage(marks):
max_total = len(marks) * 100
return round(total(marks) / max_total * 100, 2)
marks = {"English": 78, "Hindi": 85, "Maths": 92, "Science": 88, "Social Science": 81}
print(total(marks)) # 424
print(percentage(marks)) # 84.8Step 2: grade and pass
def grade(percent):
if percent >= 90:
return "A"
elif percent >= 75:
return "B"
elif percent >= 60:
return "C"
elif percent >= 33:
return "D"
return "F"
def has_passed(marks):
return all(mark >= 33 for mark in marks.values())
print(grade(84.8)) # B
print(has_passed({"Maths": 95, "Hindi": 20})) # FalseStep 3: the whole class
Now we join the pieces. report() builds one student's result as a dictionary. class_topper() uses max() with a key, and class_average() uses statistics.mean(). Here is the complete program in one place.
import statistics
def total(marks):
return sum(marks.values())
def percentage(marks):
return round(total(marks) / (len(marks) * 100) * 100, 2)
def grade(percent):
for limit, letter in [(90, "A"), (75, "B"), (60, "C"), (33, "D")]:
if percent >= limit:
return letter
return "F"
def has_passed(marks):
return all(mark >= 33 for mark in marks.values())
def report(student):
marks = student["marks"]
passed = has_passed(marks)
pct = percentage(marks)
return {
"name": student["name"],
"total": total(marks),
"percentage": pct,
"grade": grade(pct) if passed else "F",
"result": "PASS" if passed else "FAIL",
}
def class_topper(students):
best = max(students, key=lambda s: total(s["marks"]))
return best["name"]
def class_average(students):
return round(statistics.mean(percentage(s["marks"]) for s in students), 2)
students = [
{"name": "Aarav", "marks": {"Eng": 78, "Hin": 85, "Mat": 92, "Sci": 88, "SSt": 81}},
{"name": "Diya", "marks": {"Eng": 91, "Hin": 89, "Mat": 97, "Sci": 94, "SSt": 90}},
{"name": "Kabir", "marks": {"Eng": 65, "Hin": 30, "Mat": 72, "Sci": 58, "SSt": 61}},
]
for s in students:
print(report(s))
print("Topper:", class_topper(students))
print("Class average:", class_average(students))Step 4: test with answers you already know
Testing means running your functions on inputs where you already know the right answer. Work a few out by hand, then let assert compare. Pay extra attention to the edges: exactly 33, exactly 90, and just below them. Bugs love edges.
def grade(percent):
for limit, letter in [(90, "A"), (75, "B"), (60, "C"), (33, "D")]:
if percent >= limit:
return letter
return "F"
assert grade(90) == "A", "exactly 90 is an A"
assert grade(89.99) == "B", "just below 90 is a B"
assert grade(33) == "D", "exactly 33 passes with D"
assert grade(32.99) == "F", "below 33 is F"
print("All grade tests passed")Watch the lesson
Project: marks and grade calculator · 1/7
Welcome to your first project. You will build a report card calculator for a whole class, one small function at a time.
Prefer a video by a teacher? Find free videos on “python student marks grade calculator project” on YouTube ↗
In real life: A class teacher at result time
Every March a class teacher in a government school types the marks of 40 students into a spreadsheet and works out totals, percentages and grades by hand. The same few functions do it in under a second, never make an addition mistake, and can be reused next year with a new list of students.
marks = {"English": 70, "Hindi": 64, "Maths": 88, "Science": 75, "Social Science": 69}
total = sum(marks.values())
percent = total / (len(marks) * 100) * 100
passed = all(m >= 33 for m in marks.values())
print(total, round(percent, 2), "PASS" if passed else "FAIL")Practice (0/3 done)
Write percentage(marks) where marks is a dictionary of subject to mark (each out of 100). Return the percentage rounded to 2 decimal places. Example: {"Maths": 90, "Science": 75} gives 82.5.
Write grade(percent) using this scheme: 90 and above "A", 75 and above "B", 60 and above "C", 33 and above "D", otherwise "F".
Write class_topper(students). Each student is a dictionary like {"name": "Diya", "marks": {"Maths": 97, "Science": 94}}. Return the NAME of the student with the highest total. If two students tie, return the one who comes first in the list.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.