Juggling commited on
Commit
17a32d1
·
verified ·
1 Parent(s): e50158b

Sorting availability dict by how available people are to teach

Browse files
Files changed (1) hide show
  1. workshops.py +59 -35
workshops.py CHANGED
@@ -63,17 +63,50 @@ def can_teach(person: str, slot: list, capacity: int) -> bool:
63
 
64
 
65
  # Extracts relevant information from the df with availability and puts it into a useable format
66
- def convert_df(df):
67
- people = []
68
  # Key: person's name
69
  # Value: a list of their availability
70
  availability = {}
71
- seen = set()
 
 
 
 
 
 
 
 
72
  for row in range(len(df)):
73
- # TODO: make sure no people with the same name fill out the form
74
  name = df.loc[row, NAME_COL]
 
 
 
 
 
75
 
76
- number = df.loc[row, NUM_WORKSHOPS_COL]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  if number == 1:
78
  people.append(name)
79
 
@@ -82,12 +115,8 @@ def convert_df(df):
82
  for i in range(number):
83
  people.append(name)
84
 
85
- curr_avail = df.loc[row, AVAIL_COL]
86
- curr_avail = curr_avail.split(DELIMITER)
87
- curr_avail = [elem.strip() for elem in curr_avail]
88
- availability[name] = curr_avail
89
 
90
- return people, availability
91
 
92
 
93
 
@@ -141,13 +170,12 @@ def find_all_schedules(people: list, availability: dict, schedule_obj: Schedule,
141
  # Unchoose (remove that person from the timeslot)
142
  schedule_obj.remove(person, time)
143
  # NOTE: this will not generate a full timeslot, but could still lead to a good schedule
144
- '''
145
  else:
146
  if len(people) == 1:
147
  find_all_schedules([], availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
148
  else:
149
  find_all_schedules(people[1:len(people)], availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
150
- '''
151
 
152
  return
153
 
@@ -242,7 +270,7 @@ def get_description_dict(df):
242
 
243
 
244
  # Classifies schedules into two categories: complete and incomplete:
245
- # Complete = everyone is teaching desired number of timeslots and each timeslot is filled
246
  # NOTE: I'm using "valid" instead of "complete" as a variable name so that I don't mix it up
247
  # Incomplete = not complete
248
  def classify_schedules(people: list, schedules: list, partial_names: list, total_timeslots: int, max_timeslots_filled: int) -> tuple:
@@ -345,43 +373,41 @@ def get_best_schedules(schedules: list, cutoff: str, max_workshops: int) -> list
345
  # Big wrapper function that calls the other functions
346
  def main(df, capacity:int, num_results: int, og_slots: list):
347
  descrip_dict = get_description_dict(df)
348
-
349
- # Convert the df with everyone's availability to a usable format
350
- res = convert_df(df)
351
- people = res[0]
352
- availability = res[1]
353
-
354
- # Sorts a dictionary by length of the values such that the
355
- # key associated with the shortest value is first in the list {orders}
356
- order = sorted(availability, key=lambda k: len(availability[k]))
357
-
358
- # The idea is start with people who are the LEAST available to teach,
359
- # then put the more available instructors into the available slots
360
- new_dict = {}
361
- for instructor in order:
362
- new_dict[instructor] = availability[instructor]
363
- availability = new_dict
364
 
365
  partial_names = []
366
 
367
  timeslots = initialize_timeslots(df)
 
 
368
  schedules = []
369
  schedule_obj = Schedule(timeslots)
 
 
 
 
 
 
 
 
 
 
 
370
 
371
  # Get the bare minimum of workshops that will be taught
372
  distinct_slots = set()
373
- for curr_list in availability.values():
374
- for elem in curr_list:
375
  distinct_slots.add(elem)
376
  num_distinct_slots = len(distinct_slots)
 
377
 
378
 
379
  max_timeslots_list = [num_distinct_slots]
380
  max_workshops_list = [num_distinct_slots]
 
381
 
382
- find_all_schedules(people, availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
383
 
384
- total_timeslots = len(timeslots)
385
 
386
 
387
  res = classify_schedules(people, schedules, partial_names, total_timeslots, max_timeslots_list[0])
@@ -411,8 +437,6 @@ def main(df, capacity:int, num_results: int, og_slots: list):
411
  else:
412
  results = f"{beginning} are the best options."
413
 
414
- #results += "(Remember that \"complete\" schedules are ones where everyone is teaching their desired number of workshops and every timeslot is filled.)"
415
-
416
 
417
  directory = os.path.abspath(os.getcwd())
418
  path = directory + "/schedule.csv"
 
63
 
64
 
65
  # Extracts relevant information from the df with availability and puts it into a useable format
66
+ def convert_df(df, num_timeslots: int):
 
67
  # Key: person's name
68
  # Value: a list of their availability
69
  availability = {}
70
+
71
+
72
+ # Key: person's name
73
+ # Value: how many workshops they want to teach
74
+ pref_dict = {}
75
+
76
+ # Instructors who can teach anytime
77
+ completely_available = []
78
+
79
  for row in range(len(df)):
 
80
  name = df.loc[row, NAME_COL]
81
+ curr_avail = df.loc[row, AVAIL_COL]
82
+ curr_avail = curr_avail.split(DELIMITER)
83
+
84
+ if len(curr_avail) == num_timeslots:
85
+ completely_available.append(name)
86
 
87
+ else:
88
+ curr_avail = [elem.strip() for elem in curr_avail]
89
+ availability[name] = curr_avail
90
+ pref_dict[name] = df.loc[row, NUM_WORKSHOPS_COL]
91
+
92
+
93
+ # Sorts a dictionary by length of the values such that the
94
+ # key associated with the shortest value is first in the list {orders}
95
+ order = sorted(availability, key=lambda k: len(availability[k]))
96
+
97
+ # The idea is start with people who are the LEAST available to teach,
98
+ # then put the more available instructors into the available slots
99
+ new_avail_dict = {}
100
+
101
+ for instructor in order:
102
+ new_avail_dict[instructor] = availability[instructor]
103
+
104
+
105
+ # Sorts the dict such that people who want to teach less are first in the dict
106
+ pref_dict = {k: v for k, v in sorted(pref_dict.items(), key=lambda item: item[1])}
107
+
108
+ people = []
109
+ for name,number in pref_dict.items():
110
  if number == 1:
111
  people.append(name)
112
 
 
115
  for i in range(number):
116
  people.append(name)
117
 
 
 
 
 
118
 
119
+ return {'people': people, 'availability': new_avail_dict, 'completely_available': completely_available}
120
 
121
 
122
 
 
170
  # Unchoose (remove that person from the timeslot)
171
  schedule_obj.remove(person, time)
172
  # NOTE: this will not generate a full timeslot, but could still lead to a good schedule
 
173
  else:
174
  if len(people) == 1:
175
  find_all_schedules([], availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
176
  else:
177
  find_all_schedules(people[1:len(people)], availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
178
+
179
 
180
  return
181
 
 
270
 
271
 
272
  # Classifies schedules into two categories: complete and incomplete:
273
+ # Complete = everyone is teaching desired number of timeslots and each timeslot has at least one workshop
274
  # NOTE: I'm using "valid" instead of "complete" as a variable name so that I don't mix it up
275
  # Incomplete = not complete
276
  def classify_schedules(people: list, schedules: list, partial_names: list, total_timeslots: int, max_timeslots_filled: int) -> tuple:
 
373
  # Big wrapper function that calls the other functions
374
  def main(df, capacity:int, num_results: int, og_slots: list):
375
  descrip_dict = get_description_dict(df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
 
377
  partial_names = []
378
 
379
  timeslots = initialize_timeslots(df)
380
+ total_timeslots = len(timeslots)
381
+ print(total_timeslots)
382
  schedules = []
383
  schedule_obj = Schedule(timeslots)
384
+
385
+ # Convert the df with everyone's availability to a usable format
386
+ res = convert_df(df, total_timeslots)
387
+ people = res['people']
388
+ availability = res['availability']
389
+ completely_available = res['completely_available']
390
+ print(', '.join(people))
391
+ print(availability)
392
+ print(f"These instructors are completely avaialable: {', '.join(completely_available)}")
393
+
394
+
395
 
396
  # Get the bare minimum of workshops that will be taught
397
  distinct_slots = set()
398
+ for slots in availability.values():
399
+ for elem in slots:
400
  distinct_slots.add(elem)
401
  num_distinct_slots = len(distinct_slots)
402
+ print(num_distinct_slots)
403
 
404
 
405
  max_timeslots_list = [num_distinct_slots]
406
  max_workshops_list = [num_distinct_slots]
407
+
408
 
 
409
 
410
+ find_all_schedules(people, availability, schedule_obj, capacity, schedules, max_timeslots_list, max_workshops_list)
411
 
412
 
413
  res = classify_schedules(people, schedules, partial_names, total_timeslots, max_timeslots_list[0])
 
437
  else:
438
  results = f"{beginning} are the best options."
439
 
 
 
440
 
441
  directory = os.path.abspath(os.getcwd())
442
  path = directory + "/schedule.csv"