Spaces:
Build error
Build error
File size: 5,246 Bytes
4f184d1 989e952 4f184d1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | from transformers import pipeline
import pandas as pd
import math
import gradio as gr
# Step 1: Load Excel Files (Not needed for Gradio, files are loaded in run_allocation)
# Step 2: Calculate Total Hours and Average Duty (n)
def calculate_average_duty(exams_df, teachers_df):
grouped = exams_df.groupby(['Day', 'Slot', 'Room Number'])['Student Number'].sum().reset_index(name='TotalStudents')
def compute_invigilators(x):
n = math.ceil(x / 20)
while (20 * n + 10) < x:
n += 1
return n
grouped['RequiredInvigilators'] = grouped['TotalStudents'].apply(compute_invigilators)
exams_df = pd.merge(
exams_df,
grouped[['Day', 'Slot', 'Room Number', 'RequiredInvigilators']],
on=['Day', 'Slot', 'Room Number'],
how='left'
)
exams_df['Duration'] = exams_df['Duration'].astype(int)
total_invigilator_hours = sum(exams_df['RequiredInvigilators'] * exams_df['Duration'])
n = total_invigilator_hours / len(teachers_df)
return n, total_invigilator_hours, exams_df
# Step 3: Assign Initial Duty Limits Based on Designation
def assign_initial_duties(teachers_df, avg_duty):
teachers_df['DESIG'] = teachers_df['DESIG'].str.strip().str.upper()
def get_duty_limit(desig, avg):
if desig == "SACT":
return avg - 2
elif desig in ["LAB", "HOD", "BURSAR", "AQAC"]:
return avg - 1
else:
return avg # Default for A.P. and others
teachers_df['DutyLimit'] = teachers_df['DESIG'].apply(lambda d: get_duty_limit(d, math.ceil(avg_duty)))
teachers_df['AssignedHours'] = 0
teachers_df['AssignedDays'] = [[] for _ in range(len(teachers_df))]
return teachers_df
# Step 4: Assign Duties
def assign_duties(teachers_df, exams_df, buffer=0.5):
assignments = []
unassigned = []
unique_sessions = exams_df[['Day', 'Slot', 'Room Number', 'Duration', 'RequiredInvigilators']].drop_duplicates()
for _, exam in unique_sessions.iterrows():
date = exam['Day']
time = exam['Slot']
duration = int(exam['Duration'])
room = exam['Room Number']
required_invigilators = int(exam['RequiredInvigilators'])
for _ in range(required_invigilators):
available_teachers = teachers_df[
(teachers_df['AssignedHours'] + duration <= teachers_df['DutyLimit'] + buffer) &
(~teachers_df['AssignedDays'].apply(lambda x: (date, time) in x))
]
if available_teachers.empty:
unassigned.append({
'Day': date, 'Slot': time, 'Room': room,
'Duration': duration, 'Reason': 'No available teacher'
})
continue
available_teachers = available_teachers.sort_values(by='AssignedHours')
selected_teacher = available_teachers.head(1)
idx = selected_teacher.index[0]
teachers_df.at[idx, 'AssignedHours'] += duration
teachers_df.at[idx, 'AssignedDays'].append((date, time))
assignments.append({
'Day': date,
'Slot': time,
'Room': room,
'Duration': duration,
'Teacher': teachers_df.at[idx, 'NAME'],
'Designation': teachers_df.at[idx, 'DESIG'],
'AssignedHoursAfter': teachers_df.at[idx, 'AssignedHours']
})
return pd.DataFrame(assignments), pd.DataFrame(unassigned)
# Function to run the allocation process
def run_allocation(teachers_file, exams_file, buffer=0.5):
try:
teachers_df = pd.read_excel(teachers_file.name)
exams_df = pd.read_excel(exams_file.name)
n, total_hours, exams_df = calculate_average_duty(exams_df, teachers_df)
teachers_df = assign_initial_duties(teachers_df, n)
assignments_df, unassigned_df = assign_duties(teachers_df, exams_df, buffer=buffer)
# Save assignments to Excel for download
assignments_df.to_excel("duty_allocation_summary.xlsx", index=False)
# Return DataFrames, summary, and file path for display and download
return assignments_df, unassigned_df, teachers_df[['NAME', 'DESIG', 'AssignedHours', 'DutyLimit']], total_hours, n, "duty_allocation_summary.xlsx"
except Exception as e:
return None, None, None, None, str(e), None # Return None for file path on error
# Gradio Interface
iface = gr.Interface(
fn=run_allocation,
inputs=[
gr.File(label="Teachers Excel File"),
gr.File(label="Exam Summary Excel File"),
gr.Slider(minimum=0, maximum=2, step=0.1, label="Duty Buffer", value=0.5),
],
outputs=[
gr.Dataframe(label="Duty Assignments"),
gr.Dataframe(label="Unassigned Duties"),
gr.Dataframe(label="Teacher Summary"),
gr.Textbox(label="Total Invigilator Hours"),
gr.Textbox(label="Average Duty per Teacher"),
gr.File(label="Download Duty Allocation Summary") # Add File component for download
],
title="🧑🏫 Duty Allocation System",
description="Upload your Excel files and click 'Submit' to generate duty assignments."
)
iface.launch(inline = False)
|