more complex
This commit is contained in:
@@ -14,10 +14,10 @@ DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
|
||||
|
||||
HEADER_FILL = PatternFill(start_color="1F4E78", end_color="1F4E78", fill_type="solid")
|
||||
HEADER_FONT = Font(color="FFFFFF", bold=True)
|
||||
LUNCH_FILL = PatternFill(start_color="D9D9D9", end_color="D9D9D9", fill_type="solid")
|
||||
GENERAL_FILL = PatternFill(start_color="FFF2CC", end_color="FFF2CC", fill_type="solid")
|
||||
LAB_FILL = PatternFill(start_color="D9EAD3", end_color="D9EAD3", fill_type="solid")
|
||||
THEORY_FILL = PatternFill(start_color="DDEBF7", end_color="DDEBF7", fill_type="solid")
|
||||
LONG_LECTURE_FILL = PatternFill(start_color="F4CCCC", end_color="F4CCCC", fill_type="solid")
|
||||
THIN_BORDER = Border(
|
||||
left=Side(style="thin"), right=Side(style="thin"),
|
||||
top=Side(style="thin"), bottom=Side(style="thin"),
|
||||
@@ -28,6 +28,8 @@ CENTER = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
def cell_fill_for(session):
|
||||
if session is None:
|
||||
return None
|
||||
if session.get("duration_minutes") == 120:
|
||||
return LONG_LECTURE_FILL
|
||||
if session.get("is_general"):
|
||||
return GENERAL_FILL
|
||||
if session.get("course_type") == "lab":
|
||||
@@ -35,16 +37,21 @@ def cell_fill_for(session):
|
||||
return THEORY_FILL
|
||||
|
||||
|
||||
def build_grid_sheet(ws, title, subtitle, time_slots, sessions_by_day_slot, cell_text_fn):
|
||||
def build_grid_sheet(ws, title, subtitle, display_rows, sessions_by_cell, cell_text_fn):
|
||||
"""
|
||||
Renders one timetable grid onto worksheet `ws`.
|
||||
|
||||
time_slots: ordered list of dicts: {"label": str, "start": str, "end": str,
|
||||
"is_lunch": bool}
|
||||
sessions_by_day_slot: dict[(day, slot_index)] -> session dict (or list of
|
||||
session dicts for slots spanning a double/lab period), used
|
||||
only to decide fill color via cell_fill_for().
|
||||
cell_text_fn: function(day, slot_index) -> str to render into the cell.
|
||||
display_rows: ordered list of dicts, one per rendered row:
|
||||
{"label": str, "start": str, "end": str,
|
||||
"slot_index": int, "duration_minutes": int}
|
||||
The special 08:30-10:30 long-lecture row and the normal
|
||||
09:00-10:30 row both use slot_index 0 (they clash-track
|
||||
against the same slot) but are distinguished by
|
||||
duration_minutes (120 vs 90) so they render as separate rows.
|
||||
sessions_by_cell: dict[(day, slot_index, duration_minutes)] -> session
|
||||
dict, used only to decide fill color via cell_fill_for().
|
||||
cell_text_fn: function(day, slot_index, duration_minutes) -> str to
|
||||
render into the cell.
|
||||
"""
|
||||
invalid_chars = ':\\/?*[]'
|
||||
sheet_name = "".join(c for c in title if c not in invalid_chars)
|
||||
@@ -74,14 +81,12 @@ def build_grid_sheet(ws, title, subtitle, time_slots, sessions_by_day_slot, cell
|
||||
c.alignment = CENTER
|
||||
c.border = THIN_BORDER
|
||||
|
||||
for row_offset, slot in enumerate(time_slots):
|
||||
for row_offset, slot in enumerate(display_rows):
|
||||
row = header_row + 1 + row_offset
|
||||
time_cell = ws.cell(row=row, column=1, value=f'{slot["start"]} - {slot["end"]}')
|
||||
time_cell.font = Font(bold=True, size=9)
|
||||
time_cell.alignment = CENTER
|
||||
time_cell.border = THIN_BORDER
|
||||
if slot.get("is_lunch"):
|
||||
time_cell.fill = LUNCH_FILL
|
||||
|
||||
for col, day in enumerate(DAYS, start=2):
|
||||
cell = ws.cell(row=row, column=col)
|
||||
@@ -89,15 +94,10 @@ def build_grid_sheet(ws, title, subtitle, time_slots, sessions_by_day_slot, cell
|
||||
cell.alignment = CENTER
|
||||
cell.font = Font(size=9)
|
||||
|
||||
if slot.get("is_lunch"):
|
||||
cell.fill = LUNCH_FILL
|
||||
cell.value = "LUNCH BREAK"
|
||||
continue
|
||||
|
||||
text = cell_text_fn(day, row_offset)
|
||||
text = cell_text_fn(day, slot["slot_index"], slot["duration_minutes"])
|
||||
cell.value = text if text else ""
|
||||
|
||||
session = sessions_by_day_slot.get((day, row_offset))
|
||||
session = sessions_by_cell.get((day, slot["slot_index"], slot["duration_minutes"]))
|
||||
fill = cell_fill_for(session)
|
||||
if fill:
|
||||
cell.fill = fill
|
||||
@@ -106,7 +106,7 @@ def build_grid_sheet(ws, title, subtitle, time_slots, sessions_by_day_slot, cell
|
||||
for col in range(2, 2 + len(DAYS)):
|
||||
ws.column_dimensions[get_column_letter(col)].width = 26
|
||||
|
||||
for row_offset in range(len(time_slots)):
|
||||
for row_offset in range(len(display_rows)):
|
||||
ws.row_dimensions[header_row + 1 + row_offset].height = 42
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,12 @@ earlier phase, later phases can never reuse it.
|
||||
sorted batch_code order: for each batch, every one of its remaining
|
||||
offerings is placed and locked before the next batch is considered.
|
||||
|
||||
Time grid: 5 normal 90-minute slots, 09:00-16:30, no lunch break. Labs use
|
||||
180-minute double-slots (09:00-12:00 and 12:00-15:00). A course whose
|
||||
lecture_duration_minutes is 120 ("2 hours once a week") is instead placed
|
||||
in a special fixed 08:30-10:30 slot, which overlaps normal slot 0
|
||||
(09:00-10:30) in wall-clock time and is tracked as clashing with it.
|
||||
|
||||
Room selection always tries a course's preferred lecture_room_id /
|
||||
lab_room_id first, falling back to another same-type room only if the
|
||||
preferred one is busy for that day/slot.
|
||||
@@ -32,24 +38,49 @@ DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__
|
||||
|
||||
DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
|
||||
|
||||
# Theory grid: 5 x 90-minute slots with a lunch break, 08:30-16:30
|
||||
# Normal theory grid: 5 x 90-minute slots, 09:00-16:30, no lunch break.
|
||||
# Every placeable session (normal lecture, lab, or the special long
|
||||
# lecture) is expressed as one or more of these slot indices (0-4) for
|
||||
# clash-tracking purposes — see LONG_LECTURE_SLOT below for why the long
|
||||
# lecture also uses index 0 despite rendering at a different clock time.
|
||||
TIME_SLOTS = [
|
||||
{"label": "S1", "start": "08:30", "end": "10:00", "is_lunch": False},
|
||||
{"label": "S2", "start": "10:00", "end": "11:30", "is_lunch": False},
|
||||
{"label": "S3", "start": "11:30", "end": "13:00", "is_lunch": False},
|
||||
{"label": "LUNCH", "start": "13:00", "end": "13:30", "is_lunch": True},
|
||||
{"label": "S1", "start": "09:00", "end": "10:30", "is_lunch": False},
|
||||
{"label": "S2", "start": "10:30", "end": "12:00", "is_lunch": False},
|
||||
{"label": "S3", "start": "12:00", "end": "13:30", "is_lunch": False},
|
||||
{"label": "S4", "start": "13:30", "end": "15:00", "is_lunch": False},
|
||||
{"label": "S5", "start": "15:00", "end": "16:30", "is_lunch": False},
|
||||
]
|
||||
|
||||
# Indices into TIME_SLOTS that are real teaching slots (skip lunch)
|
||||
# Indices into TIME_SLOTS that are real teaching slots (no lunch to skip
|
||||
# anymore, but kept for readability at call sites)
|
||||
TEACHING_SLOT_INDICES = [i for i, s in enumerate(TIME_SLOTS) if not s["is_lunch"]]
|
||||
|
||||
# Consecutive pairs of teaching slots usable as a 180-minute lab double-slot
|
||||
LAB_SLOT_PAIRS = [
|
||||
(a, b)
|
||||
for a, b in zip(TEACHING_SLOT_INDICES, TEACHING_SLOT_INDICES[1:])
|
||||
if TIME_SLOTS[b]["start"] == TIME_SLOTS[a]["end"]
|
||||
# Consecutive pairs of normal slots usable as a 180-minute lab double-slot:
|
||||
# 09:00-12:00 (S1+S2) and 12:00-15:00 (S3+S4).
|
||||
LAB_SLOT_PAIRS = [(0, 1), (2, 3)]
|
||||
|
||||
# The special fixed slot for courses whose lecture is "2 hours once a
|
||||
# week": 08:30-10:30. This overlaps 09:00-10:30 (normal slot index 0) in
|
||||
# wall-clock time, so a long-lecture session is tracked as occupying slot
|
||||
# index 0 too (same key _is_free/_mark_busy use) — that's what makes it
|
||||
# correctly clash with anything else placed in normal slot 0 that day for
|
||||
# the same room/instructor/batch. duration_minutes on the session dict is
|
||||
# what distinguishes it from a normal 90-minute slot-0 session at render time.
|
||||
LONG_LECTURE_SLOT_INDEX = 0
|
||||
LONG_LECTURE_START = "08:30"
|
||||
LONG_LECTURE_END = "10:30"
|
||||
|
||||
# Rows to render on every generated timetable grid: the special long-lecture
|
||||
# row first (it starts earliest, 08:30), then the 5 normal 90-minute rows.
|
||||
# Templates/xlsx_grid_helper key session lookups on (day, slot_index,
|
||||
# duration_minutes) using these rows' slot_index/duration_minutes pairs.
|
||||
DISPLAY_ROWS = [
|
||||
{"label": "Long", "start": LONG_LECTURE_START, "end": LONG_LECTURE_END,
|
||||
"slot_index": LONG_LECTURE_SLOT_INDEX, "duration_minutes": 120},
|
||||
] + [
|
||||
{"label": s["label"], "start": s["start"], "end": s["end"],
|
||||
"slot_index": i, "duration_minutes": 90}
|
||||
for i, s in enumerate(TIME_SLOTS)
|
||||
]
|
||||
|
||||
|
||||
@@ -82,6 +113,7 @@ def load_data():
|
||||
c["lectures_per_week"] = int(c["lectures_per_week"])
|
||||
c["labs_per_week"] = int(c["labs_per_week"])
|
||||
c["is_general"] = c["is_general"].lower() == "yes"
|
||||
c["lecture_duration_minutes"] = int(c.get("lecture_duration_minutes") or 90)
|
||||
courses_by_id[c["course_id"]] = c
|
||||
|
||||
# normalize offerings: expand "batch1|batch2" section batch groups into
|
||||
@@ -183,16 +215,23 @@ class Scheduler:
|
||||
rest = [r for r in room_pool if r["room_id"] != preferred_room_id]
|
||||
return ([preferred] if preferred else []) + rest
|
||||
|
||||
def _add_session(self, offering, day, slot_indices, room):
|
||||
def _add_session(self, offering, day, slot_indices, room, is_long_lecture=False):
|
||||
course = offering["course"]
|
||||
start = TIME_SLOTS[slot_indices[0]]["start"]
|
||||
end = TIME_SLOTS[slot_indices[-1]]["end"]
|
||||
session_type = "lab" if len(slot_indices) > 1 else "theory"
|
||||
if is_long_lecture:
|
||||
start, end = LONG_LECTURE_START, LONG_LECTURE_END
|
||||
duration_minutes = 120
|
||||
session_type = "theory"
|
||||
else:
|
||||
start = TIME_SLOTS[slot_indices[0]]["start"]
|
||||
end = TIME_SLOTS[slot_indices[-1]]["end"]
|
||||
duration_minutes = 90 * len(slot_indices)
|
||||
session_type = "lab" if len(slot_indices) > 1 else "theory"
|
||||
session = {
|
||||
"day": day,
|
||||
"slot_indices": slot_indices,
|
||||
"start": start,
|
||||
"end": end,
|
||||
"duration_minutes": duration_minutes,
|
||||
"course_id": offering["course_id"],
|
||||
"course_name": course["course_name"],
|
||||
"course_type": session_type,
|
||||
@@ -208,7 +247,7 @@ class Scheduler:
|
||||
return session
|
||||
|
||||
def _place_theory_session(self, offering, room_candidates, day_order):
|
||||
"""Finds and locks a free single-slot session; returns the session dict or None."""
|
||||
"""Finds and locks a free normal 90-minute single-slot session; returns the session dict or None."""
|
||||
for day in day_order:
|
||||
for slot_index in TEACHING_SLOT_INDICES:
|
||||
for room in room_candidates:
|
||||
@@ -217,6 +256,26 @@ class Scheduler:
|
||||
return self._add_session(offering, day, [slot_index], room)
|
||||
return None
|
||||
|
||||
def _place_long_lecture(self, offering, room_candidates, day_order):
|
||||
"""
|
||||
Finds and locks a free 08:30-10:30 long-lecture session (for
|
||||
courses with lecture_duration_minutes=120). Occupies the same
|
||||
clash-tracking slot index as normal slot 0 since they overlap in
|
||||
wall-clock time (09:00-10:30). Returns the session dict or None.
|
||||
"""
|
||||
for day in day_order:
|
||||
for room in room_candidates:
|
||||
if self._is_free(day, LONG_LECTURE_SLOT_INDEX, room["room_id"], offering["instructor_code"], offering["batch_codes"]):
|
||||
self._mark_busy(day, LONG_LECTURE_SLOT_INDEX, room["room_id"], offering["instructor_code"], offering["batch_codes"])
|
||||
return self._add_session(offering, day, [LONG_LECTURE_SLOT_INDEX], room, is_long_lecture=True)
|
||||
return None
|
||||
|
||||
def _place_lecture(self, offering, room_candidates, day_order):
|
||||
"""Dispatches to the long (120-min) or normal (90-min) lecture placement based on the course's lecture_duration_minutes."""
|
||||
if offering["course"]["lecture_duration_minutes"] == 120:
|
||||
return self._place_long_lecture(offering, room_candidates, day_order)
|
||||
return self._place_theory_session(offering, room_candidates, day_order)
|
||||
|
||||
def phase_1_general_courses(self, preferred_days=("Tuesday", "Thursday"), max_repair_attempts=20):
|
||||
"""
|
||||
Places every general-course offering's weekly lectures, preferring
|
||||
@@ -233,7 +292,7 @@ class Scheduler:
|
||||
course = offering["course"]
|
||||
room_candidates = self._room_candidates(course["lecture_room_id"], self.classrooms)
|
||||
for _ in range(course["lectures_per_week"]):
|
||||
session = self._place_theory_session(offering, room_candidates, preferred_order)
|
||||
session = self._place_lecture(offering, room_candidates, preferred_order)
|
||||
if session is None:
|
||||
print(f"WARNING: could not place a lecture for general course {offering['course_id']} section {offering['section_id']}")
|
||||
|
||||
@@ -266,7 +325,7 @@ class Scheduler:
|
||||
phase_sessions.remove(losing_session)
|
||||
|
||||
room_candidates = self._room_candidates(offering["course"]["lecture_room_id"], self.classrooms)
|
||||
new_session = self._place_theory_session(offering, room_candidates, any_day_order)
|
||||
new_session = self._place_lecture(offering, room_candidates, any_day_order)
|
||||
if new_session is None:
|
||||
print(f"WARNING: could not repair general-course conflict for {offering['course_id']} section {offering['section_id']}")
|
||||
return
|
||||
@@ -326,7 +385,7 @@ class Scheduler:
|
||||
course = offering["course"]
|
||||
room_candidates = self._room_candidates(course["lecture_room_id"], self.classrooms)
|
||||
for _ in range(course["lectures_per_week"]):
|
||||
session = self._place_theory_session(offering, room_candidates, DAYS)
|
||||
session = self._place_lecture(offering, room_candidates, DAYS)
|
||||
if session is None:
|
||||
print(f"WARNING: could not place a lecture for course {offering['course_id']} section {offering['section_id']} ({offering['batch_codes']})")
|
||||
|
||||
|
||||
@@ -2,3 +2,6 @@ batch_code,department,program,session
|
||||
25021519,CS,BSCS,25
|
||||
25021520,CS,BSSE,25
|
||||
25031519,EE,BSEE,25
|
||||
25031520,EE,BSCE,25
|
||||
25041519,BBA,BBA,25
|
||||
25041520,BBA,BSAF,25
|
||||
|
||||
|
@@ -2,3 +2,6 @@ batch_code,department,program,session
|
||||
26021519,CS,BSCS,26
|
||||
26021520,CS,BSSE,26
|
||||
26031519,EE,BSEE,26
|
||||
26031520,EE,BSCE,26
|
||||
26041519,BBA,BBA,26
|
||||
26041520,BBA,BSAF,26
|
||||
|
||||
|
@@ -1,2 +1,3 @@
|
||||
block_id,block_name
|
||||
A,Block A
|
||||
B,Block B
|
||||
|
||||
|
@@ -5,3 +5,6 @@ A-103,Room 103,A,classroom,50
|
||||
A-201,Room 201,A,classroom,60
|
||||
A-L01,Computer Lab 1,A,lab,35
|
||||
A-L02,Computer Lab 2,A,lab,35
|
||||
B-101,Room 101 (B),B,classroom,50
|
||||
B-102,Room 102 (B),B,classroom,50
|
||||
B-L01,Electronics Lab,B,lab,30
|
||||
|
||||
|
@@ -1,15 +1,47 @@
|
||||
course_id,section_id,batch_codes,instructor_code
|
||||
CS101,A,25021519,1001
|
||||
CS201,A,25021519,1002
|
||||
CS301,A,25021519,1003
|
||||
CS302,A,25021519,1001
|
||||
CS101,B,25021520,1001
|
||||
CS201,B,25021520,1002
|
||||
CS301,B,25021520,1003
|
||||
CS302,B,25021520,1001
|
||||
EE101,A,25031519,1004
|
||||
EE201,A,25031519,1005
|
||||
EE301,A,25031519,1004
|
||||
EE101,B,25031520,1004
|
||||
EE201,B,25031520,1005
|
||||
EE301,B,25031520,1004
|
||||
BBA101,A,25041519,1007
|
||||
BBA201,A,25041519,1008
|
||||
BBA301,A,25041519,1007
|
||||
BBA101,B,25041520,1007
|
||||
BBA201,B,25041520,1008
|
||||
BBA301,B,25041520,1007
|
||||
CS101,C,26021519,1001
|
||||
CS201,C,26021519,1002
|
||||
CS301,C,26021519,1003
|
||||
CS302,C,26021519,1001
|
||||
CS101,D,26021520,1001
|
||||
CS201,D,26021520,1002
|
||||
EE101,B,26031519,1004
|
||||
GEN101,A,25021519|25021520|25031519,1002
|
||||
GEN102,A,25021519|25021520|25031519,1006
|
||||
GEN101,B,26021519|26021520|26031519,1002
|
||||
GEN102,B,26021519|26021520|26031519,1006
|
||||
CS301,D,26021520,1003
|
||||
CS302,D,26021520,1001
|
||||
EE101,C,26031519,1004
|
||||
EE201,C,26031519,1005
|
||||
EE301,C,26031519,1004
|
||||
EE101,D,26031520,1004
|
||||
EE201,D,26031520,1005
|
||||
EE301,D,26031520,1004
|
||||
BBA101,C,26041519,1007
|
||||
BBA201,C,26041519,1008
|
||||
BBA301,C,26041519,1007
|
||||
BBA101,D,26041520,1007
|
||||
BBA201,D,26041520,1008
|
||||
BBA301,D,26041520,1007
|
||||
GEN101,ALL,25021519|25021520|25031519|25031520|25041519|25041520,1002
|
||||
GEN102,ALL,25021519|25021520|25031519|25031520|25041519|25041520,1006
|
||||
GEN103,ALL,25021519|25021520|25031519|25031520|25041519|25041520,1006
|
||||
GEN101,ALL,26021519|26021520|26031519|26031520|26041519|26041520,1002
|
||||
GEN102,ALL,26021519|26021520|26031519|26031520|26041519|26041520,1006
|
||||
GEN103,ALL,26021519|26021520|26031519|26031520|26041519|26041520,1006
|
||||
|
||||
|
@@ -1,6 +1,14 @@
|
||||
course_id,course_name,credit_hours,lectures_per_week,labs_per_week,is_general,lecture_room_id,lab_room_id
|
||||
CS101,Programming Fundamentals,4,2,1,no,A-101,A-L01
|
||||
CS201,Data Structures,4,2,1,no,A-102,A-L01
|
||||
EE101,Basic Electronics,4,2,1,no,A-201,A-L02
|
||||
GEN101,Functional English,3,2,0,yes,A-103,
|
||||
GEN102,Islamic Studies,2,1,0,yes,A-103,
|
||||
course_id,course_name,credit_hours,lectures_per_week,labs_per_week,is_general,lecture_room_id,lab_room_id,lecture_duration_minutes
|
||||
CS101,Programming Fundamentals,4,2,1,no,A-101,A-L01,90
|
||||
CS201,Data Structures,4,2,1,no,A-102,A-L01,90
|
||||
CS301,Operating Systems,3,1,1,no,A-101,A-L02,120
|
||||
CS302,Database Systems,4,2,2,no,A-102,A-L02,90
|
||||
EE101,Basic Electronics,4,2,1,no,A-201,A-L02,90
|
||||
EE201,Digital Logic Design,4,2,1,no,B-101,B-L01,90
|
||||
EE301,Signals and Systems,3,1,0,no,B-102,,120
|
||||
BBA101,Principles of Management,3,2,0,no,B-101,,90
|
||||
BBA201,Financial Accounting,3,2,0,no,B-102,,90
|
||||
BBA301,Marketing Management,3,1,0,no,A-103,,120
|
||||
GEN101,Functional English,3,2,0,yes,A-103,,90
|
||||
GEN102,Islamic Studies,2,1,0,yes,A-103,,90
|
||||
GEN103,Pakistan Studies,2,1,0,yes,B-101,,120
|
||||
|
||||
|
@@ -1,6 +1,11 @@
|
||||
"""
|
||||
Generates small illustrative dummy CSV datasets under data/dummy/ so the
|
||||
timetable template generator has something to schedule and render.
|
||||
Generates a larger, deliberately harder dummy CSV dataset under data/dummy/
|
||||
so the timetable template generator has something non-trivial to schedule
|
||||
and render — more departments/batches/sections than the previous small
|
||||
dataset, tighter room and instructor contention (fewer rooms/instructors
|
||||
relative to demand), a second block, and mixed lecture durations (90 vs
|
||||
120 minutes) so weaknesses in the scheduler surface as WARNINGs/conflicts
|
||||
instead of everything trivially fitting.
|
||||
|
||||
Run once:
|
||||
python data/dummy/generate_dummy_data.py
|
||||
@@ -23,13 +28,18 @@ def write_csv(relative_path, header, rows):
|
||||
|
||||
|
||||
def main():
|
||||
# ---- blocks & rooms (Building/Block A only) ----
|
||||
# ---- blocks: two blocks now, Block A (bigger) and Block B (smaller) ----
|
||||
write_csv(
|
||||
"blocks/blocks.csv",
|
||||
["block_id", "block_name"],
|
||||
[["A", "Block A"]],
|
||||
[
|
||||
["A", "Block A"],
|
||||
["B", "Block B"],
|
||||
],
|
||||
)
|
||||
|
||||
# ---- rooms: deliberately tight relative to demand (see offerings
|
||||
# below) so room contention is real, spread across both blocks ----
|
||||
write_csv(
|
||||
"blocks/rooms.csv",
|
||||
["room_id", "room_name", "block_id", "room_type", "capacity"],
|
||||
@@ -40,21 +50,32 @@ def main():
|
||||
["A-201", "Room 201", "A", "classroom", 60],
|
||||
["A-L01", "Computer Lab 1", "A", "lab", 35],
|
||||
["A-L02", "Computer Lab 2", "A", "lab", 35],
|
||||
["B-101", "Room 101 (B)", "B", "classroom", 50],
|
||||
["B-102", "Room 102 (B)", "B", "classroom", 50],
|
||||
["B-L01", "Electronics Lab", "B", "lab", 30],
|
||||
],
|
||||
)
|
||||
|
||||
# ---- departments / programs / batches ----
|
||||
# batch_code = session(2) + program_id(6) e.g. 25021519
|
||||
batches_25 = [
|
||||
["25021519", "CS", "BSCS", "25"],
|
||||
["25021520", "CS", "BSSE", "25"],
|
||||
["25031519", "EE", "BSEE", "25"],
|
||||
]
|
||||
batches_26 = [
|
||||
["26021519", "CS", "BSCS", "26"],
|
||||
["26021520", "CS", "BSSE", "26"],
|
||||
["26031519", "EE", "BSEE", "26"],
|
||||
]
|
||||
# ---- departments / programs / batches: 3 departments, 2 programs
|
||||
# each, 2 sessions (25/26) -> 12 batches total (was 6) ----
|
||||
department_programs = {
|
||||
"CS": ["BSCS", "BSSE"],
|
||||
"EE": ["BSEE", "BSCE"],
|
||||
"BBA": ["BBA", "BSAF"],
|
||||
}
|
||||
program_codes = {
|
||||
"BSCS": "021519", "BSSE": "021520",
|
||||
"BSEE": "031519", "BSCE": "031520",
|
||||
"BBA": "041519", "BSAF": "041520",
|
||||
}
|
||||
|
||||
batches_25 = []
|
||||
batches_26 = []
|
||||
for department, programs in department_programs.items():
|
||||
for program in programs:
|
||||
code = program_codes[program]
|
||||
batches_25.append([f"25{code}", department, program, "25"])
|
||||
batches_26.append([f"26{code}", department, program, "26"])
|
||||
|
||||
write_csv(
|
||||
"batch_codes/25/batches.csv",
|
||||
@@ -70,62 +91,86 @@ def main():
|
||||
all_batches = batches_25 + batches_26
|
||||
|
||||
# ---- courses ----
|
||||
# One row per subject: lectures/labs per week are counted separately so
|
||||
# a single course can carry both, and each course names its preferred
|
||||
# lecture/lab room (the scheduler falls back to another same-type room
|
||||
# only if the preferred one is busy).
|
||||
# is_general courses are shared across every batch of the same session
|
||||
# (so they can be scheduled together on Tuesday first, with no clash).
|
||||
# course_id, course_name, credit_hours, lectures_per_week,
|
||||
# labs_per_week, is_general, lecture_room_id, lab_room_id,
|
||||
# lecture_duration_minutes
|
||||
#
|
||||
# Mixed lecture durations: most courses are 90-min x N/week, but a few
|
||||
# are the special "2 hours once a week" case (lecture_duration_minutes
|
||||
# 120, lectures_per_week 1). Labs vary 0/1/2 per week. Deliberately
|
||||
# more courses per department than the room/instructor pool can
|
||||
# comfortably absorb without contention.
|
||||
courses = [
|
||||
# course_id, course_name, credit_hours, lectures_per_week, labs_per_week, is_general, lecture_room_id, lab_room_id
|
||||
["CS101", "Programming Fundamentals", 4, 2, 1, "no", "A-101", "A-L01"],
|
||||
["CS201", "Data Structures", 4, 2, 1, "no", "A-102", "A-L01"],
|
||||
["EE101", "Basic Electronics", 4, 2, 1, "no", "A-201", "A-L02"],
|
||||
["GEN101", "Functional English", 3, 2, 0, "yes", "A-103", ""],
|
||||
["GEN102", "Islamic Studies", 2, 1, 0, "yes", "A-103", ""],
|
||||
# CS department courses
|
||||
["CS101", "Programming Fundamentals", 4, 2, 1, "no", "A-101", "A-L01", 90],
|
||||
["CS201", "Data Structures", 4, 2, 1, "no", "A-102", "A-L01", 90],
|
||||
["CS301", "Operating Systems", 3, 1, 1, "no", "A-101", "A-L02", 120],
|
||||
["CS302", "Database Systems", 4, 2, 2, "no", "A-102", "A-L02", 90],
|
||||
# EE department courses
|
||||
["EE101", "Basic Electronics", 4, 2, 1, "no", "A-201", "A-L02", 90],
|
||||
["EE201", "Digital Logic Design", 4, 2, 1, "no", "B-101", "B-L01", 90],
|
||||
["EE301", "Signals and Systems", 3, 1, 0, "no", "B-102", "", 120],
|
||||
# BBA department courses
|
||||
["BBA101", "Principles of Management", 3, 2, 0, "no", "B-101", "", 90],
|
||||
["BBA201", "Financial Accounting", 3, 2, 0, "no", "B-102", "", 90],
|
||||
["BBA301", "Marketing Management", 3, 1, 0, "no", "A-103", "", 120],
|
||||
# General (shared) courses
|
||||
["GEN101", "Functional English", 3, 2, 0, "yes", "A-103", "", 90],
|
||||
["GEN102", "Islamic Studies", 2, 1, 0, "yes", "A-103", "", 90],
|
||||
["GEN103", "Pakistan Studies", 2, 1, 0, "yes", "B-101", "", 120],
|
||||
]
|
||||
write_csv(
|
||||
"courses/courses.csv",
|
||||
[
|
||||
"course_id", "course_name", "credit_hours", "lectures_per_week",
|
||||
"labs_per_week", "is_general", "lecture_room_id", "lab_room_id",
|
||||
"lecture_duration_minutes",
|
||||
],
|
||||
courses,
|
||||
)
|
||||
|
||||
# ---- course offerings: course + section (a section groups the batches
|
||||
# taking that section together) + who teaches it ----
|
||||
# A course can have many sections; here each CS/EE batch of a session is
|
||||
# its own section (Section A/B/...), while general courses have a single
|
||||
# section "ALL" grouping every batch of that session.
|
||||
offerings = []
|
||||
|
||||
dept_course = {"CS": ["CS101", "CS201"], "EE": ["EE101"]}
|
||||
# ---- course offerings: course + section (batches in that section) +
|
||||
# instructor ----
|
||||
# Deliberately tight instructor pool reused across many sections/
|
||||
# courses (some instructors will end up wanted in overlapping slots),
|
||||
# forcing real contention in Phase 2/Phase 3.
|
||||
dept_courses = {
|
||||
"CS": ["CS101", "CS201", "CS301", "CS302"],
|
||||
"EE": ["EE101", "EE201", "EE301"],
|
||||
"BBA": ["BBA101", "BBA201", "BBA301"],
|
||||
}
|
||||
# Small pools relative to (department batches x courses) demand.
|
||||
dept_instructors = {
|
||||
"CS": ["1001", "1002", "1003", "1006"],
|
||||
"CS": ["1001", "1002", "1003"],
|
||||
"EE": ["1004", "1005"],
|
||||
"BBA": ["1007", "1008"],
|
||||
}
|
||||
|
||||
offerings = []
|
||||
section_letters = ["A", "B", "C", "D"]
|
||||
dept_section_counter = {"CS": 0, "EE": 0}
|
||||
dept_section_counter = {"CS": 0, "EE": 0, "BBA": 0}
|
||||
|
||||
for batch_code, department, program, session in all_batches:
|
||||
section_id = section_letters[dept_section_counter[department] % len(section_letters)]
|
||||
dept_section_counter[department] += 1
|
||||
|
||||
for i, course_id in enumerate(dept_course[department]):
|
||||
instr_pool = dept_instructors[department]
|
||||
instr_pool = dept_instructors[department]
|
||||
for i, course_id in enumerate(dept_courses[department]):
|
||||
# Deliberately narrow instructor rotation (2-3 instructors
|
||||
# covering 3-4 courses per department) so the same instructor
|
||||
# teaches multiple courses/sections -> instructor contention.
|
||||
instr = instr_pool[i % len(instr_pool)]
|
||||
offerings.append([course_id, section_id, batch_code, instr])
|
||||
|
||||
# general courses: one offering per (course, session), section "ALL"
|
||||
# grouping every batch code sharing that session, separated by "|"
|
||||
# grouping every batch code sharing that session
|
||||
for session, batch_group in (
|
||||
("25", [b[0] for b in batches_25]),
|
||||
("26", [b[0] for b in batches_26]),
|
||||
):
|
||||
offerings.append(["GEN101", "ALL", "|".join(batch_group), "1002"])
|
||||
offerings.append(["GEN102", "ALL", "|".join(batch_group), "1006"])
|
||||
offerings.append(["GEN103", "ALL", "|".join(batch_group), "1006"])
|
||||
|
||||
write_csv(
|
||||
"courses/course_offering.csv",
|
||||
@@ -143,6 +188,8 @@ def main():
|
||||
"1004": "Dr. Farah Iqbal",
|
||||
"1005": "Mr. Usman Ali",
|
||||
"1006": "Ms. Hira Shah",
|
||||
"1007": "Dr. Nadia Farooq",
|
||||
"1008": "Mr. Kamran Sheikh",
|
||||
}
|
||||
instructors = []
|
||||
for course_id, section_id, batch_codes, instr_code in offerings:
|
||||
@@ -154,10 +201,10 @@ def main():
|
||||
instructors,
|
||||
)
|
||||
|
||||
# ---- students (roll_no = batch_code-seq) ----
|
||||
# ---- students (roll_no = batch_code-seq): 18 per batch (was 5) ----
|
||||
students = []
|
||||
for batch_code, department, program, session in all_batches:
|
||||
for seq in range(1, 6): # 5 sample students per batch
|
||||
for seq in range(1, 19):
|
||||
roll_no = f"{batch_code}-{seq:03d}"
|
||||
students.append([roll_no, batch_code, f"Student {roll_no}"])
|
||||
|
||||
|
||||
@@ -1,15 +1,47 @@
|
||||
instructor_code,instructor_name,course_id,section_id
|
||||
1001,Dr. Ahsan Raza,CS101,A
|
||||
1002,Ms. Sana Tariq,CS201,A
|
||||
1003,Mr. Bilal Khan,CS301,A
|
||||
1001,Dr. Ahsan Raza,CS302,A
|
||||
1001,Dr. Ahsan Raza,CS101,B
|
||||
1002,Ms. Sana Tariq,CS201,B
|
||||
1003,Mr. Bilal Khan,CS301,B
|
||||
1001,Dr. Ahsan Raza,CS302,B
|
||||
1004,Dr. Farah Iqbal,EE101,A
|
||||
1005,Mr. Usman Ali,EE201,A
|
||||
1004,Dr. Farah Iqbal,EE301,A
|
||||
1004,Dr. Farah Iqbal,EE101,B
|
||||
1005,Mr. Usman Ali,EE201,B
|
||||
1004,Dr. Farah Iqbal,EE301,B
|
||||
1007,Dr. Nadia Farooq,BBA101,A
|
||||
1008,Mr. Kamran Sheikh,BBA201,A
|
||||
1007,Dr. Nadia Farooq,BBA301,A
|
||||
1007,Dr. Nadia Farooq,BBA101,B
|
||||
1008,Mr. Kamran Sheikh,BBA201,B
|
||||
1007,Dr. Nadia Farooq,BBA301,B
|
||||
1001,Dr. Ahsan Raza,CS101,C
|
||||
1002,Ms. Sana Tariq,CS201,C
|
||||
1003,Mr. Bilal Khan,CS301,C
|
||||
1001,Dr. Ahsan Raza,CS302,C
|
||||
1001,Dr. Ahsan Raza,CS101,D
|
||||
1002,Ms. Sana Tariq,CS201,D
|
||||
1004,Dr. Farah Iqbal,EE101,B
|
||||
1003,Mr. Bilal Khan,CS301,D
|
||||
1001,Dr. Ahsan Raza,CS302,D
|
||||
1004,Dr. Farah Iqbal,EE101,C
|
||||
1005,Mr. Usman Ali,EE201,C
|
||||
1004,Dr. Farah Iqbal,EE301,C
|
||||
1004,Dr. Farah Iqbal,EE101,D
|
||||
1005,Mr. Usman Ali,EE201,D
|
||||
1004,Dr. Farah Iqbal,EE301,D
|
||||
1007,Dr. Nadia Farooq,BBA101,C
|
||||
1008,Mr. Kamran Sheikh,BBA201,C
|
||||
1007,Dr. Nadia Farooq,BBA301,C
|
||||
1007,Dr. Nadia Farooq,BBA101,D
|
||||
1008,Mr. Kamran Sheikh,BBA201,D
|
||||
1007,Dr. Nadia Farooq,BBA301,D
|
||||
1002,Ms. Sana Tariq,GEN101,ALL
|
||||
1006,Ms. Hira Shah,GEN102,ALL
|
||||
1006,Ms. Hira Shah,GEN103,ALL
|
||||
1002,Ms. Sana Tariq,GEN101,ALL
|
||||
1006,Ms. Hira Shah,GEN102,ALL
|
||||
1006,Ms. Hira Shah,GEN103,ALL
|
||||
|
||||
|
@@ -4,28 +4,214 @@ roll_no,batch_code,student_name
|
||||
25021519-003,25021519,Student 25021519-003
|
||||
25021519-004,25021519,Student 25021519-004
|
||||
25021519-005,25021519,Student 25021519-005
|
||||
25021519-006,25021519,Student 25021519-006
|
||||
25021519-007,25021519,Student 25021519-007
|
||||
25021519-008,25021519,Student 25021519-008
|
||||
25021519-009,25021519,Student 25021519-009
|
||||
25021519-010,25021519,Student 25021519-010
|
||||
25021519-011,25021519,Student 25021519-011
|
||||
25021519-012,25021519,Student 25021519-012
|
||||
25021519-013,25021519,Student 25021519-013
|
||||
25021519-014,25021519,Student 25021519-014
|
||||
25021519-015,25021519,Student 25021519-015
|
||||
25021519-016,25021519,Student 25021519-016
|
||||
25021519-017,25021519,Student 25021519-017
|
||||
25021519-018,25021519,Student 25021519-018
|
||||
25021520-001,25021520,Student 25021520-001
|
||||
25021520-002,25021520,Student 25021520-002
|
||||
25021520-003,25021520,Student 25021520-003
|
||||
25021520-004,25021520,Student 25021520-004
|
||||
25021520-005,25021520,Student 25021520-005
|
||||
25021520-006,25021520,Student 25021520-006
|
||||
25021520-007,25021520,Student 25021520-007
|
||||
25021520-008,25021520,Student 25021520-008
|
||||
25021520-009,25021520,Student 25021520-009
|
||||
25021520-010,25021520,Student 25021520-010
|
||||
25021520-011,25021520,Student 25021520-011
|
||||
25021520-012,25021520,Student 25021520-012
|
||||
25021520-013,25021520,Student 25021520-013
|
||||
25021520-014,25021520,Student 25021520-014
|
||||
25021520-015,25021520,Student 25021520-015
|
||||
25021520-016,25021520,Student 25021520-016
|
||||
25021520-017,25021520,Student 25021520-017
|
||||
25021520-018,25021520,Student 25021520-018
|
||||
25031519-001,25031519,Student 25031519-001
|
||||
25031519-002,25031519,Student 25031519-002
|
||||
25031519-003,25031519,Student 25031519-003
|
||||
25031519-004,25031519,Student 25031519-004
|
||||
25031519-005,25031519,Student 25031519-005
|
||||
25031519-006,25031519,Student 25031519-006
|
||||
25031519-007,25031519,Student 25031519-007
|
||||
25031519-008,25031519,Student 25031519-008
|
||||
25031519-009,25031519,Student 25031519-009
|
||||
25031519-010,25031519,Student 25031519-010
|
||||
25031519-011,25031519,Student 25031519-011
|
||||
25031519-012,25031519,Student 25031519-012
|
||||
25031519-013,25031519,Student 25031519-013
|
||||
25031519-014,25031519,Student 25031519-014
|
||||
25031519-015,25031519,Student 25031519-015
|
||||
25031519-016,25031519,Student 25031519-016
|
||||
25031519-017,25031519,Student 25031519-017
|
||||
25031519-018,25031519,Student 25031519-018
|
||||
25031520-001,25031520,Student 25031520-001
|
||||
25031520-002,25031520,Student 25031520-002
|
||||
25031520-003,25031520,Student 25031520-003
|
||||
25031520-004,25031520,Student 25031520-004
|
||||
25031520-005,25031520,Student 25031520-005
|
||||
25031520-006,25031520,Student 25031520-006
|
||||
25031520-007,25031520,Student 25031520-007
|
||||
25031520-008,25031520,Student 25031520-008
|
||||
25031520-009,25031520,Student 25031520-009
|
||||
25031520-010,25031520,Student 25031520-010
|
||||
25031520-011,25031520,Student 25031520-011
|
||||
25031520-012,25031520,Student 25031520-012
|
||||
25031520-013,25031520,Student 25031520-013
|
||||
25031520-014,25031520,Student 25031520-014
|
||||
25031520-015,25031520,Student 25031520-015
|
||||
25031520-016,25031520,Student 25031520-016
|
||||
25031520-017,25031520,Student 25031520-017
|
||||
25031520-018,25031520,Student 25031520-018
|
||||
25041519-001,25041519,Student 25041519-001
|
||||
25041519-002,25041519,Student 25041519-002
|
||||
25041519-003,25041519,Student 25041519-003
|
||||
25041519-004,25041519,Student 25041519-004
|
||||
25041519-005,25041519,Student 25041519-005
|
||||
25041519-006,25041519,Student 25041519-006
|
||||
25041519-007,25041519,Student 25041519-007
|
||||
25041519-008,25041519,Student 25041519-008
|
||||
25041519-009,25041519,Student 25041519-009
|
||||
25041519-010,25041519,Student 25041519-010
|
||||
25041519-011,25041519,Student 25041519-011
|
||||
25041519-012,25041519,Student 25041519-012
|
||||
25041519-013,25041519,Student 25041519-013
|
||||
25041519-014,25041519,Student 25041519-014
|
||||
25041519-015,25041519,Student 25041519-015
|
||||
25041519-016,25041519,Student 25041519-016
|
||||
25041519-017,25041519,Student 25041519-017
|
||||
25041519-018,25041519,Student 25041519-018
|
||||
25041520-001,25041520,Student 25041520-001
|
||||
25041520-002,25041520,Student 25041520-002
|
||||
25041520-003,25041520,Student 25041520-003
|
||||
25041520-004,25041520,Student 25041520-004
|
||||
25041520-005,25041520,Student 25041520-005
|
||||
25041520-006,25041520,Student 25041520-006
|
||||
25041520-007,25041520,Student 25041520-007
|
||||
25041520-008,25041520,Student 25041520-008
|
||||
25041520-009,25041520,Student 25041520-009
|
||||
25041520-010,25041520,Student 25041520-010
|
||||
25041520-011,25041520,Student 25041520-011
|
||||
25041520-012,25041520,Student 25041520-012
|
||||
25041520-013,25041520,Student 25041520-013
|
||||
25041520-014,25041520,Student 25041520-014
|
||||
25041520-015,25041520,Student 25041520-015
|
||||
25041520-016,25041520,Student 25041520-016
|
||||
25041520-017,25041520,Student 25041520-017
|
||||
25041520-018,25041520,Student 25041520-018
|
||||
26021519-001,26021519,Student 26021519-001
|
||||
26021519-002,26021519,Student 26021519-002
|
||||
26021519-003,26021519,Student 26021519-003
|
||||
26021519-004,26021519,Student 26021519-004
|
||||
26021519-005,26021519,Student 26021519-005
|
||||
26021519-006,26021519,Student 26021519-006
|
||||
26021519-007,26021519,Student 26021519-007
|
||||
26021519-008,26021519,Student 26021519-008
|
||||
26021519-009,26021519,Student 26021519-009
|
||||
26021519-010,26021519,Student 26021519-010
|
||||
26021519-011,26021519,Student 26021519-011
|
||||
26021519-012,26021519,Student 26021519-012
|
||||
26021519-013,26021519,Student 26021519-013
|
||||
26021519-014,26021519,Student 26021519-014
|
||||
26021519-015,26021519,Student 26021519-015
|
||||
26021519-016,26021519,Student 26021519-016
|
||||
26021519-017,26021519,Student 26021519-017
|
||||
26021519-018,26021519,Student 26021519-018
|
||||
26021520-001,26021520,Student 26021520-001
|
||||
26021520-002,26021520,Student 26021520-002
|
||||
26021520-003,26021520,Student 26021520-003
|
||||
26021520-004,26021520,Student 26021520-004
|
||||
26021520-005,26021520,Student 26021520-005
|
||||
26021520-006,26021520,Student 26021520-006
|
||||
26021520-007,26021520,Student 26021520-007
|
||||
26021520-008,26021520,Student 26021520-008
|
||||
26021520-009,26021520,Student 26021520-009
|
||||
26021520-010,26021520,Student 26021520-010
|
||||
26021520-011,26021520,Student 26021520-011
|
||||
26021520-012,26021520,Student 26021520-012
|
||||
26021520-013,26021520,Student 26021520-013
|
||||
26021520-014,26021520,Student 26021520-014
|
||||
26021520-015,26021520,Student 26021520-015
|
||||
26021520-016,26021520,Student 26021520-016
|
||||
26021520-017,26021520,Student 26021520-017
|
||||
26021520-018,26021520,Student 26021520-018
|
||||
26031519-001,26031519,Student 26031519-001
|
||||
26031519-002,26031519,Student 26031519-002
|
||||
26031519-003,26031519,Student 26031519-003
|
||||
26031519-004,26031519,Student 26031519-004
|
||||
26031519-005,26031519,Student 26031519-005
|
||||
26031519-006,26031519,Student 26031519-006
|
||||
26031519-007,26031519,Student 26031519-007
|
||||
26031519-008,26031519,Student 26031519-008
|
||||
26031519-009,26031519,Student 26031519-009
|
||||
26031519-010,26031519,Student 26031519-010
|
||||
26031519-011,26031519,Student 26031519-011
|
||||
26031519-012,26031519,Student 26031519-012
|
||||
26031519-013,26031519,Student 26031519-013
|
||||
26031519-014,26031519,Student 26031519-014
|
||||
26031519-015,26031519,Student 26031519-015
|
||||
26031519-016,26031519,Student 26031519-016
|
||||
26031519-017,26031519,Student 26031519-017
|
||||
26031519-018,26031519,Student 26031519-018
|
||||
26031520-001,26031520,Student 26031520-001
|
||||
26031520-002,26031520,Student 26031520-002
|
||||
26031520-003,26031520,Student 26031520-003
|
||||
26031520-004,26031520,Student 26031520-004
|
||||
26031520-005,26031520,Student 26031520-005
|
||||
26031520-006,26031520,Student 26031520-006
|
||||
26031520-007,26031520,Student 26031520-007
|
||||
26031520-008,26031520,Student 26031520-008
|
||||
26031520-009,26031520,Student 26031520-009
|
||||
26031520-010,26031520,Student 26031520-010
|
||||
26031520-011,26031520,Student 26031520-011
|
||||
26031520-012,26031520,Student 26031520-012
|
||||
26031520-013,26031520,Student 26031520-013
|
||||
26031520-014,26031520,Student 26031520-014
|
||||
26031520-015,26031520,Student 26031520-015
|
||||
26031520-016,26031520,Student 26031520-016
|
||||
26031520-017,26031520,Student 26031520-017
|
||||
26031520-018,26031520,Student 26031520-018
|
||||
26041519-001,26041519,Student 26041519-001
|
||||
26041519-002,26041519,Student 26041519-002
|
||||
26041519-003,26041519,Student 26041519-003
|
||||
26041519-004,26041519,Student 26041519-004
|
||||
26041519-005,26041519,Student 26041519-005
|
||||
26041519-006,26041519,Student 26041519-006
|
||||
26041519-007,26041519,Student 26041519-007
|
||||
26041519-008,26041519,Student 26041519-008
|
||||
26041519-009,26041519,Student 26041519-009
|
||||
26041519-010,26041519,Student 26041519-010
|
||||
26041519-011,26041519,Student 26041519-011
|
||||
26041519-012,26041519,Student 26041519-012
|
||||
26041519-013,26041519,Student 26041519-013
|
||||
26041519-014,26041519,Student 26041519-014
|
||||
26041519-015,26041519,Student 26041519-015
|
||||
26041519-016,26041519,Student 26041519-016
|
||||
26041519-017,26041519,Student 26041519-017
|
||||
26041519-018,26041519,Student 26041519-018
|
||||
26041520-001,26041520,Student 26041520-001
|
||||
26041520-002,26041520,Student 26041520-002
|
||||
26041520-003,26041520,Student 26041520-003
|
||||
26041520-004,26041520,Student 26041520-004
|
||||
26041520-005,26041520,Student 26041520-005
|
||||
26041520-006,26041520,Student 26041520-006
|
||||
26041520-007,26041520,Student 26041520-007
|
||||
26041520-008,26041520,Student 26041520-008
|
||||
26041520-009,26041520,Student 26041520-009
|
||||
26041520-010,26041520,Student 26041520-010
|
||||
26041520-011,26041520,Student 26041520-011
|
||||
26041520-012,26041520,Student 26041520-012
|
||||
26041520-013,26041520,Student 26041520-013
|
||||
26041520-014,26041520,Student 26041520-014
|
||||
26041520-015,26041520,Student 26041520-015
|
||||
26041520-016,26041520,Student 26041520-016
|
||||
26041520-017,26041520,Student 26041520-017
|
||||
26041520-018,26041520,Student 26041520-018
|
||||
|
||||
|
@@ -1,3 +1,12 @@
|
||||
Timetable generation log - started 2026-09-09T18:10:11.467126
|
||||
Timetable generation log - started 2026-09-09T18:19:44.655145
|
||||
================================================================================
|
||||
[18:10:11] INFO: clear_all: schedule state, result templates, and log have been reset. Run phase_1 to start over.
|
||||
[18:19:44] INFO: clear_all: schedule state, result templates, and log have been reset. Run phase_1 to start over.
|
||||
[18:19:48] INFO: Phase 1/3: scheduling general courses (Tue/Thu preferred)...
|
||||
[18:19:48] INFO: [Phase 1 (general courses)] No conflicts found — clash-free.
|
||||
[18:19:48] INFO: phase_1 complete: 8 session(s) added this phase, 8 total so far. State saved to D:\projects\UORM\timetable\result\schedule_state.json.
|
||||
[18:19:57] INFO: Phase 2/3: scheduling labs (on top of phase_1's fixed placements)...
|
||||
[18:19:57] INFO: [Phase 2 (general courses + labs)] No conflicts found — clash-free.
|
||||
[18:19:57] INFO: phase_2 complete: 23 session(s) added this phase, 31 total so far. State saved to D:\projects\UORM\timetable\result\schedule_state.json.
|
||||
[18:20:05] INFO: Phase 3/3: scheduling remaining courses (batch by batch)...
|
||||
[18:20:05] INFO: [Phase 3 (full schedule)] No conflicts found — clash-free.
|
||||
[18:20:05] INFO: phase_3 complete: 51 session(s) added this phase, 82 total so far. State saved to D:\projects\UORM\timetable\result\schedule_state.json.
|
||||
|
||||
2305
result/schedule_state.json
Normal file
2305
result/schedule_state.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
result/templates/batch-wise/25021519.xlsx
Normal file
BIN
result/templates/batch-wise/25021519.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/25021520.xlsx
Normal file
BIN
result/templates/batch-wise/25021520.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/25031519.xlsx
Normal file
BIN
result/templates/batch-wise/25031519.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/25031520.xlsx
Normal file
BIN
result/templates/batch-wise/25031520.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/25041519.xlsx
Normal file
BIN
result/templates/batch-wise/25041519.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/25041520.xlsx
Normal file
BIN
result/templates/batch-wise/25041520.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/26021519.xlsx
Normal file
BIN
result/templates/batch-wise/26021519.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/26021520.xlsx
Normal file
BIN
result/templates/batch-wise/26021520.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/26031519.xlsx
Normal file
BIN
result/templates/batch-wise/26031519.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/26031520.xlsx
Normal file
BIN
result/templates/batch-wise/26031520.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/26041519.xlsx
Normal file
BIN
result/templates/batch-wise/26041519.xlsx
Normal file
Binary file not shown.
BIN
result/templates/batch-wise/26041520.xlsx
Normal file
BIN
result/templates/batch-wise/26041520.xlsx
Normal file
Binary file not shown.
BIN
result/templates/department-wise/BBA.xlsx
Normal file
BIN
result/templates/department-wise/BBA.xlsx
Normal file
Binary file not shown.
BIN
result/templates/department-wise/CS.xlsx
Normal file
BIN
result/templates/department-wise/CS.xlsx
Normal file
Binary file not shown.
BIN
result/templates/department-wise/EE.xlsx
Normal file
BIN
result/templates/department-wise/EE.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/A-101.xlsx
Normal file
BIN
result/templates/room-wise/A-101.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/A-102.xlsx
Normal file
BIN
result/templates/room-wise/A-102.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/A-103.xlsx
Normal file
BIN
result/templates/room-wise/A-103.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/A-201.xlsx
Normal file
BIN
result/templates/room-wise/A-201.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/A-L01.xlsx
Normal file
BIN
result/templates/room-wise/A-L01.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/A-L02.xlsx
Normal file
BIN
result/templates/room-wise/A-L02.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/B-101.xlsx
Normal file
BIN
result/templates/room-wise/B-101.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/B-102.xlsx
Normal file
BIN
result/templates/room-wise/B-102.xlsx
Normal file
Binary file not shown.
BIN
result/templates/room-wise/B-L01.xlsx
Normal file
BIN
result/templates/room-wise/B-L01.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-001.xlsx
Normal file
BIN
result/templates/student-wise/25021519-001.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-002.xlsx
Normal file
BIN
result/templates/student-wise/25021519-002.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-003.xlsx
Normal file
BIN
result/templates/student-wise/25021519-003.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-004.xlsx
Normal file
BIN
result/templates/student-wise/25021519-004.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-005.xlsx
Normal file
BIN
result/templates/student-wise/25021519-005.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-006.xlsx
Normal file
BIN
result/templates/student-wise/25021519-006.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-007.xlsx
Normal file
BIN
result/templates/student-wise/25021519-007.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-008.xlsx
Normal file
BIN
result/templates/student-wise/25021519-008.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-009.xlsx
Normal file
BIN
result/templates/student-wise/25021519-009.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-010.xlsx
Normal file
BIN
result/templates/student-wise/25021519-010.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-011.xlsx
Normal file
BIN
result/templates/student-wise/25021519-011.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-012.xlsx
Normal file
BIN
result/templates/student-wise/25021519-012.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-013.xlsx
Normal file
BIN
result/templates/student-wise/25021519-013.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-014.xlsx
Normal file
BIN
result/templates/student-wise/25021519-014.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-015.xlsx
Normal file
BIN
result/templates/student-wise/25021519-015.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-016.xlsx
Normal file
BIN
result/templates/student-wise/25021519-016.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-017.xlsx
Normal file
BIN
result/templates/student-wise/25021519-017.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021519-018.xlsx
Normal file
BIN
result/templates/student-wise/25021519-018.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-001.xlsx
Normal file
BIN
result/templates/student-wise/25021520-001.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-002.xlsx
Normal file
BIN
result/templates/student-wise/25021520-002.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-003.xlsx
Normal file
BIN
result/templates/student-wise/25021520-003.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-004.xlsx
Normal file
BIN
result/templates/student-wise/25021520-004.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-005.xlsx
Normal file
BIN
result/templates/student-wise/25021520-005.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-006.xlsx
Normal file
BIN
result/templates/student-wise/25021520-006.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-007.xlsx
Normal file
BIN
result/templates/student-wise/25021520-007.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-008.xlsx
Normal file
BIN
result/templates/student-wise/25021520-008.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-009.xlsx
Normal file
BIN
result/templates/student-wise/25021520-009.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-010.xlsx
Normal file
BIN
result/templates/student-wise/25021520-010.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-011.xlsx
Normal file
BIN
result/templates/student-wise/25021520-011.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-012.xlsx
Normal file
BIN
result/templates/student-wise/25021520-012.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-013.xlsx
Normal file
BIN
result/templates/student-wise/25021520-013.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-014.xlsx
Normal file
BIN
result/templates/student-wise/25021520-014.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-015.xlsx
Normal file
BIN
result/templates/student-wise/25021520-015.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-016.xlsx
Normal file
BIN
result/templates/student-wise/25021520-016.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-017.xlsx
Normal file
BIN
result/templates/student-wise/25021520-017.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25021520-018.xlsx
Normal file
BIN
result/templates/student-wise/25021520-018.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-001.xlsx
Normal file
BIN
result/templates/student-wise/25031519-001.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-002.xlsx
Normal file
BIN
result/templates/student-wise/25031519-002.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-003.xlsx
Normal file
BIN
result/templates/student-wise/25031519-003.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-004.xlsx
Normal file
BIN
result/templates/student-wise/25031519-004.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-005.xlsx
Normal file
BIN
result/templates/student-wise/25031519-005.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-006.xlsx
Normal file
BIN
result/templates/student-wise/25031519-006.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-007.xlsx
Normal file
BIN
result/templates/student-wise/25031519-007.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-008.xlsx
Normal file
BIN
result/templates/student-wise/25031519-008.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-009.xlsx
Normal file
BIN
result/templates/student-wise/25031519-009.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-010.xlsx
Normal file
BIN
result/templates/student-wise/25031519-010.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-011.xlsx
Normal file
BIN
result/templates/student-wise/25031519-011.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-012.xlsx
Normal file
BIN
result/templates/student-wise/25031519-012.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-013.xlsx
Normal file
BIN
result/templates/student-wise/25031519-013.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-014.xlsx
Normal file
BIN
result/templates/student-wise/25031519-014.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-015.xlsx
Normal file
BIN
result/templates/student-wise/25031519-015.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-016.xlsx
Normal file
BIN
result/templates/student-wise/25031519-016.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-017.xlsx
Normal file
BIN
result/templates/student-wise/25031519-017.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031519-018.xlsx
Normal file
BIN
result/templates/student-wise/25031519-018.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-001.xlsx
Normal file
BIN
result/templates/student-wise/25031520-001.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-002.xlsx
Normal file
BIN
result/templates/student-wise/25031520-002.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-003.xlsx
Normal file
BIN
result/templates/student-wise/25031520-003.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-004.xlsx
Normal file
BIN
result/templates/student-wise/25031520-004.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-005.xlsx
Normal file
BIN
result/templates/student-wise/25031520-005.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-006.xlsx
Normal file
BIN
result/templates/student-wise/25031520-006.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-007.xlsx
Normal file
BIN
result/templates/student-wise/25031520-007.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-008.xlsx
Normal file
BIN
result/templates/student-wise/25031520-008.xlsx
Normal file
Binary file not shown.
BIN
result/templates/student-wise/25031520-009.xlsx
Normal file
BIN
result/templates/student-wise/25031520-009.xlsx
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user