Python code for grade 9 analysis tool
Python code for grade 9 analysis tool
import numpy as np
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.styles.differential import DifferentialStyle
from openpyxl.formatting.rule import Rule, FormulaRule
from openpyxl.chart import BarChart, PieChart, Reference
from openpyxl.chart.label import DataLabelList
from openpyxl.worksheet.datavalidation import DataValidation
from openpyxl.utils import get_column_letter
from openpyxl.drawing.image import Image
import datetime
import os
def create_class_assessment_tool(filename='Class_Assessment_Tool.xlsx',
num_students=30):
"""
Create an Excel workbook for class assessment analysis with three sheets:
1. Mark Schedule
2. Summary Analysis
3. Dashboard
Args:
filename (str): Output Excel filename
num_students (int): Number of sample student rows to include
"""
# Create a new workbook
wb = openpyxl.Workbook()
# Add instructions
add_instructions(wb)
# Grade formula
ws[f'H{row}'] =
f'=IF(G{row}="","",IF(ISNA(G{row}),"X",IF(G{row}>=75,"ONE",IF(G{row}>=60,"TWO",IF(G
{row}>=50,"THREE",IF(G{row}>=40,"FOUR",IF(G{row}>=0,"F","X")))))))'
# Standard formula
ws[f'I{row}'] =
f'=IF(H{row}="","",IF(H{row}="X","ABSENT",IF(H{row}="F","FAIL",IF(H{row}="FOUR","PA
SS",IF(H{row}="THREE","CREDIT",IF(H{row}="TWO","MERIT","DISTINCTION"))))))'
# Serial number
ws.cell(row=row, column=1, value=i+1)
# Sex (M/F)
ws.cell(row=row, column=3, value=genders[i])
# F (FAIL): Red
ws.conditional_formatting.add(f'H2:H{num_students+1}',
FormulaRule(formula=['$H2="F"'], fill=red_fill))
# X (ABSENT): Gray
ws.conditional_formatting.add(f'H2:H{num_students+1}',
FormulaRule(formula=['$H2="X"'], fill=gray_fill))
# PASS: Green
ws.conditional_formatting.add(f'I2:I{num_students+1}',
FormulaRule(formula=['$I2="PASS"'],
fill=green_fill))
# FAIL: Red
ws.conditional_formatting.add(f'I2:I{num_students+1}',
FormulaRule(formula=['$I2="FAIL"'],
fill=red_fill))
# ABSENT: Gray
ws.conditional_formatting.add(f'I2:I{num_students+1}',
FormulaRule(formula=['$I2="ABSENT"'],
fill=gray_fill))
def setup_summary_analysis(ws):
"""
Set up the Summary Analysis sheet with various summary tables
"""
# Add sheet title
ws['A1'] = "Summary Analysis"
ws['A1'].font = Font(bold=True, size=14)
if grade == "TOTAL":
# Total Males
ws.cell(row=row, column=2, value=f"=SUM(B5:B{row-1})")
# Total Females
ws.cell(row=row, column=4, value=f"=SUM(D5:D{row-1})")
# Total Students
ws.cell(row=row, column=6, value=f"=SUM(F5:F{row-1})")
# Percentages will be 100%
ws.cell(row=row, column=3, value="100%")
ws.cell(row=row, column=5, value="100%")
ws.cell(row=row, column=7, value="100%")
else:
# Male Count
ws.cell(row=row, column=2, value=f'=COUNTIFS(\'Mark Schedule\'!$C:
$C,"M",\'Mark Schedule\'!$H:$H,"{grade}")')
# Female Count
ws.cell(row=row, column=4, value=f'=COUNTIFS(\'Mark Schedule\'!$C:
$C,"F",\'Mark Schedule\'!$H:$H,"{grade}")')
# Total Count
ws.cell(row=row, column=6, value=f'=COUNTIFS(\'Mark Schedule\'!$H:
$H,"{grade}")')
# Male Percentage
ws.cell(row=row, column=3, value=f'=IF(B11=0,0,B{row}/B11)')
# Female Percentage
ws.cell(row=row, column=5, value=f'=IF(D11=0,0,D{row}/D11)')
# Total Percentage
ws.cell(row=row, column=7, value=f'=IF(F11=0,0,F{row}/F11)')
if standard == "TOTAL":
# Total Males
ws.cell(row=row, column=2, value=f"=SUM(B16:B{row-1})")
# Total Females
ws.cell(row=row, column=4, value=f"=SUM(D16:D{row-1})")
# Total Students
ws.cell(row=row, column=6, value=f"=SUM(F16:F{row-1})")
# Percentages will be 100%
ws.cell(row=row, column=3, value="100%")
ws.cell(row=row, column=5, value="100%")
ws.cell(row=row, column=7, value="100%")
else:
# Male Count
ws.cell(row=row, column=2, value=f'=COUNTIFS(\'Mark Schedule\'!$C:
$C,"M",\'Mark Schedule\'!$I:$I,"{standard}")')
# Female Count
ws.cell(row=row, column=4, value=f'=COUNTIFS(\'Mark Schedule\'!$C:
$C,"F",\'Mark Schedule\'!$I:$I,"{standard}")')
# Total Count
ws.cell(row=row, column=6, value=f'=COUNTIFS(\'Mark Schedule\'!$I:
$I,"{standard}")')
# Male Percentage
ws.cell(row=row, column=3, value=f'=IF(B22=0,0,B{row}/B22)')
# Female Percentage
ws.cell(row=row, column=5, value=f'=IF(D22=0,0,D{row}/D22)')
# Total Percentage
ws.cell(row=row, column=7, value=f'=IF(F22=0,0,F{row}/F22)')
# Average Score
ws['B31'] = '=AVERAGEIFS(\'Mark Schedule\'!$G:$G,\'Mark Schedule\'!$C:$C,"M")'
ws['B31'].number_format = "0.00"
def setup_dashboard(ws):
"""
Set up the Dashboard sheet with KPIs and charts
"""
# Add sheet title and information
ws['A1'] = "Class Assessment Dashboard"
ws['A1'].font = Font(bold=True, size=16)
# KPI Section
ws['A5'] = "Key Performance Indicators"
ws['A5'].font = Font(bold=True, size=14)
# KPI Headers
kpi_titles = [
"Class Average",
"Male Average",
"Female Average",
"Pass Rate",
"Distinction Rate",
"Merit Rate",
"Credit Rate",
"Pass Rate (Grade 4)",
"Failure Rate",
"Absence Rate",
"Total Students"
]
# Format numbers
if "Rate" in title:
ws.cell(row=row, column=2).number_format = "0.0%"
elif "Average" in title:
ws.cell(row=row, column=2).number_format = "0.00"
# Add charts
create_charts(ws)
def get_kpi_formula(kpi_title):
"""
Get the appropriate formula for each KPI
"""
if kpi_title == "Class Average":
return "=AVERAGE('Mark Schedule'!G:G)"
elif kpi_title == "Male Average":
return "=AVERAGEIFS('Mark Schedule'!G:G,'Mark Schedule'!C:C,\"M\")"
elif kpi_title == "Female Average":
return "=AVERAGEIFS('Mark Schedule'!G:G,'Mark Schedule'!C:C,\"F\")"
elif kpi_title == "Pass Rate":
return "=COUNTIFS('Mark Schedule'!H:H,\"ONE\")+COUNTIFS('Mark Schedule'!
H:H,\"TWO\")+COUNTIFS('Mark Schedule'!H:H,\"THREE\")+COUNTIFS('Mark Schedule'!
H:H,\"FOUR\")/COUNTIFS('Mark Schedule'!A:A,\"<>\"\"\")"
elif kpi_title == "Distinction Rate":
return "=COUNTIFS('Mark Schedule'!H:H,\"ONE\")/COUNTIFS('Mark Schedule'!
A:A,\"<>\"\"\")"
elif kpi_title == "Merit Rate":
return "=COUNTIFS('Mark Schedule'!H:H,\"TWO\")/COUNTIFS('Mark Schedule'!
A:A,\"<>\"\"\")"
elif kpi_title == "Credit Rate":
return "=COUNTIFS('Mark Schedule'!H:H,\"THREE\")/COUNTIFS('Mark Schedule'!
A:A,\"<>\"\"\")"
elif kpi_title == "Pass Rate (Grade 4)":
return "=COUNTIFS('Mark Schedule'!H:H,\"FOUR\")/COUNTIFS('Mark Schedule'!
A:A,\"<>\"\"\")"
elif kpi_title == "Failure Rate":
return "=COUNTIFS('Mark Schedule'!H:H,\"F\")/COUNTIFS('Mark Schedule'!
A:A,\"<>\"\"\")"
elif kpi_title == "Absence Rate":
return "=COUNTIFS('Mark Schedule'!H:H,\"X\")/COUNTIFS('Mark Schedule'!
A:A,\"<>\"\"\")"
elif kpi_title == "Total Students":
return "=COUNTIFS('Mark Schedule'!A:A,\"<>\"\"\")-1" # Subtract 1 for
header row
else:
return "=0"
def create_charts(ws):
"""
Create charts for the dashboard
"""
# Create a bar chart for grades by gender
bar_chart = BarChart()
bar_chart.title = "Grade Distribution by Gender"
bar_chart.style = 10
bar_chart.x_axis.title = "Grade"
bar_chart.y_axis.title = "Number of Students"
# Headers
grade_headers = ["Grade", "Male", "Female", "Total"]
for i, header in enumerate(grade_headers):
ws.cell(row=6, column=i+4, value=header)
ws.cell(row=6, column=i+4).font = Font(bold=True)
# Headers
perf_headers = ["Standard", "Male", "Female", "Total"]
for i, header in enumerate(perf_headers):
ws.cell(row=6, column=i+9, value=header)
ws.cell(row=6, column=i+9).font = Font(bold=True)
ws.add_chart(pie_chart, "I15")
# Headers
gender_headers = ["Gender", "Count"]
for i, header in enumerate(gender_headers):
ws.cell(row=6, column=i+12, value=header)
ws.cell(row=6, column=i+12).font = Font(bold=True)
ws.add_chart(gender_pie_chart, "L15")
def define_named_ranges(wb):
"""
Define named ranges for easier formula references
"""
# Define named ranges for the Mark Schedule sheet
mark_schedule = wb['Mark Schedule']
wb.defined_names.append(openpyxl.workbook.defined_name.DefinedName('StudentNames',
attr_text=f"'Mark Schedule'!$B$2:$B${mark_schedule.max_row}"))
def adjust_column_widths(wb):
"""
Adjust column widths for better readability
"""
# Adjust column widths for the Mark Schedule sheet
mark_schedule = wb['Mark Schedule']
mark_schedule.column_dimensions['A'].width = 5 # SN
mark_schedule.column_dimensions['B'].width = 20 # Name
mark_schedule.column_dimensions['C'].width = 8 # Sex
mark_schedule.column_dimensions['D'].width = 12 # Assessment 1
mark_schedule.column_dimensions['E'].width = 12 # Assessment 2
mark_schedule.column_dimensions['F'].width = 12 # Assessment 3
mark_schedule.column_dimensions['G'].width = 12 # Average
mark_schedule.column_dimensions['H'].width = 10 # Grade
mark_schedule.column_dimensions['I'].width = 12 # Standard
def add_instructions(wb):
"""
Add instructions to the Mark Schedule sheet
"""
mark_schedule = wb['Mark Schedule']
def set_print_areas(wb):
"""
Set print areas for each sheet
"""
# Set print area for Mark Schedule
mark_schedule = wb['Mark Schedule']
mark_schedule.print_area = f"A1:I{mark_schedule.max_row}"