aneesqumar commited on
Commit
3e75c6e
·
verified ·
1 Parent(s): fa92abb

Update timetable.py

Browse files
Files changed (1) hide show
  1. timetable.py +56 -97
timetable.py CHANGED
@@ -1,105 +1,64 @@
1
  import pandas as pd
 
2
  import random
3
 
 
4
  DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
5
- # Time slots with duration in hours
6
- TIME_SLOTS = ["9:00-10:00", "10:00-11:00", "11:00-12:30", "12:30-1:30", "1:30-3:00"]
7
- MAX_SLOT_DURATION = {"9:00-10:00": 1.0, "10:00-11:00":1.0, "11:00-12:30":1.5,
8
- "12:30-1:30":1.0, "1:30-3:00":1.5}
9
 
10
- def split_course_hours(hours):
11
- """Split weekly hours into chunks <=1.5 per day"""
12
- chunks = []
13
- remaining = hours
14
- while remaining > 0:
15
- dur = 1.5 if remaining >= 1.5 else 1.0
16
- chunks.append(dur)
17
- remaining -= dur
18
- return chunks
19
-
20
- def generate_class_timetable(class_courses, rooms, teacher_schedule, room_schedule):
21
- """Generate timetable for a single class"""
22
- timetable = {day: [None]*len(TIME_SLOTS) for day in DAYS}
23
-
24
- # Prepare course blocks
25
- course_blocks = []
26
- for _, row in class_courses.iterrows():
27
- chunks = split_course_hours(row['Hours'])
28
- for dur in chunks:
29
- course_blocks.append({
30
- "Course": row['Course'],
31
- "Teacher": row['Teacher'],
32
- "Duration": dur
33
- })
34
-
35
- random.shuffle(course_blocks)
36
-
37
- for block in course_blocks:
38
- allocated = False
39
- random_days = DAYS.copy()
40
- random.shuffle(random_days)
41
-
42
- for day in random_days:
43
- for idx, slot in enumerate(TIME_SLOTS):
44
- slot_max = MAX_SLOT_DURATION[slot]
45
- if timetable[day][idx] is None and block['Duration'] <= slot_max:
46
- teacher = block['Teacher']
47
-
48
- # Check teacher availability
49
- if teacher_schedule.get((teacher, day, idx), False):
50
- continue
51
-
52
- # Check room availability
53
- available_room = None
54
- for room in rooms:
55
- if not room_schedule.get((room, day, idx), False):
56
- available_room = room
57
- break
58
- if not available_room:
59
- continue
60
-
61
- # Assign course
62
- timetable[day][idx] = f"{block['Course']} ({teacher}) [{available_room}]"
63
-
64
- # Mark teacher and room as busy
65
- teacher_schedule[(teacher, day, idx)] = True
66
- room_schedule[(available_room, day, idx)] = True
67
-
68
- allocated = True
69
  break
70
- if allocated:
71
- break
72
- if not allocated:
73
- print(f"⚠️ Could not allocate: {block['Course']} ({block['Teacher']})")
74
-
75
- return timetable
76
-
77
- def timetable_to_dataframe(timetable, class_name):
78
- """Convert timetable dict to DataFrame"""
79
- max_slots = len(TIME_SLOTS)
80
- data = []
81
- for day in DAYS:
82
- row = [day] + [timetable[day][i] if timetable[day][i] else "" for i in range(max_slots)]
83
- data.append(row)
84
-
85
- columns = ["Day"] + [f"Slot {i+1}" for i in range(max_slots)]
86
- df = pd.DataFrame(data, columns=columns)
87
- df.insert(0, "Class/Program", class_name)
88
- return df
89
-
90
- def generate_full_timetable(courses_path, rooms_path):
91
- courses_df = pd.read_csv(courses_path)
92
- rooms_df = pd.read_csv(rooms_path)
93
- rooms = rooms_df['Room'].tolist()
94
-
95
- full_df = pd.DataFrame()
96
- teacher_schedule = {} # Track teacher occupied slots across all classes
97
- room_schedule = {} # Track room occupied slots across all classes
98
 
99
- for class_name in courses_df['Class'].unique():
100
- class_courses = courses_df[courses_df['Class']==class_name]
101
- timetable = generate_class_timetable(class_courses, rooms, teacher_schedule, room_schedule)
102
- df = timetable_to_dataframe(timetable, class_name)
103
- full_df = pd.concat([full_df, df], ignore_index=True)
104
 
105
- return full_df
 
1
  import pandas as pd
2
+ import numpy as np
3
  import random
4
 
5
+ TIME_SLOTS = ["9:00-10:30", "10:30-12:00", "12:00-1:30", "1:30-3:00"]
6
  DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
 
 
 
 
7
 
8
+ def generate_timetable(courses_file, rooms_file):
9
+ courses_df = pd.read_csv(courses_file)
10
+ rooms = pd.read_csv(rooms_file)["Room"].tolist()
11
+
12
+ timetable_dict = {}
13
+
14
+ for cls in courses_df["Class"].unique():
15
+ cls_df = courses_df[courses_df["Class"] == cls].copy()
16
+ timetable = {day: [None]*len(TIME_SLOTS) for day in DAYS}
17
+ teacher_slots = {teacher: {day: [] for day in DAYS} for teacher in cls_df["Teacher"].unique()}
18
+ room_slots = {room: {day: [] for day in DAYS} for room in rooms}
19
+
20
+ # Split course hours into 1.5-hour blocks
21
+ course_blocks = []
22
+ for idx, row in cls_df.iterrows():
23
+ remaining_hours = row["Hours"]
24
+ while remaining_hours > 0:
25
+ block_hours = min(1.5, remaining_hours)
26
+ course_blocks.append({
27
+ "Course": row["Course"],
28
+ "Teacher": row["Teacher"],
29
+ "Hours": block_hours,
30
+ "Class": row["Class"]
31
+ })
32
+ remaining_hours -= block_hours
33
+
34
+ random.shuffle(course_blocks)
35
+
36
+ # Assign courses to slots
37
+ for block in course_blocks:
38
+ assigned = False
39
+ for day in DAYS:
40
+ for i, slot in enumerate(TIME_SLOTS):
41
+ if timetable[day][i] is None:
42
+ # Check teacher and room conflicts
43
+ teacher = block["Teacher"]
44
+ available_rooms = [r for r in rooms if i not in room_slots[r][day]]
45
+ if i in teacher_slots[teacher][day]:
46
+ continue
47
+ if not available_rooms:
48
+ continue
49
+ room = random.choice(available_rooms)
50
+ timetable[day][i] = f"{block['Course']}\n{block['Teacher']}\n{room}\n{block['Hours']}h"
51
+ teacher_slots[teacher][day].append(i)
52
+ room_slots[room][day].append(i)
53
+ assigned = True
54
+ break
55
+ if assigned:
 
 
 
 
 
 
 
 
 
 
 
56
  break
57
+ if not assigned:
58
+ print(f"Could not assign {block['Course']} for {cls}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ # Convert timetable to DataFrame
61
+ df = pd.DataFrame(timetable, index=TIME_SLOTS)
62
+ timetable_dict[cls] = df
 
 
63
 
64
+ return timetable_dict