From a0a2845198a6845d7de429b250a1c5aed80b7c9e Mon Sep 17 00:00:00 2001 From: Peter Howell Date: Sat, 16 Aug 2025 13:41:00 -0700 Subject: [PATCH] report on reg changes --- pipelines.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/pipelines.py b/pipelines.py index 54b9322..5d5604c 100644 --- a/pipelines.py +++ b/pipelines.py @@ -1130,6 +1130,64 @@ def get_doc_generic(docid, bracket=1, verbose=0): +def process_reg_history(): + from collections import defaultdict + from itertools import groupby + from operator import itemgetter + + def read_grouped_csv(path): + with open(path, newline='') as f: + fieldnames = ['datetime', 'crn', 'course', 'teacher', 'max', 'enrolled', 'waitlistmax', 'waitlisted'] + reader = csv.DictReader(f, fieldnames=fieldnames) + rows = sorted(reader, key=lambda r: r['datetime']) # Group by timestamp + grouped = {} + for ts, group in groupby(rows, key=itemgetter('datetime')): + grouped[ts] = {r['crn']: r for r in group} + return grouped + + def detect_changes(prev, curr): + changes = defaultdict(list) + + all_crns = prev.keys() | curr.keys() + for crn in all_crns: + o, n = prev.get(crn), curr.get(crn) + if not o: + changes[crn].append("Section was added.") + elif not n: + changes[crn].append("Section was removed.") + else: + if o['teacher'] != n['teacher']: + changes[crn].append(f"Changed teacher to {n['teacher']}.") + if o['enrolled'] != n['enrolled']: + if int(n['enrolled']) >= int(n.get('max', 9999)): + changes[crn].append("Filled up.") + else: + changes[crn].append(f"Enrollment changed to {n['enrolled']}.") + if int(n.get('waitlisted', 0)) > 10 and o['waitlisted'] != n['waitlisted']: + changes[crn].append(f"Waitlist exceeds 10: {n['waitlisted']}.") + return changes + + def process_diff_timeline(path): + snapshots = read_grouped_csv(path) + timeline = sorted(snapshots.keys()) + reports = [] + + for i in range(1, len(timeline)): + prev_ts, curr_ts = timeline[i-1], timeline[i] + prev, curr = snapshots[prev_ts], snapshots[curr_ts] + delta = detect_changes(prev, curr) + if delta: + reports.append((curr_ts, delta)) + return reports + + result = process_diff_timeline("cache/reg_history_fa25.csv") + for timestamp, changes in result: + print(f"\n[{timestamp}]") + for crn, msgs in sorted(changes.items()): + print(f" CRN {crn}:") + for msg in msgs: + print(f" - {msg}") + if __name__ == "__main__": @@ -1138,6 +1196,7 @@ if __name__ == "__main__": options = { 1: ['Fetch rosters on schedule',fetch_current_rosters_auto] , 2: ['Get canvas data 2024 style', canvas_data_2024_run ], 3: ['Set up canvas data 2024 style', setup_canvas_data_2024_run], + 4: ['Narrative timeline of section updates', process_reg_history], } '''1: ['Re-create schedule csv and json files from raw html',recent_schedules] ,