File size: 5,078 Bytes
ff47493
 
 
 
 
 
9b552ec
ff47493
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9b552ec
 
ff47493
9b552ec
ff47493
9b552ec
 
 
 
 
 
 
ff47493
 
 
 
9b552ec
ff47493
9b552ec
 
 
 
 
 
 
ff47493
 
 
9b552ec
ff47493
9b552ec
ff47493
9b552ec
ff47493
9b552ec
 
 
 
ff47493
9b552ec
 
 
 
ff47493
9b552ec
 
 
 
ff47493
 
 
 
 
 
 
 
 
9b552ec
ff47493
 
 
9b552ec
 
ff47493
 
9b552ec
 
 
 
 
 
 
 
 
 
ff47493
 
 
 
 
 
 
9b552ec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ff47493
 
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
142
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()