Spaces:
Sleeping
Sleeping
Cleaned up the code, added a BTW message, and changed where I put the deep copy
Browse files- workshops.py +30 -25
workshops.py
CHANGED
@@ -7,8 +7,6 @@ import random
|
|
7 |
import re
|
8 |
from datetime import date
|
9 |
|
10 |
-
from websockets import asyncio
|
11 |
-
|
12 |
import supabase
|
13 |
import json
|
14 |
|
@@ -87,6 +85,7 @@ def convert_df(df, num_timeslots: int):
|
|
87 |
if len(curr_avail) == num_timeslots:
|
88 |
completely_available.append(name)
|
89 |
|
|
|
90 |
else:
|
91 |
curr_avail = [elem.strip() for elem in curr_avail]
|
92 |
availability[name] = curr_avail
|
@@ -105,7 +104,7 @@ def convert_df(df, num_timeslots: int):
|
|
105 |
new_avail_dict[instructor] = availability[instructor]
|
106 |
|
107 |
|
108 |
-
# Sorts the dict such that people who want to teach
|
109 |
pref_dict = {k: v for k, v in sorted(pref_dict.items(), key=lambda item: item[1])}
|
110 |
|
111 |
people = []
|
@@ -143,12 +142,13 @@ def initialize_timeslots(df) -> dict:
|
|
143 |
|
144 |
# Recursive function that generates all possible schedules
|
145 |
def find_all_schedules(people: list, availability: dict, schedule_obj: Schedule, capacity: int, schedules: list, max_timeslots_list: list, max_workshops_list: list) -> None:
|
146 |
-
if schedule_obj.num_timeslots_filled
|
147 |
-
schedules.append(copy.deepcopy(schedule_obj))
|
148 |
max_timeslots_list[0] = schedule_obj.num_timeslots_filled
|
|
|
149 |
# Keep track of total number of workshops taught
|
150 |
-
if schedule_obj.total_num_workshops
|
151 |
max_workshops_list[0] = schedule_obj.total_num_workshops
|
|
|
152 |
|
153 |
# Base case
|
154 |
if len(people) == 0:
|
@@ -215,7 +215,7 @@ def make_df(schedules: list, descrip_dict: dict, og_slots: list):
|
|
215 |
all_times.append("")
|
216 |
all_instructors.append("")
|
217 |
|
218 |
-
if len(schedules)
|
219 |
all_times.append(f"Schedule #{count}")
|
220 |
all_instructors.append("")
|
221 |
count += 1
|
@@ -276,7 +276,7 @@ def get_description_dict(df):
|
|
276 |
# Complete = everyone is teaching desired number of timeslots and each timeslot has at least one workshop
|
277 |
# NOTE: I'm using "valid" instead of "complete" as a variable name so that I don't mix it up
|
278 |
# Incomplete = not complete
|
279 |
-
def classify_schedules(people: list, schedules: list,
|
280 |
valid_schedules = []
|
281 |
|
282 |
# Key: score
|
@@ -287,8 +287,6 @@ def classify_schedules(people: list, schedules: list, partial_names: list, total
|
|
287 |
# Key: person
|
288 |
# Value: number of workshops they WANT to teach
|
289 |
pref_dict = Counter(people)
|
290 |
-
|
291 |
-
pref_dict.update(Counter(partial_names))
|
292 |
|
293 |
all_names = pref_dict.keys()
|
294 |
|
@@ -310,7 +308,7 @@ def classify_schedules(people: list, schedules: list, partial_names: list, total
|
|
310 |
if instructor in freq_dict:
|
311 |
freq_dict[instructor] += 1
|
312 |
else:
|
313 |
-
|
314 |
|
315 |
# See if everyone is teaching their desired number of workshops
|
316 |
everyone_is_teaching = True
|
@@ -328,7 +326,7 @@ def classify_schedules(people: list, schedules: list, partial_names: list, total
|
|
328 |
if len(valid_schedules) > 0:
|
329 |
continue
|
330 |
#print(f"teaching desired number of timeslots: {everyone_is_teaching}. At least one workshop per slot: {filled_all_timeslots}.\n{sched}\n")
|
331 |
-
if sched.num_timeslots_filled
|
332 |
overall_max = sched.num_timeslots_filled
|
333 |
|
334 |
if sched.num_timeslots_filled not in incomplete_schedules:
|
@@ -377,11 +375,8 @@ def get_best_schedules(schedules: list, cutoff: str, max_workshops: int) -> list
|
|
377 |
def main(df, capacity:int, num_results: int, og_slots: list):
|
378 |
descrip_dict = get_description_dict(df)
|
379 |
|
380 |
-
partial_names = []
|
381 |
-
|
382 |
timeslots = initialize_timeslots(df)
|
383 |
total_timeslots = len(timeslots)
|
384 |
-
print(total_timeslots)
|
385 |
schedules = []
|
386 |
schedule_obj = Schedule(timeslots)
|
387 |
|
@@ -390,9 +385,6 @@ def main(df, capacity:int, num_results: int, og_slots: list):
|
|
390 |
people = res['people']
|
391 |
availability = res['availability']
|
392 |
completely_available = res['completely_available']
|
393 |
-
print(', '.join(people))
|
394 |
-
print(availability)
|
395 |
-
print(f"These instructors are completely avaialable: {', '.join(completely_available)}")
|
396 |
|
397 |
|
398 |
|
@@ -402,7 +394,6 @@ def main(df, capacity:int, num_results: int, og_slots: list):
|
|
402 |
for elem in slots:
|
403 |
distinct_slots.add(elem)
|
404 |
num_distinct_slots = len(distinct_slots)
|
405 |
-
print(num_distinct_slots)
|
406 |
|
407 |
|
408 |
max_timeslots_list = [num_distinct_slots]
|
@@ -413,11 +404,26 @@ def main(df, capacity:int, num_results: int, og_slots: list):
|
|
413 |
find_all_schedules(people, availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
|
414 |
|
415 |
|
416 |
-
res = classify_schedules(people, schedules,
|
417 |
valid_schedules = res[0]
|
418 |
decent_schedules = res[1]
|
419 |
|
420 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
# Return schedules
|
422 |
if len(valid_schedules) > 0:
|
423 |
best_schedules = get_best_schedules(valid_schedules, num_results, max_workshops_list[0])
|
@@ -425,20 +431,19 @@ def main(df, capacity:int, num_results: int, og_slots: list):
|
|
425 |
new_df = res[0]
|
426 |
count = res[1]
|
427 |
if count == 1:
|
428 |
-
results = "Good news! I was able to make a complete schedule."
|
429 |
else:
|
430 |
-
results = "Good news! I was able to make multiple complete schedules."
|
431 |
|
432 |
else:
|
433 |
best_schedules = get_best_schedules(decent_schedules, num_results, max_workshops_list[0])
|
434 |
res = make_df(best_schedules, descrip_dict, og_slots)
|
435 |
new_df = res[0]
|
436 |
count = res[1]
|
437 |
-
beginning = "Here"
|
438 |
if count == 1:
|
439 |
-
results = f"
|
440 |
else:
|
441 |
-
results = f"
|
442 |
|
443 |
|
444 |
directory = os.path.abspath(os.getcwd())
|
|
|
7 |
import re
|
8 |
from datetime import date
|
9 |
|
|
|
|
|
10 |
import supabase
|
11 |
import json
|
12 |
|
|
|
85 |
if len(curr_avail) == num_timeslots:
|
86 |
completely_available.append(name)
|
87 |
|
88 |
+
# should I wrap this in an "if" statement? # yes
|
89 |
else:
|
90 |
curr_avail = [elem.strip() for elem in curr_avail]
|
91 |
availability[name] = curr_avail
|
|
|
104 |
new_avail_dict[instructor] = availability[instructor]
|
105 |
|
106 |
|
107 |
+
# Sorts the dict such that people who want to teach fewer workshops are first in the dict
|
108 |
pref_dict = {k: v for k, v in sorted(pref_dict.items(), key=lambda item: item[1])}
|
109 |
|
110 |
people = []
|
|
|
142 |
|
143 |
# Recursive function that generates all possible schedules
|
144 |
def find_all_schedules(people: list, availability: dict, schedule_obj: Schedule, capacity: int, schedules: list, max_timeslots_list: list, max_workshops_list: list) -> None:
|
145 |
+
if schedule_obj.num_timeslots_filled >= max_timeslots_list[0]:
|
|
|
146 |
max_timeslots_list[0] = schedule_obj.num_timeslots_filled
|
147 |
+
|
148 |
# Keep track of total number of workshops taught
|
149 |
+
if schedule_obj.total_num_workshops >= max_workshops_list[0]:
|
150 |
max_workshops_list[0] = schedule_obj.total_num_workshops
|
151 |
+
schedules.append(copy.deepcopy(schedule_obj))
|
152 |
|
153 |
# Base case
|
154 |
if len(people) == 0:
|
|
|
215 |
all_times.append("")
|
216 |
all_instructors.append("")
|
217 |
|
218 |
+
if len(schedules) >= 1:
|
219 |
all_times.append(f"Schedule #{count}")
|
220 |
all_instructors.append("")
|
221 |
count += 1
|
|
|
276 |
# Complete = everyone is teaching desired number of timeslots and each timeslot has at least one workshop
|
277 |
# NOTE: I'm using "valid" instead of "complete" as a variable name so that I don't mix it up
|
278 |
# Incomplete = not complete
|
279 |
+
def classify_schedules(people: list, schedules: list, total_timeslots: int, max_timeslots_filled: int) -> tuple:
|
280 |
valid_schedules = []
|
281 |
|
282 |
# Key: score
|
|
|
287 |
# Key: person
|
288 |
# Value: number of workshops they WANT to teach
|
289 |
pref_dict = Counter(people)
|
|
|
|
|
290 |
|
291 |
all_names = pref_dict.keys()
|
292 |
|
|
|
308 |
if instructor in freq_dict:
|
309 |
freq_dict[instructor] += 1
|
310 |
else:
|
311 |
+
raise Exception("There is a serious issue!!!!")
|
312 |
|
313 |
# See if everyone is teaching their desired number of workshops
|
314 |
everyone_is_teaching = True
|
|
|
326 |
if len(valid_schedules) > 0:
|
327 |
continue
|
328 |
#print(f"teaching desired number of timeslots: {everyone_is_teaching}. At least one workshop per slot: {filled_all_timeslots}.\n{sched}\n")
|
329 |
+
if sched.num_timeslots_filled >= overall_max:
|
330 |
overall_max = sched.num_timeslots_filled
|
331 |
|
332 |
if sched.num_timeslots_filled not in incomplete_schedules:
|
|
|
375 |
def main(df, capacity:int, num_results: int, og_slots: list):
|
376 |
descrip_dict = get_description_dict(df)
|
377 |
|
|
|
|
|
378 |
timeslots = initialize_timeslots(df)
|
379 |
total_timeslots = len(timeslots)
|
|
|
380 |
schedules = []
|
381 |
schedule_obj = Schedule(timeslots)
|
382 |
|
|
|
385 |
people = res['people']
|
386 |
availability = res['availability']
|
387 |
completely_available = res['completely_available']
|
|
|
|
|
|
|
388 |
|
389 |
|
390 |
|
|
|
394 |
for elem in slots:
|
395 |
distinct_slots.add(elem)
|
396 |
num_distinct_slots = len(distinct_slots)
|
|
|
397 |
|
398 |
|
399 |
max_timeslots_list = [num_distinct_slots]
|
|
|
404 |
find_all_schedules(people, availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
|
405 |
|
406 |
|
407 |
+
res = classify_schedules(people, schedules, total_timeslots, max_timeslots_list[0])
|
408 |
valid_schedules = res[0]
|
409 |
decent_schedules = res[1]
|
410 |
|
411 |
|
412 |
+
|
413 |
+
|
414 |
+
# Format "BTW" message
|
415 |
+
if len(completely_available) == 0:
|
416 |
+
btw = ''
|
417 |
+
else:
|
418 |
+
btw = 'BTW, '
|
419 |
+
if len(completely_available) == 1:
|
420 |
+
btw += f"{completely_available[0]} can teach any time."
|
421 |
+
elif len(completely_available) == 2:
|
422 |
+
btw += f"{completely_available[0]} and {completely_available[1]} can teach any time."
|
423 |
+
else:
|
424 |
+
btw += f"{', '.join(completely_available)}can teach any time."
|
425 |
+
btw += " They are NOT in any of the schedules below. Put them where you want!"
|
426 |
+
|
427 |
# Return schedules
|
428 |
if len(valid_schedules) > 0:
|
429 |
best_schedules = get_best_schedules(valid_schedules, num_results, max_workshops_list[0])
|
|
|
431 |
new_df = res[0]
|
432 |
count = res[1]
|
433 |
if count == 1:
|
434 |
+
results = f"Good news! I was able to make a complete schedule. {btw}"
|
435 |
else:
|
436 |
+
results = f"Good news! I was able to make multiple complete schedules. {btw}"
|
437 |
|
438 |
else:
|
439 |
best_schedules = get_best_schedules(decent_schedules, num_results, max_workshops_list[0])
|
440 |
res = make_df(best_schedules, descrip_dict, og_slots)
|
441 |
new_df = res[0]
|
442 |
count = res[1]
|
|
|
443 |
if count == 1:
|
444 |
+
results = f"Here is the best option. {btw}"
|
445 |
else:
|
446 |
+
results = f"Here are the best options. {btw}"
|
447 |
|
448 |
|
449 |
directory = os.path.abspath(os.getcwd())
|