backlog_planner / app.py
kosmoscpp's picture
Update app.py
9b552ec verified
Raw
History Blame Contribute Delete
5.08 kB
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()