more complex

This commit is contained in:
Talhadeveloperr
2026-09-09 18:29:08 +05:00
parent 0f1e3adbb1
commit 868bcbe175
266 changed files with 2825 additions and 137 deletions

View File

@@ -8,7 +8,7 @@ sys.path.insert(0, os.path.join(_ROOT, "app"))
sys.path.insert(0, os.path.join(_ROOT, "controller"))
from xlsx_grid_helper import build_grid_sheet, new_workbook, save_workbook # noqa: E402
from template_controller import TIME_SLOTS as GRID_TIME_SLOTS # noqa: E402
from template_controller import DISPLAY_ROWS # noqa: E402
def _sessions_for_batch(sessions, batch_code):
@@ -28,10 +28,10 @@ def generate_batch_wise_templates(sessions, data, output_dir):
by_day_slot = {}
for s in batch_sessions:
for slot_index in s["slot_indices"]:
by_day_slot.setdefault((s["day"], slot_index), []).append(s)
by_day_slot.setdefault((s["day"], slot_index, s["duration_minutes"]), []).append(s)
def cell_text(day, slot_index, by_day_slot=by_day_slot):
entries = by_day_slot.get((day, slot_index))
def cell_text(day, slot_index, duration_minutes, by_day_slot=by_day_slot):
entries = by_day_slot.get((day, slot_index, duration_minutes))
if not entries:
return ""
lines = []
@@ -49,8 +49,8 @@ def generate_batch_wise_templates(sessions, data, output_dir):
ws,
title=f"Batch {batch_code}",
subtitle=subtitle,
time_slots=GRID_TIME_SLOTS,
sessions_by_day_slot=first_by_day_slot,
display_rows=DISPLAY_ROWS,
sessions_by_cell=first_by_day_slot,
cell_text_fn=cell_text,
)
path = save_workbook(wb, output_dir, f"{batch_code}.xlsx")

View File

@@ -8,7 +8,7 @@ sys.path.insert(0, os.path.join(_ROOT, "app"))
sys.path.insert(0, os.path.join(_ROOT, "controller"))
from xlsx_grid_helper import build_grid_sheet, new_workbook, save_workbook # noqa: E402
from template_controller import TIME_SLOTS as GRID_TIME_SLOTS # noqa: E402
from template_controller import DISPLAY_ROWS # noqa: E402
def generate_department_wise_templates(sessions, data, output_dir):
@@ -22,10 +22,10 @@ def generate_department_wise_templates(sessions, data, output_dir):
by_day_slot = {}
for s in dept_sessions:
for slot_index in s["slot_indices"]:
by_day_slot.setdefault((s["day"], slot_index), []).append(s)
by_day_slot.setdefault((s["day"], slot_index, s["duration_minutes"]), []).append(s)
def cell_text(day, slot_index, by_day_slot=by_day_slot):
entries = by_day_slot.get((day, slot_index))
def cell_text(day, slot_index, duration_minutes, by_day_slot=by_day_slot):
entries = by_day_slot.get((day, slot_index, duration_minutes))
if not entries:
return ""
lines = []
@@ -44,8 +44,8 @@ def generate_department_wise_templates(sessions, data, output_dir):
ws,
title=f"Department: {department}",
subtitle="All batches / programs",
time_slots=GRID_TIME_SLOTS,
sessions_by_day_slot=first_by_day_slot,
display_rows=DISPLAY_ROWS,
sessions_by_cell=first_by_day_slot,
cell_text_fn=cell_text,
)
path = save_workbook(wb, output_dir, f"{department}.xlsx")

View File

@@ -8,7 +8,7 @@ sys.path.insert(0, os.path.join(_ROOT, "app"))
sys.path.insert(0, os.path.join(_ROOT, "controller"))
from xlsx_grid_helper import build_grid_sheet, new_workbook, save_workbook # noqa: E402
from template_controller import TIME_SLOTS as GRID_TIME_SLOTS # noqa: E402
from template_controller import DISPLAY_ROWS # noqa: E402
def generate_room_wise_templates(sessions, data, output_dir):
@@ -23,10 +23,10 @@ def generate_room_wise_templates(sessions, data, output_dir):
by_day_slot = {}
for s in room_sessions:
for slot_index in s["slot_indices"]:
by_day_slot.setdefault((s["day"], slot_index), []).append(s)
by_day_slot.setdefault((s["day"], slot_index, s["duration_minutes"]), []).append(s)
def cell_text(day, slot_index, by_day_slot=by_day_slot):
entries = by_day_slot.get((day, slot_index))
def cell_text(day, slot_index, duration_minutes, by_day_slot=by_day_slot):
entries = by_day_slot.get((day, slot_index, duration_minutes))
if not entries:
return ""
lines = []
@@ -44,8 +44,8 @@ def generate_room_wise_templates(sessions, data, output_dir):
ws,
title=f'{room["room_name"]} ({room_id})',
subtitle=f'Block {room["block_id"]} - {room["room_type"].title()} - Capacity {room["capacity"]}',
time_slots=GRID_TIME_SLOTS,
sessions_by_day_slot=first_by_day_slot,
display_rows=DISPLAY_ROWS,
sessions_by_cell=first_by_day_slot,
cell_text_fn=cell_text,
)
path = save_workbook(wb, output_dir, f"{room_id}.xlsx")

View File

@@ -8,7 +8,7 @@ sys.path.insert(0, os.path.join(_ROOT, "app"))
sys.path.insert(0, os.path.join(_ROOT, "controller"))
from xlsx_grid_helper import build_grid_sheet, new_workbook, save_workbook # noqa: E402
from template_controller import TIME_SLOTS as GRID_TIME_SLOTS # noqa: E402
from template_controller import DISPLAY_ROWS # noqa: E402
from template_logger import log_error # noqa: E402
@@ -24,17 +24,17 @@ def generate_student_wise_templates(sessions, data, output_dir):
batch = data["batches_by_code"].get(batch_code)
student_sessions = _sessions_for_batch(sessions, batch_code)
# A student can only be in one place at a time: each (day, slot)
# must resolve to exactly one session. If the schedule places more
# than one, that's a real scheduling error - log it instead of
# silently picking/overwriting one.
# A student can only be in one place at a time: each (day, slot,
# duration) must resolve to exactly one session. If the schedule
# places more than one, that's a real scheduling error - log it
# instead of silently picking/overwriting one.
raw_by_day_slot = {}
for s in student_sessions:
for slot_index in s["slot_indices"]:
raw_by_day_slot.setdefault((s["day"], slot_index), []).append(s)
raw_by_day_slot.setdefault((s["day"], slot_index, s["duration_minutes"]), []).append(s)
by_day_slot = {}
for (day, slot_index), entries in raw_by_day_slot.items():
for (day, slot_index, duration_minutes), entries in raw_by_day_slot.items():
if len(entries) > 1:
course_list = ", ".join(
f'{e["course_id"]} Sec {e["section_id"]} ({e["course_type"]}) with {e["instructor_name"]} in {e["room_id"]}'
@@ -44,10 +44,10 @@ def generate_student_wise_templates(sessions, data, output_dir):
f"Student conflict: roll {roll_no} (batch {batch_code}) has "
f"{len(entries)} overlapping courses on {day} slot {slot_index}: {course_list}"
)
by_day_slot[(day, slot_index)] = entries[0]
by_day_slot[(day, slot_index, duration_minutes)] = entries[0]
def cell_text(day, slot_index, raw_by_day_slot=raw_by_day_slot):
entries = raw_by_day_slot.get((day, slot_index))
def cell_text(day, slot_index, duration_minutes, raw_by_day_slot=raw_by_day_slot):
entries = raw_by_day_slot.get((day, slot_index, duration_minutes))
if not entries:
return ""
s = entries[0]
@@ -67,8 +67,8 @@ def generate_student_wise_templates(sessions, data, output_dir):
ws,
title=f"Roll No: {roll_no}",
subtitle=subtitle,
time_slots=GRID_TIME_SLOTS,
sessions_by_day_slot=by_day_slot,
display_rows=DISPLAY_ROWS,
sessions_by_cell=by_day_slot,
cell_text_fn=cell_text,
)
path = save_workbook(wb, output_dir, f"{roll_no}.xlsx")

View File

@@ -8,7 +8,7 @@ sys.path.insert(0, os.path.join(_ROOT, "app"))
sys.path.insert(0, os.path.join(_ROOT, "controller"))
from xlsx_grid_helper import build_grid_sheet, new_workbook, save_workbook # noqa: E402
from template_controller import TIME_SLOTS as GRID_TIME_SLOTS # noqa: E402
from template_controller import DISPLAY_ROWS # noqa: E402
from template_logger import log_error # noqa: E402
@@ -33,17 +33,17 @@ def generate_teacher_wise_templates(sessions, data, output_dir):
instructor_name = name_by_code[code]
instr_sessions = [s for s in sessions if s["instructor_code"] == code]
# A teacher can only be in one place at a time: each (day, slot)
# must resolve to exactly one session. If the schedule places more
# than one, that's a real scheduling error - log it instead of
# silently picking/overwriting one.
# A teacher can only be in one place at a time: each (day, slot,
# duration) must resolve to exactly one session. If the schedule
# places more than one, that's a real scheduling error - log it
# instead of silently picking/overwriting one.
raw_by_day_slot = {}
for s in instr_sessions:
for slot_index in s["slot_indices"]:
raw_by_day_slot.setdefault((s["day"], slot_index), []).append(s)
raw_by_day_slot.setdefault((s["day"], slot_index, s["duration_minutes"]), []).append(s)
by_day_slot = {}
for (day, slot_index), entries in raw_by_day_slot.items():
for (day, slot_index, duration_minutes), entries in raw_by_day_slot.items():
if len(entries) > 1:
course_list = ", ".join(
f'{e["course_id"]} ({e["course_type"]}) for batch(es) {"+".join(e["batch_codes"])} in {e["room_id"]}'
@@ -53,10 +53,10 @@ def generate_teacher_wise_templates(sessions, data, output_dir):
f"Teacher conflict: {instructor_name} ({code}) is double-booked on "
f"{day} slot {slot_index}: {course_list}"
)
by_day_slot[(day, slot_index)] = entries[0]
by_day_slot[(day, slot_index, duration_minutes)] = entries[0]
def cell_text(day, slot_index, raw_by_day_slot=raw_by_day_slot):
entries = raw_by_day_slot.get((day, slot_index))
def cell_text(day, slot_index, duration_minutes, raw_by_day_slot=raw_by_day_slot):
entries = raw_by_day_slot.get((day, slot_index, duration_minutes))
if not entries:
return ""
s = entries[0]
@@ -75,8 +75,8 @@ def generate_teacher_wise_templates(sessions, data, output_dir):
ws,
title=f'{instructor_name} ({code})',
subtitle=subtitle,
time_slots=GRID_TIME_SLOTS,
sessions_by_day_slot=by_day_slot,
display_rows=DISPLAY_ROWS,
sessions_by_cell=by_day_slot,
cell_text_fn=cell_text,
)
path = save_workbook(wb, output_dir, f"{code}.xlsx")