Student marksheet and grades
This project turns a set of subject marks into a printed report with a total, a percentage and a grade. It brings together dictionaries, functions, loops and f-string formatting. It is also the kind of small tool people really use.
The data
One student's marks fit naturally in a dictionary: the subject is the key and the marks are the value.
marks = {"English": 78, "Hindi": 84, "Maths": 91, "Science": 69, "Social Science": 73}
print(len(marks), "subjects")
print(sum(marks.values()), "marks in all")Output
5 subjects
395 marks in allSmall functions first
Write one function for each thing to be worked out. Each takes what it needs and returns the answer. Test each as you write it.
def percentage(marks, max_per_subject=100):
return sum(marks.values()) / (len(marks) * max_per_subject) * 100
def grade(percent):
if percent >= 90:
return "A+"
if percent >= 75:
return "A"
if percent >= 60:
return "B"
if percent >= 45:
return "C"
if percent >= 33:
return "D"
return "E"
marks = {"English": 78, "Hindi": 84, "Maths": 91, "Science": 69, "Social Science": 73}
p = percentage(marks)
print(round(p, 1), grade(p))Output
79.0 AThe grade bands here are our own example. Every board and school has its own, so change the numbers to match yours.
Pass or fail
A common rule is that a student must pass every subject, not just reach the overall percentage. all checks a condition for every value.
def has_passed(marks, pass_mark=33):
return all(m >= pass_mark for m in marks.values())
print(has_passed({"English": 78, "Maths": 91}))
print(has_passed({"English": 78, "Maths": 21}))Output
True
FalseThe report
Now a function that prints the whole sheet. The widths in the f-strings line the columns up.
def percentage(marks, max_per_subject=100):
return sum(marks.values()) / (len(marks) * max_per_subject) * 100
def grade(percent):
for limit, letter in [(90, "A+"), (75, "A"), (60, "B"), (45, "C"), (33, "D")]:
if percent >= limit:
return letter
return "E"
def has_passed(marks, pass_mark=33):
return all(m >= pass_mark for m in marks.values())
def print_report(name, marks):
line = "-" * 28
print(f"Marksheet: {name}")
print(line)
for subject, m in marks.items():
print(f"{subject:<18}{m:>6}")
print(line)
total = sum(marks.values())
p = percentage(marks)
print(f"{'Total':<18}{total:>6}")
print(f"{'Percentage':<18}{p:>6.1f}")
print(f"{'Grade':<18}{grade(p):>6}")
print(f"{'Result':<18}{'PASS' if has_passed(marks) else 'FAIL':>6}")
print_report("Asha Verma", {"English": 78, "Hindi": 84, "Maths": 91, "Science": 69, "Social Science": 73})Output
Marksheet: Asha Verma
----------------------------
English 78
Hindi 84
Maths 91
Science 69
Social Science 73
----------------------------
Total 395
Percentage 79.0
Grade A
Result PASSLook at the new version of grade. The chain of if statements has become a list of pairs and a loop. When the bands change, you edit one line of data and no logic.
A whole class
For many students, use a dictionary of dictionaries and loop over it. Sorting by percentage gives a rank list.
def percentage(marks):
return sum(marks.values()) / (len(marks) * 100) * 100
school = {
"Asha": {"English": 78, "Maths": 91, "Science": 69},
"Ravi": {"English": 65, "Maths": 58, "Science": 72},
"Meena": {"English": 88, "Maths": 95, "Science": 90},
}
ranked = sorted(school, key=lambda name: percentage(school[name]), reverse=True)
for rank, name in enumerate(ranked, 1):
print(f"{rank}. {name:<8}{percentage(school[name]):.1f}%")
best_maths = max(school, key=lambda name: school[name]["Maths"])
print("Top in Maths:", best_maths)Output
1. Meena 91.0%
2. Asha 79.3%
3. Ravi 65.0%
Top in Maths: MeenaIdeas to extend it
- Ask for the marks with
input, checking that each is a number from 0 to 100 (lesson 19). - Read the class from a CSV file and write the rank list to another file (lesson 18).
- Print the subject in which each student scored lowest, as a hint for where to work.
- Turn
Studentinto a class withpercentageandgrademethods (lesson 21).
Exercise 1. Write a function weakest_subject(marks) that returns the name of the subject with the lowest marks. Test it with three subjects.
Show one answer
def weakest_subject(marks):
return min(marks, key=marks.get)
print(weakest_subject({"English": 78, "Maths": 91, "Science": 69}))Output
ScienceExamples on this page were run with Python 3.14 on 12 November 2026. The output shown is the real output.
This is an independent learning site. It is not connected with or approved by the Python Software Foundation. "Python" is a trademark of the Python Software Foundation and is used here only to name the language.