ShareYourGroupShareYourGroupPython

Small project 2 of 4

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 all

Small 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 A

The 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
False

The 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              PASS

Look 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: Meena

Ideas to extend it

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

Science

Examples 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.