kosmoscpp commited on
Commit
ff47493
·
verified ·
1 Parent(s): d2bdf89

Create app.py

Browse files

The code, ran locally with tkinter, using gradio here

Files changed (1) hide show
  1. app.py +137 -0
app.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import matplotlib.pyplot as plt
4
+ from math import ceil
5
+ from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
6
+ from reportlab.lib import colors
7
+ import io
8
+
9
+ # --- Core Planner Logic ---
10
+ class Subject:
11
+ def __init__(self, name, lectures_per_day, backlog, avg_time, priority):
12
+ self.name = name
13
+ self.A = lectures_per_day
14
+ self.B = backlog
15
+ self.time = avg_time
16
+ self.priority = priority
17
+
18
+ class Planner:
19
+ def __init__(self, subjects, avg_hours, max_hours):
20
+ self.subjects = subjects
21
+ self.avg_minutes = avg_hours * 60
22
+ self.max_minutes = max_hours * 60
23
+
24
+ def calculate(self, T):
25
+ daily_plan = {}
26
+ total_time = 0
27
+ for s in self.subjects:
28
+ required = s.A + ceil((s.B * s.priority) / T)
29
+ time_needed = required * s.time
30
+ daily_plan[s.name] = {"lectures": required, "time": time_needed}
31
+ total_time += time_needed
32
+ return daily_plan, total_time
33
+
34
+ def auto_adjust_days(self, T):
35
+ while True:
36
+ plan, time = self.calculate(T)
37
+ if time <= self.avg_minutes:
38
+ return T, plan, time
39
+ T += 1
40
+
41
+ # --- Gradio Functions ---
42
+ def run_planner(subjects_text, days, avg_hours, max_hours):
43
+ # Parse subjects input (name, lectures/day, backlog, avg_time, priority)
44
+ subjects = []
45
+ for line in subjects_text.strip().split("\n"):
46
+ parts = line.split(",")
47
+ if len(parts) != 5:
48
+ continue
49
+ try:
50
+ s = Subject(
51
+ parts[0].strip(),
52
+ float(parts[1]),
53
+ int(parts[2]),
54
+ float(parts[3]),
55
+ float(parts[4])
56
+ )
57
+ subjects.append(s)
58
+ except:
59
+ continue
60
+
61
+ planner = Planner(subjects, float(avg_hours), float(max_hours))
62
+ T, plan, total_time = planner.auto_adjust_days(int(days))
63
+
64
+ # Build dataframe
65
+ df_data = []
66
+ for k, v in plan.items():
67
+ df_data.append([k, v["lectures"], round(v["time"],1)])
68
+ df = pd.DataFrame(df_data, columns=["Subject","Lectures/day","Time/day (min)"])
69
+
70
+ # Build textual summary
71
+ summary = f"Adjusted target days: {T}\nTotal daily time: {total_time:.1f} min\n\n"
72
+ for k, v in plan.items():
73
+ summary += f"{k}: {v['lectures']} lectures → {v['time']:.1f} min/day\n"
74
+
75
+ return df, summary
76
+
77
+ def plot_graph(df):
78
+ fig, ax = plt.subplots(figsize=(6,4))
79
+ ax.pie(df["Time/day (min)"], labels=df["Subject"], autopct='%1.1f%%')
80
+ ax.set_title("Daily Time Distribution")
81
+ buf = io.BytesIO()
82
+ plt.savefig(buf, format='png')
83
+ buf.seek(0)
84
+ return buf
85
+
86
+ def export_csv(df):
87
+ buf = io.StringIO()
88
+ df.to_csv(buf, index=False)
89
+ buf.seek(0)
90
+ return buf
91
+
92
+ def export_pdf(df):
93
+ buf = io.BytesIO()
94
+ doc = SimpleDocTemplate(buf)
95
+ data = [df.columns.tolist()] + df.values.tolist()
96
+ table = Table(data)
97
+ style = TableStyle([
98
+ ('BACKGROUND',(0,0),(-1,0),colors.grey),
99
+ ('TEXTCOLOR',(0,0),(-1,0),colors.whitesmoke),
100
+ ('ALIGN',(0,0),(-1,-1),'CENTER'),
101
+ ('GRID',(0,0),(-1,-1),1,colors.black),
102
+ ])
103
+ table.setStyle(style)
104
+ doc.build([table])
105
+ buf.seek(0)
106
+ return buf
107
+
108
+ # --- Gradio Interface ---
109
+ with gr.Blocks() as demo:
110
+ gr.Markdown("# Advanced Backlog Planner")
111
+ with gr.Row():
112
+ with gr.Column():
113
+ subjects_input = gr.Textbox(label="Subjects (name, lectures/day, backlog, avg_time, priority)",
114
+ placeholder="Math,2,5,50,1.0\nPhysics,1,3,40,1.2", lines=10)
115
+ days_input = gr.Number(label="Target Days", value=5)
116
+ avg_input = gr.Number(label="Avg hrs/day", value=4)
117
+ max_input = gr.Number(label="Max hrs/day", value=8)
118
+ run_button = gr.Button("Calculate")
119
+ with gr.Column():
120
+ summary_output = gr.Textbox(label="Summary", lines=15)
121
+ table_output = gr.Dataframe(headers=["Subject","Lectures/day","Time/day (min)"])
122
+ graph_output = gr.Image(label="Graph")
123
+ csv_output = gr.File(label="Download CSV")
124
+ pdf_output = gr.File(label="Download PDF")
125
+
126
+ def compute(subjects_input, days_input, avg_input, max_input):
127
+ df, summary = run_planner(subjects_input, days_input, avg_input, max_input)
128
+ graph = plot_graph(df)
129
+ csv_buf = export_csv(df)
130
+ pdf_buf = export_pdf(df)
131
+ return summary, df, graph, csv_buf, pdf_buf
132
+
133
+ run_button.click(compute,
134
+ inputs=[subjects_input, days_input, avg_input, max_input],
135
+ outputs=[summary_output, table_output, graph_output, csv_output, pdf_output])
136
+
137
+ demo.launch()