A grade analysis tool that calculates class averages, assigns letter grades, identifies top and struggling students, and plots a distribution histogram.
Generate sample student data with marks in five subjects.
import pandas as pd
import numpy as np
np.random.seed(42)
n = 35
df = pd.DataFrame({
'Name': [f'Student_{i:02d}' for i in range(1, n+1)],
'Maths': np.random.randint(35, 100, n),
'English': np.random.randint(40, 100, n),
'Science': np.random.randint(30, 100, n),
'History': np.random.randint(45, 100, n),
'Python': np.random.randint(50, 100, n),
})
df.to_csv('gradebook.csv', index=False)
print(df.head())
A single line of pandas computes each student's average across all subjects.
df = pd.read_csv('gradebook.csv')
subjects = ['Maths','English','Science','History','Python']
df['Total'] = df[subjects].sum(axis=1)
df['Average'] = df[subjects].mean(axis=1).round(1)
df['Rank'] = df['Average'].rank(ascending=False).astype(int)
def letter_grade(avg):
if avg >= 90: return 'A+'
if avg >= 80: return 'A'
if avg >= 70: return 'B'
if avg >= 60: return 'C'
if avg >= 50: return 'D'
return 'F'
df['Grade'] = df['Average'].apply(letter_grade)
print(df[['Name','Average','Grade','Rank']].sort_values('Rank').head(10))
Summary statistics and a histogram reveal the shape of the class performance.
import matplotlib.pyplot as plt
print("\n=== Class Statistics ===")
print(f"Class Average: {df['Average'].mean():.1f}")
print(f"Highest Score: {df['Average'].max():.1f} — {df.loc[df['Average'].idxmax(), 'Name']}")
print(f"Lowest Score: {df['Average'].min():.1f} — {df.loc[df['Average'].idxmin(), 'Name']}")
print(f"\nGrade Distribution:")
print(df['Grade'].value_counts().sort_index())
# Histogram
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
df['Average'].plot(kind='hist', bins=10, ax=axes[0], color='#3b82f6', edgecolor='white')
axes[0].set_title('Score Distribution')
axes[0].set_xlabel('Average Score')
axes[0].axvline(df['Average'].mean(), color='#ef4444', linestyle='--', label='Mean')
axes[0].legend()
df[subjects].mean().plot(kind='bar', ax=axes[1], color='#22c55e', edgecolor='white')
axes[1].set_title('Average Score per Subject')
axes[1].set_xlabel('Subject')
axes[1].set_ylabel('Average')
plt.xticks(rotation=30)
plt.tight_layout()
plt.savefig('grade_analysis.png', dpi=120)
plt.show()
Identify who needs extra help and who deserves recognition.
print("\n=== Top 5 Students ===")
print(df.nlargest(5, 'Average')[['Name','Average','Grade']].to_string(index=False))
print("\n=== Students Needing Support (below 50%) ===")
struggling = df[df['Average'] < 50]
if struggling.empty:
print("None — great class!")
else:
print(struggling[['Name','Average'] + subjects].to_string(index=False))
# Save a formatted report
df.sort_values('Rank').to_csv('grade_report.csv', index=False)
print("\nFull report saved to grade_report.csv")
A 60-line script that replaces hours of manual spreadsheet work every semester. The same pattern — load, compute, filter, visualise — is the backbone of every business intelligence dashboard.
Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.