import gradio as gr import pandas as pd import matplotlib.pyplot as plt from math import ceil from reportlab.platypus import SimpleDocTemplate, Table, TableStyle from reportlab.lib import colors import tempfile # --- Core Planner Logic --- class Subject: def __init__(self, name, lectures_per_day, backlog, avg_time, priority): self.name = name self.A = lectures_per_day self.B = backlog self.time = avg_time self.priority = priority class Planner: def __init__(self, subjects, avg_hours, max_hours): self.subjects = subjects self.avg_minutes = avg_hours * 60 self.max_minutes = max_hours * 60 def calculate(self, T): daily_plan = {} total_time = 0 for s in self.subjects: required = s.A + ceil((s.B * s.priority) / T) time_needed = required * s.time daily_plan[s.name] = {"lectures": required, "time": time_needed} total_time += time_needed return daily_plan, total_time def auto_adjust_days(self, T): while True: plan, time = self.calculate(T) if time <= self.avg_minutes: return T, plan, time T += 1 # --- Gradio Functions --- def run_planner(df_input, target_days, avg_hours, max_hours): # Convert dataframe to Subject list subjects = [] for _, row in df_input.iterrows(): try: subjects.append(Subject( str(row["Subject"]), float(row["Lectures/day"]), int(row["Backlog"]), float(row["Avg time"]), float(row["Priority"]) )) except: continue planner = Planner(subjects, float(avg_hours), float(max_hours)) T, plan, total_time = planner.auto_adjust_days(int(target_days)) # Build dataframe output df_output = pd.DataFrame([ [k, v["lectures"], round(v["time"],1)] for k, v in plan.items() ], columns=["Subject","Lectures/day","Time/day (min)"]) # Text summary summary = f"Adjusted target days: {T}\nTotal daily time: {total_time:.1f} min\n\n" for k, v in plan.items(): summary += f"{k}: {v['lectures']} lectures → {v['time']:.1f} min/day\n" return df_output, summary def plot_graph(df_output): fig, ax = plt.subplots(figsize=(6,4)) ax.pie(df_output["Time/day (min)"], labels=df_output["Subject"], autopct='%1.1f%%') ax.set_title("Daily Time Distribution") tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png") plt.savefig(tmp_file.name) plt.close(fig) return tmp_file.name def export_csv(df_output): tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".csv") df_output.to_csv(tmp_file.name, index=False) return tmp_file.name def export_pdf(df_output): tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") doc = SimpleDocTemplate(tmp_file.name) data = [df_output.columns.tolist()] + df_output.values.tolist() table = Table(data) style = TableStyle([ ('BACKGROUND',(0,0),(-1,0),colors.grey), ('TEXTCOLOR',(0,0),(-1,0),colors.whitesmoke), ('ALIGN',(0,0),(-1,-1),'CENTER'), ('GRID',(0,0),(-1,-1),1,colors.black), ]) table.setStyle(style) doc.build([table]) return tmp_file.name # --- Gradio Interface --- with gr.Blocks() as demo: gr.Markdown("# 📝 Advanced Backlog Planner") with gr.Row(): with gr.Column(): df_input = gr.Dataframe( headers=["Subject","Lectures/day","Backlog","Avg time","Priority"], datatype=["str","number","number","number","number"], interactive=True, label="Subjects Input" ) target_days = gr.Number(label="Target Days", value=5) avg_hours = gr.Number(label="Avg hrs/day", value=4) max_hours = gr.Number(label="Max hrs/day", value=8) run_button = gr.Button("Calculate Plan") with gr.Column(): summary_output = gr.Textbox(label="Summary", lines=15) table_output = gr.Dataframe(headers=["Subject","Lectures/day","Time/day (min)"]) graph_output = gr.Image(label="Graph") csv_output = gr.File(label="Download CSV") pdf_output = gr.File(label="Download PDF") def compute(df_input, target_days, avg_hours, max_hours): df_output, summary = run_planner(df_input, target_days, avg_hours, max_hours) return df_output, summary run_button.click( compute, inputs=[df_input, target_days, avg_hours, max_hours], outputs=[table_output, summary_output] ) # Graph button gr.Button("Show Graph").click(plot_graph, inputs=[table_output], outputs=[graph_output]) # CSV button gr.Button("Export CSV").click(export_csv, inputs=[table_output], outputs=[csv_output]) # PDF button gr.Button("Export PDF").click(export_pdf, inputs=[table_output], outputs=[pdf_output]) demo.launch()