Skip to content

Commit dcbea18

Browse files
author
Logan Endes
committed
Added time block class, worked on main algorithm, added tostring for sections, added bucket helpers, added constants for class times
1 parent 0c305a7 commit dcbea18

File tree

7 files changed

+297
-45
lines changed

7 files changed

+297
-45
lines changed

buckets.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from student import Student
2-
from typing import List
2+
from typing import List, Dict
3+
import math
34

45
class Buckets:
56
"""
@@ -23,9 +24,11 @@ class Buckets:
2324
intermediateASL: list = []
2425
advancedASL: list = []
2526

27+
size_dict = {}
28+
bucket_dict = {}
29+
count_dict = {}
2630

27-
def sortcourses(self, students: List[Student]) -> None:
28-
31+
def sort_courses(self, students: List[Student]) -> None:
2932
for student in students:
3033
# Put into proper English bucket
3134
if student.english <= 3:
@@ -50,6 +53,29 @@ def sortcourses(self, students: List[Student]) -> None:
5053
self.advancedASL.append(student)
5154
else:
5255
self.intermediateASL.append(student)
56+
57+
self.bucket_dict = {
58+
"beginningEnglish": self.beginningEnglish,
59+
"intermediateEnglish": self.intermediateEnglish,
60+
"advancedEnglish": self.advancedEnglish,
61+
"beginningMath": self.beginningMath,
62+
"intermediateMath": self.intermediateMath,
63+
"advancedMath": self.advancedMath,
64+
"beginningASL": self.beginningASL,
65+
"intermediateASL": self.intermediateASL,
66+
"advancedASL": self.advancedASL
67+
}
68+
self.size_dict = {
69+
"beginningEnglish": len(self.beginningEnglish),
70+
"intermediateEnglish": len(self.intermediateEnglish),
71+
"advancedEnglish": len(self.advancedEnglish),
72+
"beginningMath": len(self.beginningMath),
73+
"intermediateMath": len(self.intermediateMath),
74+
"advancedMath": len(self.advancedMath),
75+
"beginningASL": len(self.beginningASL),
76+
"intermediateASL": len(self.intermediateASL),
77+
"advancedASL": len(self.advancedASL)
78+
}
5379

5480
def get_buckets(self) -> List[List[Student]]:
5581
return [
@@ -77,6 +103,25 @@ def get_bucket_sizes(self) -> List[int]:
77103
len(self.advancedASL)
78104
]
79105

106+
def set_class_count(self, class_limit = 7) -> None:
107+
"""
108+
Returns a list of tuples containing the course name and the number of sections.
109+
"""
110+
for key, size in self.size_dict.items():
111+
if size == 0:
112+
self.count_dict[key] = 0
113+
else:
114+
self.count_dict[key] = math.ceil(size / class_limit)
115+
116+
def get_class_count(self) -> Dict:
117+
return self.count_dict
118+
119+
def get_bucket_dict(self) -> Dict:
120+
return self.bucket_dict
121+
122+
def get_size_dict(self) -> Dict:
123+
return self.size_dict
124+
80125
def __str__(self) -> str:
81126
sizes = self.get_bucket_sizes()
82127
return f"""

constants.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1-
BEGGINER = 0
1+
from time_block import TimeBlock
2+
from datetime import time
3+
BEGINNER = 0
24
INTERMEDIATE = 1
3-
ADAVANCED = 2
5+
ADVANCED = 2
6+
CLASS_LIMIT = 7
7+
BLOCK_ONE = TimeBlock(time(8, 0), time(9, 0))
8+
BLOCK_TWO = TimeBlock(time(9, 15), time(10, 15))
9+
BLOCK_THREE = TimeBlock(time(10, 45), time(11, 45))
10+
LUNCH_TIME = TimeBlock(time(11, 45), time(12, 45))
11+
BLOCK_FOUR = TimeBlock(time(12, 45), time(1, 45))
12+
BLOCK_FIVE = TimeBlock(time(2, 0), time(3, 0))
13+
BLOCK_SIX = TimeBlock(time(3, 30), time(4, 30))

main.py

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
99
A score of 0 means that no test score was received. In this instance, they will default to Beginner level.
1010
"""
11-
from typing import List, Tuple
11+
from typing import List, Tuple, Dict, Union
1212
from student import Student
1313
from buckets import Buckets
1414
from teacher import Teacher
15+
from section import Section
16+
from constants import *
17+
import math
18+
1519

1620
def load_student_csv(file_name) -> List[Student]:
1721
"""
@@ -51,7 +55,7 @@ def return_scores(students: List[Student]) -> List[Tuple[int, int, int]]:
5155

5256
def make_buckets(students: List[Student]) -> Buckets:
5357
bucket = Buckets()
54-
bucket.sortcourses(students)
58+
bucket.sort_courses(students)
5559
return bucket
5660

5761
def sort_students(students_to_score: List[Student]) -> List[Student]:
@@ -98,6 +102,94 @@ def load_instructor_csv(file_name) -> List[Teacher]:
98102
teachers.append(Teacher('Mentoring', mentor, 0, is_mentor=True))
99103
return teachers
100104

105+
def create_sections_easy(class_count_dict: Dict) -> List[Section]:
106+
"""
107+
Creates sections for each class assuming there is no issue with the number of students.
108+
"""
109+
sections = []
110+
for class_name, count in class_count_dict.items():
111+
if count > 0:
112+
for i in range(count):
113+
level = 0
114+
if "beginning" in class_name:
115+
level = BEGINNER
116+
elif "intermediate" in class_name:
117+
level = INTERMEDIATE
118+
elif "advanced" in class_name:
119+
level = ADVANCED
120+
121+
if "English" in class_name:
122+
name = "Essential Communication"
123+
elif "Math" in class_name:
124+
name = "Technical Math"
125+
elif "ASL" in class_name:
126+
name = "ASL"
127+
128+
sections.append(Section(name, None, CLASS_LIMIT, level, None))
129+
return sections
130+
131+
def create_sections_hard(class_count_dict: Dict, subject_availability_dict: Dict, subjects: Union[List, str]) -> Tuple[List[Section], Dict]:
132+
"""
133+
Creates sections for each class assuming there is an issue with the number of students.
134+
This function will create sections based on the availability of subjects.
135+
If there are not enough sections available, it will prioritize lower level classes first, and then move higher classes to the overflow dictionary.
136+
137+
IN FUTURE ITERATIONS, THIS SHOULD INSTEAD PRIORITIZE THE LARGER CLASS FIRST, THEN THE SMALLER CLASS.
138+
139+
"""
140+
sections = []
141+
overflow_dict = {}
142+
class_counts = class_count_dict.items()
143+
144+
if isinstance(subjects, str):
145+
subjects = [subjects]
146+
147+
# Loop through each class and add 1 sections until there are no more subjects available
148+
subject_availability_dict = {key: value for key, value in subject_availability_dict.items() if key in subjects} # Filter to only include relevant subjects
149+
150+
while any(subject_availability_dict.values()): # Continue while there are available subjects
151+
# print("Subject availability dict: ", subject_availability_dict)
152+
for class_name, count in class_counts:
153+
# print("Class name: ", class_name, "Count: ", count)
154+
if count > 0:
155+
# Determine the level based on the class name
156+
level = 0
157+
if "beginning" in class_name:
158+
level = BEGINNER
159+
elif "intermediate" in class_name:
160+
level = INTERMEDIATE
161+
elif "advanced" in class_name:
162+
level = ADVANCED
163+
164+
name = class_name
165+
if "English" in class_name or "Communication" in class_name:
166+
name = "Essential Communication"
167+
elif "Math" in class_name:
168+
name = "Technical Math"
169+
elif "ASL" in class_name:
170+
name = "ASL"
171+
172+
# Create a section and append it to the list
173+
sections.append(Section(name, None, CLASS_LIMIT, level, None))
174+
175+
# Decrement the count in subject_availability_dict
176+
subject_availability_dict[name] -= 1
177+
# Decrement the count in class_count_dict
178+
class_count_dict[class_name] -= 1
179+
# If the count reaches zero, remove it from the dictionary
180+
if subject_availability_dict[name] <= 0:
181+
del subject_availability_dict[name]
182+
break
183+
184+
# print(sections)
185+
186+
# Add any remaining counts to overflow_dict
187+
for class_name, count in class_count_dict.items():
188+
if count > 0:
189+
# print("Adding to overflow dict: ", class_name, count)
190+
overflow_dict[class_name] = count
191+
192+
return sections, overflow_dict
101193

102194

103195
def main():
@@ -107,15 +199,73 @@ def main():
107199

108200
# Create buckets for each subject
109201
buckets = make_buckets(students)
202+
buckets.set_class_count()
110203

111204
# Print the students and their buckets
112205
print(len(students), "students loaded.")
113206
print(buckets)
114207

115208
# Print instructors and classes
116209
print(len(instructors), "instructors loaded.")
210+
subject_availability_dict = {}
117211
for instructor in instructors:
118212
print(instructor)
213+
subject_availability_dict[instructor.subject] = instructor.sections if not subject_availability_dict.get(instructor.subject) else subject_availability_dict[instructor.subject] + instructor.sections
214+
215+
print(subject_availability_dict)
216+
217+
class_count_dict = buckets.get_class_count()
218+
219+
for class_name, count in class_count_dict.items():
220+
print(f"{class_name}: {count} sections needed")
221+
222+
# Generate total counts of each class (both available and required)
223+
224+
english_required_dict = {key: value for key, value in class_count_dict.items() if "English" in key}
225+
math_required_dict = {key: value for key, value in class_count_dict.items() if "Math" in key}
226+
asl_required_dict = {key: value for key, value in class_count_dict.items() if "ASL" in key}
227+
228+
# Create section objects
229+
print("Creating sections...")
230+
if sum(english_required_dict.values()) <= subject_availability_dict.get("Essential Communication", 0):
231+
english_sections = create_sections_easy(english_required_dict)
232+
english_overflow = {}
233+
else:
234+
# print("Hard english")
235+
english_sections, english_overflow = create_sections_hard(english_required_dict, subject_availability_dict, "Essential Communication")
236+
if sum(math_required_dict.values()) <= subject_availability_dict.get("Technical Math", 0):
237+
math_sections = create_sections_easy(math_required_dict)
238+
math_overflow = {}
239+
else:
240+
# print("Hard math")
241+
math_sections, math_overflow = create_sections_hard(math_required_dict, subject_availability_dict, "Technical Math")
242+
if sum(asl_required_dict.values()) <= subject_availability_dict.get("ASL", 0):
243+
asl_sections = create_sections_easy(asl_required_dict)
244+
asl_overflow = {}
245+
else:
246+
# print("Hard asl")
247+
asl_sections, asl_overflow = create_sections_hard(asl_required_dict, subject_availability_dict, "ASL")
248+
249+
# Combine all sections into one list
250+
all_sections = english_sections + math_sections + asl_sections
251+
all_overflow = {**english_overflow, **math_overflow, **asl_overflow}
252+
print(all_overflow)
253+
# Print the sections
254+
print("Sections created:")
255+
for section in all_sections:
256+
print(section)
257+
258+
259+
# Assign classes to the instructors
260+
for instructor in instructors:
261+
if instructor.sections > 0:
262+
for class_name, count in class_count_dict.items():
263+
if instructor.subject == class_name:
264+
265+
instructor.sections -= count
266+
break
267+
268+
119269

120270
def test_instructors():
121271
instructors = load_instructor_csv('instructors.csv')

section.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
from typing import Tuple
2+
from time_block import TimeBlock
3+
from teacher import Teacher
4+
5+
16
class Section:
27
"""
38
Creates a section of a class that students will take
49
Name: Name of the Class, could be seperated into 'name, difficulty'
5-
Time: Available times of the class
10+
Time: Time block of the class
611
Capacity: How many students can take the class
712
"""
8-
def __init__(self, subject, time, capacity, level, teacher):
13+
def __init__(self, subject: str, time: TimeBlock, capacity: int, level: int, teacher: Teacher):
914
self.__subject = subject
1015
self.__time = time
1116
self.__cap = capacity
@@ -49,5 +54,11 @@ def __eq__(self, other):
4954
if isinstance(other, Section):
5055
return self.__subject == other.__subject and self.__time == other.__time and self.__level == other.__level and self.__teacher == other.__teacher
5156
return False
57+
58+
def __str__(self):
59+
return f"Section({self.__subject}, {self.__time}, {self.__cap}, {self.__level}, {self.__teacher})"
60+
61+
def __repr__(self):
62+
return self.__str__()
5263

5364

students.csv

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,4 @@ Lorenza Deckow,3,9,5
2121
Wellington Collier,3,4,9
2222
Derrick Glover V,8,9,4
2323
Quinton Lebsack,7,8,2
24-
Kaya Robel,1,7,6
25-
Lacy Metz,2,3,6
26-
Iliana Boehm,6,8,5
27-
Meaghan Hermann,3,3,9
28-
Kaden DuBuque,8,3,1
29-
Dr. Savion Dach,9,8,8
30-
Anderson Hessel,4,1,4
31-
Cordie Hyatt,2,3,4
32-
Miss Gay McDermott,8,5,3
33-
Fausto Lind,8,6,9
34-
Wilhelmine Pollich MD,8,7,9
35-
Lucinda Walter,7,8,2
36-
Mrs. Bruce Bailey,2,6,7
37-
Bernadine Bauch,8,7,8
38-
Jewell Blick,7,7,1
39-
Aida Kutch DDS,4,6,7
40-
Wiley Borer,4,5,7
41-
Domenick Reinger,5,3,3
42-
Jay Schmitt,6,2,4
43-
Xzavier Waelchi,8,2,1
44-
Viola Bogan,7,5,6
45-
Dr. Carlos Welch,2,7,7
46-
Hailey Borer DDS,2,6,6
47-
Franco Berge,7,9,9
48-
Albert Haag MD,1,4,6
49-
Kirsten Goldner,7,4,8
50-
Russ Herzog,5,4,3
51-
Dallas Kuhic,9,1,1
52-
Paul Beier,4,8,5
53-
Kellie Wuckert,8,6,1
54-
Bridgette Homenick,4,5,7
55-
Paula Graham,6,9,9
56-
Van Ratke PhD,1,1,4
57-
Theodore Maggio,3,2,4
58-
Crawford Casper,3,5,5
59-
Destiny Trantow,4,,8
24+
Kaya Robel,1,7,6

0 commit comments

Comments
 (0)