diff --git a/app/template_generator.py b/app/template_generator.py index 6dbdca9..4fb9caa 100644 --- a/app/template_generator.py +++ b/app/template_generator.py @@ -1,12 +1,20 @@ """ -Main entry point: builds a clash-free dummy schedule and renders all five -timetable views (batch/department/room/student/teacher -wise) as .xlsx -files under result/templates//. +Main entry point: runs the three scheduling phases (general courses, labs, +remaining courses) and renders all five timetable views (batch/department/ +room/student/teacher -wise) as .xlsx files under result/templates//. -Run: - python app/template_generator.py +Each phase is its own subcommand so it can be run and inspected as a +separate step; each phase's placements are persisted to +result/schedule_state.json and loaded back in by the next phase's command. + +Usage: + python app/template_generator.py phase_1 # general courses (Tue/Thu preferred) + python app/template_generator.py phase_2 # labs, on top of phase_1 + python app/template_generator.py phase_3 # remaining courses, batch by batch + python app/template_generator.py clear_all # wipe state/results/log to start over """ +import json import os import shutil import sys @@ -35,8 +43,43 @@ from student_wise_template import generate_student_wise_templates # noqa: E402 from teacher_wise_template import generate_teacher_wise_templates # noqa: E402 RESULT_DIR = os.path.join(ROOT_DIR, "result", "templates") +STATE_FILE = os.path.join(ROOT_DIR, "result", "schedule_state.json") VIEW_NAMES = ["batch-wise", "department-wise", "room-wise", "student-wise", "teacher-wise"] +PHASE_ORDER = ["phase_1", "phase_2", "phase_3"] + +GENERATORS = [ + ("batch-wise", generate_batch_wise_templates), + ("department-wise", generate_department_wise_templates), + ("room-wise", generate_room_wise_templates), + ("student-wise", generate_student_wise_templates), + ("teacher-wise", generate_teacher_wise_templates), +] + + +# --------------------------------------------------------------------------- +# State persistence +# --------------------------------------------------------------------------- + +def load_state(): + """Returns the saved schedule state dict, or None if none exists yet.""" + if not os.path.exists(STATE_FILE): + return None + with open(STATE_FILE, encoding="utf-8") as f: + return json.load(f) + + +def save_state(scheduler, phases_completed): + state = scheduler.to_state() + state["phases_completed"] = phases_completed + os.makedirs(os.path.dirname(STATE_FILE), exist_ok=True) + with open(STATE_FILE, "w", encoding="utf-8") as f: + json.dump(state, f, indent=2) + + +# --------------------------------------------------------------------------- +# Shared helpers +# --------------------------------------------------------------------------- def _check_and_log(sessions, label): """Runs student + teacher conflict checks over `sessions` and logs the result.""" @@ -64,10 +107,7 @@ def clear_result_dir(): os.makedirs(output_dir, exist_ok=True) -def main(): - reset_log() - clear_result_dir() - +def ensure_dummy_data(): data_csv_marker = os.path.join(ROOT_DIR, "data", "dummy", "blocks", "rooms.csv") if not os.path.exists(data_csv_marker): print("Dummy data not found — generating it first...") @@ -76,49 +116,101 @@ def main(): generate_dummy_data() print() - log_info("Loading data...") - data = load_data() - scheduler = Scheduler(data) - - # --- Phase 1: general courses (Tue/Thu preferred), self-repaired until clash-free --- - log_info("Phase 1/3: scheduling general courses...") - phase1_sessions = scheduler.phase_1_general_courses() - _check_and_log(phase1_sessions, "Phase 1 (general courses)") - - # --- Phase 2: labs, scheduled against Phase 1's fixed placements --- - log_info("Phase 2/3: scheduling labs...") - phase2_sessions = scheduler.phase_2_labs() - _check_and_log(phase1_sessions + phase2_sessions, "Phase 2 (general courses + labs)") - - # --- Phase 3: remaining theory courses, batch by batch --- - log_info("Phase 3/3: scheduling remaining courses (batch by batch)...") - phase3_sessions = scheduler.phase_3_remaining_courses() - - sessions = phase1_sessions + phase2_sessions + phase3_sessions - log_info( - f"Scheduling complete: {len(phase1_sessions)} general, {len(phase2_sessions)} lab, " - f"{len(phase3_sessions)} remaining = {len(sessions)} total session(s)." - ) - - log_info("Running final conflict check (student/batch and teacher) over the full schedule...") - _check_and_log(sessions, "Final (full schedule)") - - generators = [ - ("batch-wise", generate_batch_wise_templates), - ("department-wise", generate_department_wise_templates), - ("room-wise", generate_room_wise_templates), - ("student-wise", generate_student_wise_templates), - ("teacher-wise", generate_teacher_wise_templates), - ] +def regenerate_templates(sessions, data): + clear_result_dir() total_files = 0 - for view_name, generate_fn in generators: + for view_name, generate_fn in GENERATORS: output_dir = os.path.join(RESULT_DIR, view_name) written = generate_fn(sessions, data, output_dir) total_files += len(written) print(f"[{view_name}] generated {len(written)} file(s) -> {output_dir}") + print(f"\n{total_files} timetable file(s) written under {RESULT_DIR}") - print(f"\nDone. {total_files} timetable file(s) written under {RESULT_DIR}") + +# --------------------------------------------------------------------------- +# Commands +# --------------------------------------------------------------------------- + +def cmd_clear_all(): + if os.path.exists(STATE_FILE): + os.remove(STATE_FILE) + clear_result_dir() + reset_log() + log_info("clear_all: schedule state, result templates, and log have been reset. Run phase_1 to start over.") + + +def cmd_phase(phase_name): + ensure_dummy_data() + data = load_data() + + state = load_state() + completed = state["phases_completed"] if state else [] + + if phase_name in completed: + log_error( + f"{phase_name} has already been run (completed phases: {completed}). " + f"Run 'python app/template_generator.py clear_all' first if you want to redo it." + ) + return + + phase_index = PHASE_ORDER.index(phase_name) + required_prior = PHASE_ORDER[:phase_index] + missing = [p for p in required_prior if p not in completed] + if missing: + log_error( + f"Cannot run {phase_name} yet — missing prior phase(s) {missing}. " + f"Run them in order: {', '.join(PHASE_ORDER)} (or 'clear_all' to start over)." + ) + return + + if state is None: + scheduler = Scheduler(data) + else: + scheduler = Scheduler.from_state(data, state) + + if phase_name == "phase_1": + log_info("Phase 1/3: scheduling general courses (Tue/Thu preferred)...") + new_sessions = scheduler.phase_1_general_courses() + elif phase_name == "phase_2": + log_info("Phase 2/3: scheduling labs (on top of phase_1's fixed placements)...") + new_sessions = scheduler.phase_2_labs() + else: + log_info("Phase 3/3: scheduling remaining courses (batch by batch)...") + new_sessions = scheduler.phase_3_remaining_courses() + + label = { + "phase_1": "Phase 1 (general courses)", + "phase_2": "Phase 2 (general courses + labs)", + "phase_3": "Phase 3 (full schedule)", + }[phase_name] + _check_and_log(scheduler.sessions, label) + + completed = completed + [phase_name] + save_state(scheduler, completed) + log_info( + f"{phase_name} complete: {len(new_sessions)} session(s) added this phase, " + f"{len(scheduler.sessions)} total so far. State saved to {STATE_FILE}." + ) + + regenerate_templates(scheduler.sessions, data) + + +def print_usage(): + print(__doc__) + + +def main(): + args = sys.argv[1:] + if not args or args[0] not in ("phase_1", "phase_2", "phase_3", "clear_all"): + print_usage() + return + + command = args[0] + if command == "clear_all": + cmd_clear_all() + else: + cmd_phase(command) if __name__ == "__main__": diff --git a/app/template_logger.py b/app/template_logger.py index 4edbc76..37be571 100644 --- a/app/template_logger.py +++ b/app/template_logger.py @@ -40,8 +40,19 @@ def log_info(message): def _write(level, message): + global _log_path if _log_path is None: - reset_log() + os.makedirs(LOGS_DIR, exist_ok=True) + _log_path = LOG_FILE + if not os.path.exists(_log_path): + # First-ever write with no prior reset_log() call in this + # process (e.g. a phase_N command run without a preceding + # clear_all): create the file fresh, but never truncate an + # existing log — separate process invocations of phase_1/2/3 + # must all append to the same ongoing log. + with open(_log_path, "w", encoding="utf-8") as f: + f.write(f"Timetable generation log - started {datetime.datetime.now().isoformat()}\n") + f.write("=" * 80 + "\n") line = f"[{datetime.datetime.now().strftime('%H:%M:%S')}] {level}: {message}" with open(_log_path, "a", encoding="utf-8") as f: f.write(line + "\n") diff --git a/controller/template_controller.py b/controller/template_controller.py index e829c31..9203dce 100644 --- a/controller/template_controller.py +++ b/controller/template_controller.py @@ -121,6 +121,39 @@ class Scheduler: self.sessions = [] + def to_state(self): + """ + Serializes this scheduler's accumulated sessions and busy-maps to a + JSON-able dict, so a later process can resume exactly where this + one left off (used to run each phase as a separate CLI command). + """ + def _dump_busy(busy_map): + return {f"{day}|{slot_index}": sorted(values) for (day, slot_index), values in busy_map.items()} + + return { + "sessions": self.sessions, + "room_busy": _dump_busy(self.room_busy), + "instructor_busy": _dump_busy(self.instructor_busy), + "batch_busy": _dump_busy(self.batch_busy), + } + + @classmethod + def from_state(cls, data, state): + """Rebuilds a Scheduler from a dict previously produced by to_state().""" + def _load_busy(dumped): + busy = {} + for key, values in dumped.items(): + day, slot_index = key.rsplit("|", 1) + busy[(day, int(slot_index))] = set(values) + return busy + + scheduler = cls(data) + scheduler.sessions = list(state["sessions"]) + scheduler.room_busy = _load_busy(state["room_busy"]) + scheduler.instructor_busy = _load_busy(state["instructor_busy"]) + scheduler.batch_busy = _load_busy(state["batch_busy"]) + return scheduler + def _is_free(self, day, slot_index, room_id, instructor_code, batch_codes): key = (day, slot_index) if room_id in self.room_busy.get(key, set()): diff --git a/logs/template_generator.log b/logs/template_generator.log index 1122fd3..f6c440e 100644 --- a/logs/template_generator.log +++ b/logs/template_generator.log @@ -1,11 +1,5 @@ -Timetable generation log - started 2026-09-09T18:02:42.384468 +Timetable generation log - started 2026-09-09T18:06:49.239332 ================================================================================ -[18:02:42] INFO: Loading data... -[18:02:42] INFO: Phase 1/3: scheduling general courses... -[18:02:42] INFO: [Phase 1 (general courses)] No conflicts found — clash-free. -[18:02:42] INFO: Phase 2/3: scheduling labs... -[18:02:42] INFO: [Phase 2 (general courses + labs)] No conflicts found — clash-free. -[18:02:42] INFO: Phase 3/3: scheduling remaining courses (batch by batch)... -[18:02:42] INFO: Scheduling complete: 6 general, 10 lab, 20 remaining = 36 total session(s). -[18:02:42] INFO: Running final conflict check (student/batch and teacher) over the full schedule... -[18:02:42] INFO: [Final (full schedule)] No conflicts found — clash-free. +[18:06:49] INFO: Phase 3/3: scheduling remaining courses (batch by batch)... +[18:06:49] INFO: [Phase 3 (full schedule)] No conflicts found — clash-free. +[18:06:49] INFO: phase_3 complete: 20 session(s) added this phase, 36 total so far. State saved to D:\projects\UORM\timetable\result\schedule_state.json. diff --git a/result/schedule_state.json b/result/schedule_state.json new file mode 100644 index 0000000..c031f1f --- /dev/null +++ b/result/schedule_state.json @@ -0,0 +1,1027 @@ +{ + "sessions": [ + { + "day": "Tuesday", + "slot_indices": [ + 0 + ], + "start": "08:30", + "end": "10:00", + "course_id": "GEN101", + "course_name": "Functional English", + "course_type": "theory", + "is_general": true, + "section_id": "A", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-103", + "room_name": "Room 103", + "batch_codes": [ + "25021519", + "25021520", + "25031519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 1 + ], + "start": "10:00", + "end": "11:30", + "course_id": "GEN101", + "course_name": "Functional English", + "course_type": "theory", + "is_general": true, + "section_id": "A", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-103", + "room_name": "Room 103", + "batch_codes": [ + "25021519", + "25021520", + "25031519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "GEN102", + "course_name": "Islamic Studies", + "course_type": "theory", + "is_general": true, + "section_id": "A", + "instructor_code": "1006", + "instructor_name": "Ms. Hira Shah", + "room_id": "A-103", + "room_name": "Room 103", + "batch_codes": [ + "25021519", + "25021520", + "25031519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "GEN101", + "course_name": "Functional English", + "course_type": "theory", + "is_general": true, + "section_id": "B", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "26021519", + "26021520", + "26031519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 4 + ], + "start": "13:30", + "end": "15:00", + "course_id": "GEN101", + "course_name": "Functional English", + "course_type": "theory", + "is_general": true, + "section_id": "B", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-103", + "room_name": "Room 103", + "batch_codes": [ + "26021519", + "26021520", + "26031519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 0 + ], + "start": "08:30", + "end": "10:00", + "course_id": "GEN102", + "course_name": "Islamic Studies", + "course_type": "theory", + "is_general": true, + "section_id": "B", + "instructor_code": "1006", + "instructor_name": "Ms. Hira Shah", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "26021519", + "26021520", + "26031519" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 0, + 1 + ], + "start": "08:30", + "end": "11:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "lab", + "is_general": false, + "section_id": "A", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-L01", + "room_name": "Computer Lab 1", + "batch_codes": [ + "25021519" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 4, + 5 + ], + "start": "13:30", + "end": "16:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "lab", + "is_general": false, + "section_id": "A", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-L01", + "room_name": "Computer Lab 1", + "batch_codes": [ + "25021519" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 4, + 5 + ], + "start": "13:30", + "end": "16:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "lab", + "is_general": false, + "section_id": "B", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-L02", + "room_name": "Computer Lab 2", + "batch_codes": [ + "25021520" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 0, + 1 + ], + "start": "08:30", + "end": "11:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "lab", + "is_general": false, + "section_id": "B", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-L02", + "room_name": "Computer Lab 2", + "batch_codes": [ + "25021520" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 4, + 5 + ], + "start": "13:30", + "end": "16:30", + "course_id": "EE101", + "course_name": "Basic Electronics", + "course_type": "lab", + "is_general": false, + "section_id": "A", + "instructor_code": "1004", + "instructor_name": "Dr. Farah Iqbal", + "room_id": "A-L02", + "room_name": "Computer Lab 2", + "batch_codes": [ + "25031519" + ] + }, + { + "day": "Wednesday", + "slot_indices": [ + 0, + 1 + ], + "start": "08:30", + "end": "11:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "lab", + "is_general": false, + "section_id": "C", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-L01", + "room_name": "Computer Lab 1", + "batch_codes": [ + "26021519" + ] + }, + { + "day": "Wednesday", + "slot_indices": [ + 4, + 5 + ], + "start": "13:30", + "end": "16:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "lab", + "is_general": false, + "section_id": "C", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-L01", + "room_name": "Computer Lab 1", + "batch_codes": [ + "26021519" + ] + }, + { + "day": "Wednesday", + "slot_indices": [ + 4, + 5 + ], + "start": "13:30", + "end": "16:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "lab", + "is_general": false, + "section_id": "D", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-L02", + "room_name": "Computer Lab 2", + "batch_codes": [ + "26021520" + ] + }, + { + "day": "Wednesday", + "slot_indices": [ + 0, + 1 + ], + "start": "08:30", + "end": "11:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "lab", + "is_general": false, + "section_id": "D", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-L02", + "room_name": "Computer Lab 2", + "batch_codes": [ + "26021520" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 0, + 1 + ], + "start": "08:30", + "end": "11:30", + "course_id": "EE101", + "course_name": "Basic Electronics", + "course_type": "lab", + "is_general": false, + "section_id": "B", + "instructor_code": "1004", + "instructor_name": "Dr. Farah Iqbal", + "room_id": "A-L02", + "room_name": "Computer Lab 2", + "batch_codes": [ + "26031519" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "A", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "25021519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 4 + ], + "start": "13:30", + "end": "15:00", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "A", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "25021519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 5 + ], + "start": "15:00", + "end": "16:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "A", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "25021519" + ] + }, + { + "day": "Wednesday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "A", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "25021519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 5 + ], + "start": "15:00", + "end": "16:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "B", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "25021520" + ] + }, + { + "day": "Wednesday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "B", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "25021520" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "B", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "25021520" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 0 + ], + "start": "08:30", + "end": "10:00", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "B", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "25021520" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 0 + ], + "start": "08:30", + "end": "10:00", + "course_id": "EE101", + "course_name": "Basic Electronics", + "course_type": "theory", + "is_general": false, + "section_id": "A", + "instructor_code": "1004", + "instructor_name": "Dr. Farah Iqbal", + "room_id": "A-201", + "room_name": "Room 201", + "batch_codes": [ + "25031519" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 1 + ], + "start": "10:00", + "end": "11:30", + "course_id": "EE101", + "course_name": "Basic Electronics", + "course_type": "theory", + "is_general": false, + "section_id": "A", + "instructor_code": "1004", + "instructor_name": "Dr. Farah Iqbal", + "room_id": "A-201", + "room_name": "Room 201", + "batch_codes": [ + "25031519" + ] + }, + { + "day": "Tuesday", + "slot_indices": [ + 1 + ], + "start": "10:00", + "end": "11:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "C", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "26021519" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 0 + ], + "start": "08:30", + "end": "10:00", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "C", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "26021519" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 1 + ], + "start": "10:00", + "end": "11:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "C", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "26021519" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "C", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "26021519" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 1 + ], + "start": "10:00", + "end": "11:30", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "D", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "26021520" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "CS101", + "course_name": "Programming Fundamentals", + "course_type": "theory", + "is_general": false, + "section_id": "D", + "instructor_code": "1001", + "instructor_name": "Dr. Ahsan Raza", + "room_id": "A-101", + "room_name": "Room 101", + "batch_codes": [ + "26021520" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 4 + ], + "start": "13:30", + "end": "15:00", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "D", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "26021520" + ] + }, + { + "day": "Thursday", + "slot_indices": [ + 5 + ], + "start": "15:00", + "end": "16:30", + "course_id": "CS201", + "course_name": "Data Structures", + "course_type": "theory", + "is_general": false, + "section_id": "D", + "instructor_code": "1002", + "instructor_name": "Ms. Sana Tariq", + "room_id": "A-102", + "room_name": "Room 102", + "batch_codes": [ + "26021520" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 2 + ], + "start": "11:30", + "end": "13:00", + "course_id": "EE101", + "course_name": "Basic Electronics", + "course_type": "theory", + "is_general": false, + "section_id": "B", + "instructor_code": "1004", + "instructor_name": "Dr. Farah Iqbal", + "room_id": "A-201", + "room_name": "Room 201", + "batch_codes": [ + "26031519" + ] + }, + { + "day": "Monday", + "slot_indices": [ + 4 + ], + "start": "13:30", + "end": "15:00", + "course_id": "EE101", + "course_name": "Basic Electronics", + "course_type": "theory", + "is_general": false, + "section_id": "B", + "instructor_code": "1004", + "instructor_name": "Dr. Farah Iqbal", + "room_id": "A-201", + "room_name": "Room 201", + "batch_codes": [ + "26031519" + ] + } + ], + "room_busy": { + "Tuesday|0": [ + "A-101", + "A-103" + ], + "Tuesday|1": [ + "A-101", + "A-103" + ], + "Tuesday|2": [ + "A-101", + "A-103" + ], + "Tuesday|4": [ + "A-101", + "A-103", + "A-L02" + ], + "Monday|0": [ + "A-201", + "A-L01", + "A-L02" + ], + "Monday|1": [ + "A-201", + "A-L01", + "A-L02" + ], + "Monday|4": [ + "A-201", + "A-L01", + "A-L02" + ], + "Monday|5": [ + "A-L01", + "A-L02" + ], + "Tuesday|5": [ + "A-101", + "A-102", + "A-L02" + ], + "Wednesday|0": [ + "A-L01", + "A-L02" + ], + "Wednesday|1": [ + "A-L01", + "A-L02" + ], + "Wednesday|4": [ + "A-L01", + "A-L02" + ], + "Wednesday|5": [ + "A-L01", + "A-L02" + ], + "Thursday|0": [ + "A-101", + "A-102", + "A-L02" + ], + "Thursday|1": [ + "A-101", + "A-102", + "A-L02" + ], + "Monday|2": [ + "A-101", + "A-102", + "A-201" + ], + "Wednesday|2": [ + "A-101", + "A-102" + ], + "Thursday|2": [ + "A-101", + "A-102" + ], + "Thursday|4": [ + "A-102" + ], + "Thursday|5": [ + "A-102" + ] + }, + "instructor_busy": { + "Tuesday|0": [ + "1002", + "1006" + ], + "Tuesday|1": [ + "1001", + "1002" + ], + "Tuesday|2": [ + "1002", + "1006" + ], + "Tuesday|4": [ + "1001", + "1002", + "1004" + ], + "Monday|0": [ + "1001", + "1002", + "1004" + ], + "Monday|1": [ + "1001", + "1002", + "1004" + ], + "Monday|4": [ + "1001", + "1002", + "1004" + ], + "Monday|5": [ + "1001", + "1002" + ], + "Tuesday|5": [ + "1001", + "1002", + "1004" + ], + "Wednesday|0": [ + "1001", + "1002" + ], + "Wednesday|1": [ + "1001", + "1002" + ], + "Wednesday|4": [ + "1001", + "1002" + ], + "Wednesday|5": [ + "1001", + "1002" + ], + "Thursday|0": [ + "1001", + "1002", + "1004" + ], + "Thursday|1": [ + "1001", + "1002", + "1004" + ], + "Monday|2": [ + "1001", + "1002", + "1004" + ], + "Wednesday|2": [ + "1001", + "1002" + ], + "Thursday|2": [ + "1001", + "1002" + ], + "Thursday|4": [ + "1002" + ], + "Thursday|5": [ + "1002" + ] + }, + "batch_busy": { + "Tuesday|0": [ + "25021519", + "25021520", + "25031519", + "26021519", + "26021520", + "26031519" + ], + "Tuesday|1": [ + "25021519", + "25021520", + "25031519", + "26021519" + ], + "Tuesday|2": [ + "25021519", + "25021520", + "25031519", + "26021519", + "26021520", + "26031519" + ], + "Tuesday|4": [ + "25021519", + "25031519", + "26021519", + "26021520", + "26031519" + ], + "Monday|0": [ + "25021519", + "25021520", + "25031519" + ], + "Monday|1": [ + "25021519", + "25021520", + "25031519" + ], + "Monday|4": [ + "25021519", + "25021520", + "26031519" + ], + "Monday|5": [ + "25021519", + "25021520" + ], + "Tuesday|5": [ + "25021519", + "25021520", + "25031519" + ], + "Wednesday|0": [ + "26021519", + "26021520" + ], + "Wednesday|1": [ + "26021519", + "26021520" + ], + "Wednesday|4": [ + "26021519", + "26021520" + ], + "Wednesday|5": [ + "26021519", + "26021520" + ], + "Thursday|0": [ + "25021520", + "26021519", + "26031519" + ], + "Thursday|1": [ + "26021519", + "26021520", + "26031519" + ], + "Monday|2": [ + "25021519", + "25021520", + "26031519" + ], + "Wednesday|2": [ + "25021519", + "25021520" + ], + "Thursday|2": [ + "26021519", + "26021520" + ], + "Thursday|4": [ + "26021520" + ], + "Thursday|5": [ + "26021520" + ] + }, + "phases_completed": [ + "phase_1", + "phase_2", + "phase_3" + ] +} \ No newline at end of file diff --git a/result/templates/batch-wise/25021519.xlsx b/result/templates/batch-wise/25021519.xlsx index 1aab68b..64d5423 100644 Binary files a/result/templates/batch-wise/25021519.xlsx and b/result/templates/batch-wise/25021519.xlsx differ diff --git a/result/templates/batch-wise/25021520.xlsx b/result/templates/batch-wise/25021520.xlsx index b960112..9c3bde4 100644 Binary files a/result/templates/batch-wise/25021520.xlsx and b/result/templates/batch-wise/25021520.xlsx differ diff --git a/result/templates/batch-wise/25031519.xlsx b/result/templates/batch-wise/25031519.xlsx index 7a33756..71e28bd 100644 Binary files a/result/templates/batch-wise/25031519.xlsx and b/result/templates/batch-wise/25031519.xlsx differ diff --git a/result/templates/batch-wise/26021519.xlsx b/result/templates/batch-wise/26021519.xlsx index 7032096..a206491 100644 Binary files a/result/templates/batch-wise/26021519.xlsx and b/result/templates/batch-wise/26021519.xlsx differ diff --git a/result/templates/batch-wise/26021520.xlsx b/result/templates/batch-wise/26021520.xlsx index 817e717..e436db6 100644 Binary files a/result/templates/batch-wise/26021520.xlsx and b/result/templates/batch-wise/26021520.xlsx differ diff --git a/result/templates/batch-wise/26031519.xlsx b/result/templates/batch-wise/26031519.xlsx index fe90ad9..5e8acd1 100644 Binary files a/result/templates/batch-wise/26031519.xlsx and b/result/templates/batch-wise/26031519.xlsx differ diff --git a/result/templates/department-wise/CS.xlsx b/result/templates/department-wise/CS.xlsx index 0869396..013823a 100644 Binary files a/result/templates/department-wise/CS.xlsx and b/result/templates/department-wise/CS.xlsx differ diff --git a/result/templates/department-wise/EE.xlsx b/result/templates/department-wise/EE.xlsx index 74c9401..527c657 100644 Binary files a/result/templates/department-wise/EE.xlsx and b/result/templates/department-wise/EE.xlsx differ diff --git a/result/templates/room-wise/A-101.xlsx b/result/templates/room-wise/A-101.xlsx index 31d5882..bd3dd29 100644 Binary files a/result/templates/room-wise/A-101.xlsx and b/result/templates/room-wise/A-101.xlsx differ diff --git a/result/templates/room-wise/A-102.xlsx b/result/templates/room-wise/A-102.xlsx index f4619ad..27e89c8 100644 Binary files a/result/templates/room-wise/A-102.xlsx and b/result/templates/room-wise/A-102.xlsx differ diff --git a/result/templates/room-wise/A-103.xlsx b/result/templates/room-wise/A-103.xlsx index 3f0a0b2..a509365 100644 Binary files a/result/templates/room-wise/A-103.xlsx and b/result/templates/room-wise/A-103.xlsx differ diff --git a/result/templates/room-wise/A-201.xlsx b/result/templates/room-wise/A-201.xlsx index e9fad0e..a84f004 100644 Binary files a/result/templates/room-wise/A-201.xlsx and b/result/templates/room-wise/A-201.xlsx differ diff --git a/result/templates/room-wise/A-L01.xlsx b/result/templates/room-wise/A-L01.xlsx index e229615..137c1e9 100644 Binary files a/result/templates/room-wise/A-L01.xlsx and b/result/templates/room-wise/A-L01.xlsx differ diff --git a/result/templates/room-wise/A-L02.xlsx b/result/templates/room-wise/A-L02.xlsx index 5a3701b..727c1cb 100644 Binary files a/result/templates/room-wise/A-L02.xlsx and b/result/templates/room-wise/A-L02.xlsx differ diff --git a/result/templates/student-wise/25021519-001.xlsx b/result/templates/student-wise/25021519-001.xlsx index 6455807..0a711f5 100644 Binary files a/result/templates/student-wise/25021519-001.xlsx and b/result/templates/student-wise/25021519-001.xlsx differ diff --git a/result/templates/student-wise/25021519-002.xlsx b/result/templates/student-wise/25021519-002.xlsx index b453900..5741e98 100644 Binary files a/result/templates/student-wise/25021519-002.xlsx and b/result/templates/student-wise/25021519-002.xlsx differ diff --git a/result/templates/student-wise/25021519-003.xlsx b/result/templates/student-wise/25021519-003.xlsx index f8419cc..4b07131 100644 Binary files a/result/templates/student-wise/25021519-003.xlsx and b/result/templates/student-wise/25021519-003.xlsx differ diff --git a/result/templates/student-wise/25021519-004.xlsx b/result/templates/student-wise/25021519-004.xlsx index f11bd6b..1c78358 100644 Binary files a/result/templates/student-wise/25021519-004.xlsx and b/result/templates/student-wise/25021519-004.xlsx differ diff --git a/result/templates/student-wise/25021519-005.xlsx b/result/templates/student-wise/25021519-005.xlsx index c6e0cbd..d56ffee 100644 Binary files a/result/templates/student-wise/25021519-005.xlsx and b/result/templates/student-wise/25021519-005.xlsx differ diff --git a/result/templates/student-wise/25021520-001.xlsx b/result/templates/student-wise/25021520-001.xlsx index f182249..a597e90 100644 Binary files a/result/templates/student-wise/25021520-001.xlsx and b/result/templates/student-wise/25021520-001.xlsx differ diff --git a/result/templates/student-wise/25021520-002.xlsx b/result/templates/student-wise/25021520-002.xlsx index a023d40..e28fe70 100644 Binary files a/result/templates/student-wise/25021520-002.xlsx and b/result/templates/student-wise/25021520-002.xlsx differ diff --git a/result/templates/student-wise/25021520-003.xlsx b/result/templates/student-wise/25021520-003.xlsx index 9a7cc77..5f2ec71 100644 Binary files a/result/templates/student-wise/25021520-003.xlsx and b/result/templates/student-wise/25021520-003.xlsx differ diff --git a/result/templates/student-wise/25021520-004.xlsx b/result/templates/student-wise/25021520-004.xlsx index 7da0b7f..bb88976 100644 Binary files a/result/templates/student-wise/25021520-004.xlsx and b/result/templates/student-wise/25021520-004.xlsx differ diff --git a/result/templates/student-wise/25021520-005.xlsx b/result/templates/student-wise/25021520-005.xlsx index 49278a0..8f662b4 100644 Binary files a/result/templates/student-wise/25021520-005.xlsx and b/result/templates/student-wise/25021520-005.xlsx differ diff --git a/result/templates/student-wise/25031519-001.xlsx b/result/templates/student-wise/25031519-001.xlsx index c8c30ea..b6acb66 100644 Binary files a/result/templates/student-wise/25031519-001.xlsx and b/result/templates/student-wise/25031519-001.xlsx differ diff --git a/result/templates/student-wise/25031519-002.xlsx b/result/templates/student-wise/25031519-002.xlsx index ba3b781..7717029 100644 Binary files a/result/templates/student-wise/25031519-002.xlsx and b/result/templates/student-wise/25031519-002.xlsx differ diff --git a/result/templates/student-wise/25031519-003.xlsx b/result/templates/student-wise/25031519-003.xlsx index eb1dd96..9404666 100644 Binary files a/result/templates/student-wise/25031519-003.xlsx and b/result/templates/student-wise/25031519-003.xlsx differ diff --git a/result/templates/student-wise/25031519-004.xlsx b/result/templates/student-wise/25031519-004.xlsx index 54ae605..5d4e86d 100644 Binary files a/result/templates/student-wise/25031519-004.xlsx and b/result/templates/student-wise/25031519-004.xlsx differ diff --git a/result/templates/student-wise/25031519-005.xlsx b/result/templates/student-wise/25031519-005.xlsx index d390205..15de308 100644 Binary files a/result/templates/student-wise/25031519-005.xlsx and b/result/templates/student-wise/25031519-005.xlsx differ diff --git a/result/templates/student-wise/26021519-001.xlsx b/result/templates/student-wise/26021519-001.xlsx index 5cb4ae2..f2c1ae9 100644 Binary files a/result/templates/student-wise/26021519-001.xlsx and b/result/templates/student-wise/26021519-001.xlsx differ diff --git a/result/templates/student-wise/26021519-002.xlsx b/result/templates/student-wise/26021519-002.xlsx index d2d0c85..b3f1400 100644 Binary files a/result/templates/student-wise/26021519-002.xlsx and b/result/templates/student-wise/26021519-002.xlsx differ diff --git a/result/templates/student-wise/26021519-003.xlsx b/result/templates/student-wise/26021519-003.xlsx index bc1d8bc..849c505 100644 Binary files a/result/templates/student-wise/26021519-003.xlsx and b/result/templates/student-wise/26021519-003.xlsx differ diff --git a/result/templates/student-wise/26021519-004.xlsx b/result/templates/student-wise/26021519-004.xlsx index 2184a3a..b16e05b 100644 Binary files a/result/templates/student-wise/26021519-004.xlsx and b/result/templates/student-wise/26021519-004.xlsx differ diff --git a/result/templates/student-wise/26021519-005.xlsx b/result/templates/student-wise/26021519-005.xlsx index 68c58fa..df29b0a 100644 Binary files a/result/templates/student-wise/26021519-005.xlsx and b/result/templates/student-wise/26021519-005.xlsx differ diff --git a/result/templates/student-wise/26021520-001.xlsx b/result/templates/student-wise/26021520-001.xlsx index 8cd0662..95cedd9 100644 Binary files a/result/templates/student-wise/26021520-001.xlsx and b/result/templates/student-wise/26021520-001.xlsx differ diff --git a/result/templates/student-wise/26021520-002.xlsx b/result/templates/student-wise/26021520-002.xlsx index 14bf818..d679f75 100644 Binary files a/result/templates/student-wise/26021520-002.xlsx and b/result/templates/student-wise/26021520-002.xlsx differ diff --git a/result/templates/student-wise/26021520-003.xlsx b/result/templates/student-wise/26021520-003.xlsx index d449b42..0ad2f8e 100644 Binary files a/result/templates/student-wise/26021520-003.xlsx and b/result/templates/student-wise/26021520-003.xlsx differ diff --git a/result/templates/student-wise/26021520-004.xlsx b/result/templates/student-wise/26021520-004.xlsx index e7c4499..ddafb1c 100644 Binary files a/result/templates/student-wise/26021520-004.xlsx and b/result/templates/student-wise/26021520-004.xlsx differ diff --git a/result/templates/student-wise/26021520-005.xlsx b/result/templates/student-wise/26021520-005.xlsx index 74ac343..5ab8794 100644 Binary files a/result/templates/student-wise/26021520-005.xlsx and b/result/templates/student-wise/26021520-005.xlsx differ diff --git a/result/templates/student-wise/26031519-001.xlsx b/result/templates/student-wise/26031519-001.xlsx index 9d6ebba..bdf79f1 100644 Binary files a/result/templates/student-wise/26031519-001.xlsx and b/result/templates/student-wise/26031519-001.xlsx differ diff --git a/result/templates/student-wise/26031519-002.xlsx b/result/templates/student-wise/26031519-002.xlsx index a0dbe46..74f0b80 100644 Binary files a/result/templates/student-wise/26031519-002.xlsx and b/result/templates/student-wise/26031519-002.xlsx differ diff --git a/result/templates/student-wise/26031519-003.xlsx b/result/templates/student-wise/26031519-003.xlsx index d05ddce..da1beea 100644 Binary files a/result/templates/student-wise/26031519-003.xlsx and b/result/templates/student-wise/26031519-003.xlsx differ diff --git a/result/templates/student-wise/26031519-004.xlsx b/result/templates/student-wise/26031519-004.xlsx index 869988a..07e9230 100644 Binary files a/result/templates/student-wise/26031519-004.xlsx and b/result/templates/student-wise/26031519-004.xlsx differ diff --git a/result/templates/student-wise/26031519-005.xlsx b/result/templates/student-wise/26031519-005.xlsx index 3023bd4..4becbc5 100644 Binary files a/result/templates/student-wise/26031519-005.xlsx and b/result/templates/student-wise/26031519-005.xlsx differ diff --git a/result/templates/teacher-wise/1001.xlsx b/result/templates/teacher-wise/1001.xlsx index 537f63d..fd6e59b 100644 Binary files a/result/templates/teacher-wise/1001.xlsx and b/result/templates/teacher-wise/1001.xlsx differ diff --git a/result/templates/teacher-wise/1002.xlsx b/result/templates/teacher-wise/1002.xlsx index bbe35ed..fe7769b 100644 Binary files a/result/templates/teacher-wise/1002.xlsx and b/result/templates/teacher-wise/1002.xlsx differ diff --git a/result/templates/teacher-wise/1004.xlsx b/result/templates/teacher-wise/1004.xlsx index baa7f58..b0e20b7 100644 Binary files a/result/templates/teacher-wise/1004.xlsx and b/result/templates/teacher-wise/1004.xlsx differ diff --git a/result/templates/teacher-wise/1006.xlsx b/result/templates/teacher-wise/1006.xlsx index 13d9836..0c7a431 100644 Binary files a/result/templates/teacher-wise/1006.xlsx and b/result/templates/teacher-wise/1006.xlsx differ