Student Report Card System – Class 12 CS Project in Python
CBSE Class 12 Computer Science Investigatory Project
Topics Covered: File Handling, CSV Module, Functions,Β Lists, Dictionaries, String Formatting
# ============================================================
# STUDENT REPORT CARD SYSTEM
# CBSE Class 12 Computer Science Investigatory Project
# Topics Covered: File Handling, CSV Module, Functions,
# Lists, Dictionaries, String Formatting
# ============================================================
#
# REQUIREMENTS:
# - Python 3.x (no extra pip install needed)
# - Modules used: csv, os, datetime (all built-in)
#
# HOW TO RUN:
# python student_report_card.py
#
# FILE CREATED:
# students.csv β stores all student records
# ============================================================
import csv
import os
from datetime import datetime
# βββββββββββββββββββββββββββββββββββββββββββββ
# CONSTANTS
# βββββββββββββββββββββββββββββββββββββββββββββ
CSV_FILE = "students.csv"
SUBJECTS = ["English", "Mathematics", "Science", "Social_Science", "Computer_Science"]
FIELDNAMES = ["Roll_No", "Name", "Class", "Section",
"English", "Mathematics", "Science",
"Social_Science", "Computer_Science",
"Total", "Percentage", "Grade", "Result", "Date"]
# Grade boundaries
def get_grade(percentage):
if percentage >= 91:
return "A1"
elif percentage >= 81:
return "A2"
elif percentage >= 71:
return "B1"
elif percentage >= 61:
return "B2"
elif percentage >= 51:
return "C1"
elif percentage >= 41:
return "C2"
elif percentage >= 33:
return "D"
else:
return "E (Fail)"
def get_result(marks_list):
"""Pass only if all subjects >= 33"""
for m in marks_list:
if m < 33:
return "FAIL"
return "PASS"
# βββββββββββββββββββββββββββββββββββββββββββββ
# FILE HANDLING β CSV OPERATIONS
# βββββββββββββββββββββββββββββββββββββββββββββ
def initialize_file():
"""Create CSV file with header if it doesn't exist."""
if not os.path.exists(CSV_FILE):
with open(CSV_FILE, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
writer.writeheader()
print(f"\n [INFO] New data file '{CSV_FILE}' created.")
def read_all_students():
"""Read all student records from CSV. Returns list of dicts."""
records = []
with open(CSV_FILE, "r", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
records.append(row)
return records
def write_all_students(records):
"""Overwrite CSV with given list of dicts."""
with open(CSV_FILE, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
writer.writeheader()
writer.writerows(records)
def append_student(record):
"""Append a single student record to CSV."""
with open(CSV_FILE, "a", newline="") as f:
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
writer.writerow(record)
def roll_exists(roll_no):
"""Check if a Roll Number already exists."""
records = read_all_students()
for r in records:
if r["Roll_No"] == str(roll_no):
return True
return False
# βββββββββββββββββββββββββββββββββββββββββββββ
# DISPLAY HELPERS
# βββββββββββββββββββββββββββββββββββββββββββββ
LINE = "=" * 72
def print_header(title):
print("\n" + LINE)
print(f" {title.upper()}")
print(LINE)
def print_report_card(r):
"""Print a formatted report card for one student."""
print("\n" + "+" + "-" * 60 + "+")
print("|{:^60}|".format("STUDENT REPORT CARD"))
print("|{:^60}|".format("CBSE Class 12 β Academic Year 2025-26"))
print("+" + "-" * 60 + "+")
print(f" Roll No : {r['Roll_No']}")
print(f" Name : {r['Name']}")
print(f" Class : {r['Class']} | Section : {r['Section']}")
print(f" Date : {r['Date']}")
print("+" + "-" * 60 + "+")
print(f" {'SUBJECT':<25} {'MARKS (out of 100)':>20}")
print(" " + "-" * 45)
for sub in SUBJECTS:
label = sub.replace("_", " ")
print(f" {label:<25} {r[sub]:>20}")
print(" " + "-" * 45)
print(f" {'TOTAL':<25} {r['Total']:>20}")
print(f" {'PERCENTAGE':<25} {r['Percentage']:>19}%")
print(f" {'GRADE':<25} {r['Grade']:>20}")
print(f" {'RESULT':<25} {r['Result']:>20}")
print("+" + "-" * 60 + "+\n")
def print_table(records):
"""Print all students as a compact table."""
if not records:
print("\n [!] No records found.\n")
return
print("\n" + LINE)
header = f" {'Roll':<6} {'Name':<20} {'Class':<6} {'Sec':<4} {'Total':<7} {'%':<7} {'Grade':<6} {'Result'}"
print(header)
print(" " + "-" * 68)
for r in records:
row = (f" {r['Roll_No']:<6} {r['Name']:<20} {r['Class']:<6} "
f"{r['Section']:<4} {r['Total']:<7} {r['Percentage']:<7} "
f"{r['Grade']:<6} {r['Result']}")
print(row)
print(LINE)
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 1 β ADD STUDENT
# βββββββββββββββββββββββββββββββββββββββββββββ
def add_student():
print_header("Add New Student")
# ββ Roll Number ββ
while True:
roll = input(" Enter Roll Number : ").strip()
if not roll.isdigit():
print(" [!] Roll number must be numeric. Try again.")
continue
if roll_exists(roll):
print(f" [!] Roll No {roll} already exists. Use Update option.")
return
break
name = input(" Enter Student Name : ").strip().title()
if not name:
print(" [!] Name cannot be empty.")
return
cls = input(" Enter Class (e.g. 12) : ").strip()
section = input(" Enter Section (e.g. A) : ").strip().upper()
# ββ Marks Input ββ
print("\n Enter marks for each subject (0 β 100):\n")
marks = {}
for sub in SUBJECTS:
while True:
try:
m = int(input(f" {sub.replace('_', ' '):<22}: "))
if 0 <= m <= 100:
marks[sub] = m
break
else:
print(" [!] Marks must be between 0 and 100.")
except ValueError:
print(" [!] Please enter a valid integer.")
# ββ Calculations ββ
marks_list = list(marks.values())
total = sum(marks_list)
percentage = round(total / len(SUBJECTS), 2)
grade = get_grade(percentage)
result = get_result(marks_list)
date = datetime.today().strftime("%d-%m-%Y")
record = {
"Roll_No" : roll,
"Name" : name,
"Class" : cls,
"Section" : section,
"English" : marks["English"],
"Mathematics" : marks["Mathematics"],
"Science" : marks["Science"],
"Social_Science" : marks["Social_Science"],
"Computer_Science": marks["Computer_Science"],
"Total" : total,
"Percentage" : percentage,
"Grade" : grade,
"Result" : result,
"Date" : date,
}
append_student(record)
print(f"\n β Student '{name}' (Roll No: {roll}) added successfully!")
print_report_card(record)
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 2 β VIEW REPORT CARD (by Roll No)
# βββββββββββββββββββββββββββββββββββββββββββββ
def view_report_card():
print_header("View Student Report Card")
roll = input(" Enter Roll Number to search : ").strip()
records = read_all_students()
for r in records:
if r["Roll_No"] == roll:
print_report_card(r)
return
print(f"\n [!] No student found with Roll No: {roll}\n")
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 3 β DISPLAY ALL STUDENTS
# βββββββββββββββββββββββββββββββββββββββββββββ
def display_all():
print_header("All Student Records")
records = read_all_students()
if not records:
print("\n [!] No records in the database yet.\n")
return
print(f"\n Total Students: {len(records)}")
print_table(records)
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 4 β UPDATE MARKS
# βββββββββββββββββββββββββββββββββββββββββββββ
def update_student():
print_header("Update Student Marks")
roll = input(" Enter Roll Number to update : ").strip()
records = read_all_students()
found = False
for i, r in enumerate(records):
if r["Roll_No"] == roll:
found = True
print(f"\n Found: {r['Name']} | Class {r['Class']}-{r['Section']}")
print("\n Re-enter marks for each subject (press Enter to keep old value):\n")
for sub in SUBJECTS:
while True:
old = r[sub]
val = input(f" {sub.replace('_',' '):<22} [current: {old}]: ").strip()
if val == "":
break # keep old
if val.isdigit() and 0 <= int(val) <= 100:
r[sub] = val
break
else:
print(" [!] Enter a number between 0 and 100.")
# Recalculate
marks_list = [int(r[s]) for s in SUBJECTS]
r["Total"] = sum(marks_list)
r["Percentage"] = round(r["Total"] / len(SUBJECTS), 2)
r["Grade"] = get_grade(r["Percentage"])
r["Result"] = get_result(marks_list)
r["Date"] = datetime.today().strftime("%d-%m-%Y")
records[i] = r
write_all_students(records)
print(f"\n β Marks updated for Roll No: {roll}")
print_report_card(r)
break
if not found:
print(f"\n [!] No student found with Roll No: {roll}\n")
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 5 β DELETE STUDENT
# βββββββββββββββββββββββββββββββββββββββββββββ
def delete_student():
print_header("Delete Student Record")
roll = input(" Enter Roll Number to delete : ").strip()
records = read_all_students()
new_records = [r for r in records if r["Roll_No"] != roll]
if len(new_records) == len(records):
print(f"\n [!] No student found with Roll No: {roll}\n")
return
confirm = input(f" Are you sure you want to delete Roll No {roll}? (yes/no): ").strip().lower()
if confirm == "yes":
write_all_students(new_records)
print(f"\n β Record with Roll No {roll} deleted successfully.\n")
else:
print(" [i] Deletion cancelled.\n")
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 6 β SEARCH BY NAME
# βββββββββββββββββββββββββββββββββββββββββββββ
def search_by_name():
print_header("Search Student by Name")
keyword = input(" Enter name (or part of name) to search : ").strip().lower()
records = read_all_students()
results = [r for r in records if keyword in r["Name"].lower()]
if not results:
print(f"\n [!] No student found matching '{keyword}'\n")
else:
print(f"\n Found {len(results)} record(s):\n")
print_table(results)
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 7 β CLASS TOPPER
# βββββββββββββββββββββββββββββββββββββββββββββ
def class_topper():
print_header("Class Topper")
records = read_all_students()
if not records:
print("\n [!] No records available.\n")
return
topper = max(records, key=lambda r: float(r["Percentage"]))
print(f"\n π CLASS TOPPER: {topper['Name']} (Roll No: {topper['Roll_No']})")
print(f" Percentage : {topper['Percentage']}% | Grade : {topper['Grade']}")
print_report_card(topper)
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 8 β SUBJECT-WISE STATISTICS
# βββββββββββββββββββββββββββββββββββββββββββββ
def subject_statistics():
print_header("Subject-Wise Statistics")
records = read_all_students()
if not records:
print("\n [!] No records available.\n")
return
print(f"\n {'SUBJECT':<25} {'HIGHEST':>8} {'LOWEST':>8} {'AVERAGE':>10}")
print(" " + "-" * 55)
for sub in SUBJECTS:
marks = [int(r[sub]) for r in records]
high = max(marks)
low = min(marks)
avg = round(sum(marks) / len(marks), 2)
print(f" {sub.replace('_',' '):<25} {high:>8} {low:>8} {avg:>10}")
print()
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 9 β PASS / FAIL LIST
# βββββββββββββββββββββββββββββββββββββββββββββ
def pass_fail_list():
print_header("Pass / Fail Summary")
records = read_all_students()
if not records:
print("\n [!] No records available.\n")
return
passed = [r for r in records if r["Result"] == "PASS"]
failed = [r for r in records if r["Result"] == "FAIL"]
print(f"\n Total Students : {len(records)}")
print(f" Passed : {len(passed)}")
print(f" Failed : {len(failed)}")
if failed:
print("\n --- FAILED STUDENTS ---")
print_table(failed)
else:
print("\n π All students have PASSED!\n")
# βββββββββββββββββββββββββββββββββββββββββββββ
# FEATURE 10 β GRADE-WISE DISTRIBUTION
# βββββββββββββββββββββββββββββββββββββββββββββ
def grade_distribution():
print_header("Grade-Wise Distribution")
records = read_all_students()
if not records:
print("\n [!] No records available.\n")
return
grade_order = ["A1", "A2", "B1", "B2", "C1", "C2", "D", "E (Fail)"]
dist = {g: 0 for g in grade_order}
for r in records:
g = r["Grade"]
if g in dist:
dist[g] += 1
print(f"\n {'GRADE':<12} {'COUNT':>6} BAR")
print(" " + "-" * 40)
for g in grade_order:
bar = "β" * dist[g]
print(f" {g:<12} {dist[g]:>6} {bar}")
print()
# βββββββββββββββββββββββββββββββββββββββββββββ
# MAIN MENU
# βββββββββββββββββββββββββββββββββββββββββββββ
def main_menu():
initialize_file()
while True:
print("\n" + LINE)
print(" STUDENT REPORT CARD SYSTEM β CBSE CLASS 12")
print(LINE)
print(" 1. Add New Student")
print(" 2. View Report Card (by Roll No)")
print(" 3. Display All Students")
print(" 4. Update Student Marks")
print(" 5. Delete Student Record")
print(" 6. Search Student by Name")
print(" 7. Class Topper")
print(" 8. Subject-Wise Statistics")
print(" 9. Pass / Fail Summary")
print(" 10. Grade-Wise Distribution")
print(" 0. Exit")
print(LINE)
choice = input(" Enter your choice: ").strip()
if choice == "1": add_student()
elif choice == "2": view_report_card()
elif choice == "3": display_all()
elif choice == "4": update_student()
elif choice == "5": delete_student()
elif choice == "6": search_by_name()
elif choice == "7": class_topper()
elif choice == "8": subject_statistics()
elif choice == "9": pass_fail_list()
elif choice == "10": grade_distribution()
elif choice == "0":
print("\n Thank you for using Student Report Card System. Goodbye!\n")
break
else:
print("\n [!] Invalid choice. Please enter a number from 0 to 10.\n")
# βββββββββββββββββββββββββββββββββββββββββββββ
# ENTRY POINT
# βββββββββββββββββββββββββββββββββββββββββββββ
if __name__ == "__main__":
main_menu()
