samder03 commited on
Commit
4f03472
·
verified ·
1 Parent(s): 02aae1b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -89
app.py CHANGED
@@ -249,8 +249,6 @@ for ep in range(1, EPOCHS + 1):
249
  if ep % 5 == 0:
250
  lr_now = opt.param_groups[0]["lr"]
251
  extra = f" hor={stats_va.get('maeH', float('nan')):.3f}" if "maeH" in stats_va else ""
252
- print(f"epoch {ep:03d} | lr={lr_now:.2e} | train_loss={tot_loss:.3f} | "
253
- f"val MAE: imp={stats_va['maeI']:.3f} dur={stats_va['maeD']:.3f}{extra}")
254
 
255
  # ---- early stopping on summed MAE ----
256
  if total_val < best_val - 1e-4:
@@ -260,7 +258,6 @@ for ep in range(1, EPOCHS + 1):
260
  else:
261
  bad += 1
262
  if bad >= patience:
263
- print("early stopping.")
264
  break
265
 
266
  # ---- TEST with best checkpoint ----
@@ -270,10 +267,6 @@ stats_te = eval_block(
270
  (H_te_all_t if H_te_all_t is not None else None),
271
  (mH_te_t if mH_te_t is not None else None)
272
  )
273
- print("[TEST] MAE imp={maeI:.3f} (rho={rhoI:.3f}) | MAE dur={maeD:.3f} (rho={rhoD:.3f})".format(**stats_te))
274
- if "maeH" in stats_te:
275
- print("[TEST] MAE hor={maeH:.3f} (rho={rhoH:.3f})".format(**stats_te))
276
- print("saved model -> mtl_net.pt")
277
 
278
  # ============================================================
279
  # 0) Setup: device, seeds, helper
@@ -324,8 +317,6 @@ i_tr = idx[:n_train]
324
  i_va = idx[n_train:n_train+n_val]
325
  i_te = idx[n_train+n_val:]
326
 
327
- print(f"[Split] train={len(i_tr)} val={len(i_va)} test={len(i_te)}")
328
-
329
  # ============================================================
330
  # 2) Standardize X using ONLY the train set, then tensorize
331
  # ============================================================
@@ -348,8 +339,6 @@ else:
348
  H_tr_all_t = H_va_all_t = H_te_all_t = None
349
  mH_tr_t = mH_va_t = mH_te_t = None
350
 
351
- print(f"[Check tensors] Xt_tr={Xt_tr.shape} Xt_va={Xt_va.shape} Xt_te={Xt_te.shape}")
352
-
353
  # ============================================================
354
  # 3) Model: Multi-Task MLP (shared trunk + 3 heads)
355
  # Slightly wider trunk; textbook uncertainty weighting (0.5 factor)
@@ -484,9 +473,6 @@ for ep in range(1, EPOCHS + 1):
484
  if ep % 5 == 0:
485
  lr_now = opt.param_groups[0]["lr"]
486
  extraH = f" hor={stats_va.get('maeH', float('nan')):.3f}" if "maeH" in stats_va else ""
487
- print(f"epoch {ep:03d} | lr={lr_now:.2e} | train_loss={tot_loss:.3f} | "
488
- f"val MAE: imp={stats_va['maeI']:.3f} dur={stats_va['maeD']:.3f}{extraH} | "
489
- f"rhoI={stats_va['rhoI']:.3f} rhoD={stats_va['rhoD']:.3f}")
490
 
491
  # ---- early stopping on summed MAE ----
492
  if total_val < best_val - 1e-4:
@@ -496,13 +482,11 @@ for ep in range(1, EPOCHS + 1):
496
  else:
497
  bad += 1
498
  if bad >= patience:
499
- print("early stopping.")
500
  break
501
 
502
  # ============================================================
503
  # 6) TEST with best checkpoint + final confirmation
504
  # ============================================================
505
- print(f"[Final split check] train={Xt_tr.shape[0]} val={Xt_va.shape[0]} test={Xt_te.shape[0]}")
506
 
507
  net.load_state_dict(torch.load("mtl_net.pt", map_location=device))
508
  stats_te = eval_block(
@@ -510,10 +494,6 @@ stats_te = eval_block(
510
  (H_te_all_t if H_te_all_t is not None else None),
511
  (mH_te_t if mH_te_t is not None else None)
512
  )
513
- print("[TEST] MAE imp={maeI:.3f} (rho={rhoI:.3f}) | MAE dur={maeD:.3f} (rho={rhoD:.3f})".format(**stats_te))
514
- if "maeH" in stats_te:
515
- print("[TEST] MAE hor={maeH:.3f} (rho={rhoH:.3f})".format(**stats_te))
516
- print("saved model -> mtl_net.pt")
517
 
518
  from datetime import datetime, timedelta, timezone
519
  import numpy as np
@@ -615,10 +595,14 @@ def priority_score(I, H_hours, due_dt, now=None, wI=0.70, wDeadline=0.25, wDur=0
615
  p01 = wI*(float(I)/10.0) + wDeadline*deadline_pressure + wDur*dur_pressure
616
  return round(1 + 9*p01, 1)
617
 
 
 
618
  def reorder_tasks(tasks_string, user_due_iso=None):
 
619
  tasks = [t.strip() for t in str(tasks_string).splitlines() if t.strip()]
620
  if not tasks:
621
- return "", ""
 
622
 
623
  # split/normalize user dates (string or list)
624
  if isinstance(user_due_iso, str) or user_due_iso is None:
@@ -643,34 +627,33 @@ def reorder_tasks(tasks_string, user_due_iso=None):
643
  with torch.no_grad():
644
  rI, rD, rH = net(torch.from_numpy(Xs).to(device))
645
  I = torch.clamp(rI, 1.0, 10.0).cpu().numpy()
646
- H = torch.expm1(rD).clamp(0.25, 12.0).cpu().numpy()
647
- Hd = torch.expm1(rH).clamp(0.0, 30.0).cpu().numpy()
648
 
649
  now = datetime.now(timezone.utc)
650
  assumed_local_tz = timezone.utc
651
 
652
  rows = []
653
  for t, due_s, i_imp, h_hrs, h_days in zip(tasks, due_lines, I, H, Hd):
654
- # parse user date to UTC and keep whether it had time
655
  due_user_utc, had_time = parse_user_due_utc(due_s, local_tz=assumed_local_tz) if due_s else (None, False)
656
 
657
- # due used for scoring
658
  if due_user_utc is not None:
659
  due_for_scores = due_user_utc
660
  display_due_str = _fmt_utc_for_display(due_user_utc, had_time)
661
  else:
662
  due_for_scores = _due_from_model(now, float(h_days)) or _due_from_heuristic(now, float(i_imp), float(h_hrs))
663
- # suggested is always shown as UTC date
664
  display_due_str = _fmt_utc_for_display(due_for_scores, False)
665
 
666
- hours_left = max((due_for_scores - now).total_seconds()/3600.0, 0.5)
667
- U = float(np.clip(np.log1p(float(h_hrs)/hours_left), 0.0, 1.0))
668
  P = priority_score(float(i_imp), float(h_hrs), due_for_scores, now=now)
669
 
670
  rows.append({
671
  "task": t,
672
  "display_due": display_due_str,
673
  "suggested_due_iso": due_for_scores.isoformat(),
 
674
  "priority_1to10": P,
675
  })
676
 
@@ -678,73 +661,75 @@ def reorder_tasks(tasks_string, user_due_iso=None):
678
  ["priority_1to10", "suggested_due_iso"], ascending=[False, True]
679
  ).reset_index(drop=True)
680
 
681
- task_lines = "\n".join(out["task"].tolist())
682
- due_lines_out = "\n".join(out["display_due"].tolist())
683
- return task_lines, due_lines_out
 
 
 
 
 
 
 
 
684
 
685
  import re
686
 
687
- import gradio # For building the interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
688
 
689
- with gradio.Blocks() as demo:
 
 
 
 
690
 
691
- # Let's start by adding a title and introduction
692
- gradio.Markdown(
693
- "# Automated Task Prioritizer"
694
- )
695
- gradio.Markdown(
696
- "This app will take your to-do list and reorder it based on importance, urgency, and duration."
697
- )
698
 
699
- with gradio.Tab("Task Entry"):
700
-
701
- # This row contains all of the physical parameters
702
- with gradio.Row():
703
- sample_tasks = gradio.Textbox(label="Task List", lines=10)
704
- due_dates = gradio.Textbox(label="Due Date", lines=10)
705
-
706
- # Add a button to click to run the interface
707
- run_btn = gradio.Button("Prioritize")
708
- # Finally, add a few examples
709
-
710
- gradio.Examples(
711
- examples=[
712
- ["finish lab report before monday\n"
713
- "email TA about grading\n"
714
- "practice dance combo 20 minutes\n"
715
- "apply to 3 jobs\n"
716
- "review calculus problem set (10 problems)\n"
717
- "call dentist to schedule appointment\n"
718
- "draft 1-page cover letter\n"
719
- "wash dishes\n"
720
- "organize notes for history essay\n"
721
- "watch tv show",
722
- "10/6/25\n"
723
- "10/4/25\n"
724
- "10/4/25\n"
725
- "\n"
726
- "10/8/25\n"
727
- "10/3/25\n"
728
- "10/11/25\n"
729
- "10/3/25\n"
730
- "10/5/25\n"]
731
-
732
- ],
733
- inputs=[sample_tasks, due_dates],
734
- label="Example",
735
- examples_per_page=1,
736
- cache_examples=False,
737
- )
738
-
739
- with gradio.Tab("Prioritized List"):
740
- # These are the outputs. We use both a dataframe (for tabular info) and a markdown box
741
- # for info from the LLM
742
- with gradio.Row():
743
- priority_task = gradio.Textbox(label="Prioritized Task List", lines=10)
744
- date = gradio.Textbox(label="Due Date", interactive=False, lines=10)
745
-
746
- # Run the calculations when the button is clicked
747
- run_btn.click(fn=reorder_tasks, inputs=[sample_tasks, due_dates], outputs=[priority_task, date]) # Add days_left to outputs
748
 
749
  if __name__ == "__main__":
750
  demo.launch(debug=True)
 
249
  if ep % 5 == 0:
250
  lr_now = opt.param_groups[0]["lr"]
251
  extra = f" hor={stats_va.get('maeH', float('nan')):.3f}" if "maeH" in stats_va else ""
 
 
252
 
253
  # ---- early stopping on summed MAE ----
254
  if total_val < best_val - 1e-4:
 
258
  else:
259
  bad += 1
260
  if bad >= patience:
 
261
  break
262
 
263
  # ---- TEST with best checkpoint ----
 
267
  (H_te_all_t if H_te_all_t is not None else None),
268
  (mH_te_t if mH_te_t is not None else None)
269
  )
 
 
 
 
270
 
271
  # ============================================================
272
  # 0) Setup: device, seeds, helper
 
317
  i_va = idx[n_train:n_train+n_val]
318
  i_te = idx[n_train+n_val:]
319
 
 
 
320
  # ============================================================
321
  # 2) Standardize X using ONLY the train set, then tensorize
322
  # ============================================================
 
339
  H_tr_all_t = H_va_all_t = H_te_all_t = None
340
  mH_tr_t = mH_va_t = mH_te_t = None
341
 
 
 
342
  # ============================================================
343
  # 3) Model: Multi-Task MLP (shared trunk + 3 heads)
344
  # Slightly wider trunk; textbook uncertainty weighting (0.5 factor)
 
473
  if ep % 5 == 0:
474
  lr_now = opt.param_groups[0]["lr"]
475
  extraH = f" hor={stats_va.get('maeH', float('nan')):.3f}" if "maeH" in stats_va else ""
 
 
 
476
 
477
  # ---- early stopping on summed MAE ----
478
  if total_val < best_val - 1e-4:
 
482
  else:
483
  bad += 1
484
  if bad >= patience:
 
485
  break
486
 
487
  # ============================================================
488
  # 6) TEST with best checkpoint + final confirmation
489
  # ============================================================
 
490
 
491
  net.load_state_dict(torch.load("mtl_net.pt", map_location=device))
492
  stats_te = eval_block(
 
494
  (H_te_all_t if H_te_all_t is not None else None),
495
  (mH_te_t if mH_te_t is not None else None)
496
  )
 
 
 
 
497
 
498
  from datetime import datetime, timedelta, timezone
499
  import numpy as np
 
595
  p01 = wI*(float(I)/10.0) + wDeadline*deadline_pressure + wDur*dur_pressure
596
  return round(1 + 9*p01, 1)
597
 
598
+ from datetime import datetime, timezone
599
+
600
  def reorder_tasks(tasks_string, user_due_iso=None):
601
+ now = datetime.now(timezone.utc)
602
  tasks = [t.strip() for t in str(tasks_string).splitlines() if t.strip()]
603
  if not tasks:
604
+ # Return empty boxes and clear checkboxes
605
+ return "", "", "", gr.update(choices=[], value=[])
606
 
607
  # split/normalize user dates (string or list)
608
  if isinstance(user_due_iso, str) or user_due_iso is None:
 
627
  with torch.no_grad():
628
  rI, rD, rH = net(torch.from_numpy(Xs).to(device))
629
  I = torch.clamp(rI, 1.0, 10.0).cpu().numpy()
630
+ H = torch.expm1(rD).clamp(0.25, 12.0).cpu().numpy() # duration (hrs), 0.25–12
631
+ Hd = torch.expm1(rH).clamp(0.0, 30.0).cpu().numpy() # horizon (days), 0–30
632
 
633
  now = datetime.now(timezone.utc)
634
  assumed_local_tz = timezone.utc
635
 
636
  rows = []
637
  for t, due_s, i_imp, h_hrs, h_days in zip(tasks, due_lines, I, H, Hd):
638
+ # parse user date (if provided)
639
  due_user_utc, had_time = parse_user_due_utc(due_s, local_tz=assumed_local_tz) if due_s else (None, False)
640
 
641
+ # choose due_for_scores and display string
642
  if due_user_utc is not None:
643
  due_for_scores = due_user_utc
644
  display_due_str = _fmt_utc_for_display(due_user_utc, had_time)
645
  else:
646
  due_for_scores = _due_from_model(now, float(h_days)) or _due_from_heuristic(now, float(i_imp), float(h_hrs))
 
647
  display_due_str = _fmt_utc_for_display(due_for_scores, False)
648
 
649
+ # priority score
 
650
  P = priority_score(float(i_imp), float(h_hrs), due_for_scores, now=now)
651
 
652
  rows.append({
653
  "task": t,
654
  "display_due": display_due_str,
655
  "suggested_due_iso": due_for_scores.isoformat(),
656
+ "duration_hrs": float(h_hrs), # keep raw number for sorting/formatting
657
  "priority_1to10": P,
658
  })
659
 
 
661
  ["priority_1to10", "suggested_due_iso"], ascending=[False, True]
662
  ).reset_index(drop=True)
663
 
664
+ choices = [f"{i+1}. {t}" for i, t in enumerate(out["task"].tolist())]
665
+
666
+ # Prepare the three text outputs
667
+ task_lines = "\n".join(out["task"].tolist())
668
+ due_lines_out = "\n".join(out["display_due"].tolist())
669
+ duration_lines = "\n".join(f"{d:.1f}" for d in out["duration_hrs"].tolist())
670
+
671
+ # IMPORTANT: don't wipe user selections each run
672
+ checkbox_update = gr.update(choices=choices)
673
+
674
+ return task_lines, due_lines_out, duration_lines, checkbox_update
675
 
676
  import re
677
 
678
+ import gradio as gr # For building the interface
679
+
680
+ with gr.Blocks() as demo:
681
+ gr.Markdown("# Automated Task Prioritizer")
682
+ gr.Markdown("This app will take your to-do list and reorder it based on importance, urgency, and duration.")
683
+
684
+ with gr.Tab("Task Entry"):
685
+ with gr.Row():
686
+ sample_tasks = gr.Textbox(label="Task List", lines=10, placeholder="One task per line")
687
+ due_dates = gr.Textbox(label="Due Date", lines=10, placeholder="One date per line (optional)")
688
+
689
+ run_btn = gr.Button("Prioritize")
690
+
691
+ gr.Examples(
692
+ examples=[[
693
+ "finish lab report before monday\n"
694
+ "email TA about grading\n"
695
+ "practice dance combo 20 minutes\n"
696
+ "apply to 3 jobs\n"
697
+ "review calculus problem set (10 problems)\n"
698
+ "call dentist to schedule appointment\n"
699
+ "draft 1-page cover letter\n"
700
+ "wash dishes\n"
701
+ "organize notes for history essay\n"
702
+ "watch tv show",
703
+ "10/6/25\n"
704
+ "10/4/25\n"
705
+ "10/4/25\n"
706
+ "\n"
707
+ "10/8/25\n"
708
+ "10/3/25\n"
709
+ "10/11/25\n"
710
+ "10/3/25\n"
711
+ "10/5/25\n"
712
+ ]],
713
+ inputs=[sample_tasks, due_dates],
714
+ label="Example",
715
+ examples_per_page=1,
716
+ cache_examples=False,
717
+ )
718
 
719
+ with gr.Tab("Prioritized List"):
720
+ with gr.Row():
721
+ priority_task = gr.Textbox(label="Prioritized Task List", lines=10, interactive=False)
722
+ date_box = gr.Textbox(label="Due Date", lines=10, interactive=False)
723
+ durations_box = gr.Textbox(label="Duration (hrs)", lines=10, interactive=False)
724
 
725
+ done_boxes = gr.CheckboxGroup(label="Mark completed tasks", interactive=True) # <-- ensure interactive
 
 
 
 
 
 
726
 
727
+ # Wire up
728
+ run_btn.click(
729
+ fn=reorder_tasks,
730
+ inputs=[sample_tasks, due_dates],
731
+ outputs=[priority_task, date_box, durations_box, done_boxes]
732
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
 
734
  if __name__ == "__main__":
735
  demo.launch(debug=True)