def create_schedule(campus, *args): """ campus: a string - either "St. George", "Scarborough", or "Mississauga" args: strings of course codes e.g. "CSC148", "COG250" Returns a tuple: - the first element is a list of strings containing all possible times (i.e. no conflicts) of combinations of course sections. For the format of the strings, see the process_times() function in the time_conflicts_check module - the second element is a list of strings representing the respective course sections Sample output: (['MONDAY 18:00-20:00 THURSDAY 18:00-21:00 TUESDAY 18:00-21:00 WEDNESDAY 18:00-20:00'], ['CSC148 Lec 5101 CSC148 Lec 5101 CSC165 Lec 5101 CSC165 Lec 5101']) Here, because the lists have length 1, there is only one possible combination of course sections. Note that the sections in the second list are given in the same order as the times in the first list. The times and sections are all delimited by spaces. The output times and sections will be all the schedules comprised of a combination of sections from the input courses with no time conflicts. If no such combinations exist, the return value is a tuple of two empty lists. """ all_times = [] all_sections = [] all_course_times = [] all_course_sections = [] for course_code in args: course_times, course_sections = __get_all_possible_course_times( course_code, campus) all_course_times.append(course_times) all_course_sections.append(course_sections) times_combs = list(itertools.product(*all_course_times)) sections_combs = list(itertools.product(*all_course_sections)) for i in range(len(times_combs)): has_conflicts = False time_comb = times_combs[i] for j in range(0, len(time_comb) - 1): for k in range(j + 1, len(time_comb)): if not time_conflicts_check.no_time_conflict( time_comb[j], time_comb[k]): has_conflicts = True break if has_conflicts: break if has_conflicts: break all_times.append(" ".join(times_combs[i])) all_sections.append(" ".join(sections_combs[i])) return (all_times, all_sections)
def test_no_time_conflict_6(self): assert time_conflicts_check.no_time_conflict( "MONDAY 12:00-14:00 MONDAY 12:00-13:00", "TUESDAY 9:00-10:00")
def test_no_time_conflict_5(self): assert not time_conflicts_check.no_time_conflict( "MONDAY 18:00-20:00", "MONDAY 19:00-20:00")
def test_no_time_conflict_4(self): assert not time_conflicts_check.no_time_conflict( "MONDAY 9:00-12:00", "MONDAY 7:00-8:00 MONDAY 10:00-11:00")
def test_no_time_conflict_3(self): assert time_conflicts_check.no_time_conflict("MONDAY 18:00-20:00", "TUESDAY 18:00-20:00")
def test_no_time_conflict_2(self): assert time_conflicts_check.no_time_conflict( "MONDAY 18:00-20:00 THURSDAY 18:00-21:00", "MONDAY 17:00-18:00")
def __get_all_possible_course_times(course_code, campus): """ course_code: a string e.g. "CSC148" campus: a string - either "St. George", "Scarborough", or "Mississauga" Returns a tuple: - the first element is a list of strings containing all possible times (i.e. no conflicts) of combinations of lecture/tutorial/lab sections. For the format of the strings, see the process_times() function in the time_conflicts_check module - the second element is a list of strings representing the respective lecture, tutorial and lab sections Sample outputs: (['THURSDAY 13:00-16:00', 'THURSDAY 18:00-21:00'], ['CSC108 Lec 0101', 'CSC108 Lec 5101']) Here, because the lists have length 2, there are two possible combinations of course sections. Each of these combinations has only one section - a lecture. (['FRIDAY 14:00-16:00 WEDNESDAY 14:00-16:00 MONDAY 14:00-16:00 MONDAY 16:00-18:00 WEDNESDAY 16:00-18:00'], ['APS105 Lec 0101 APS105 Lec 0101 APS105 Lec 0101 APS105 Tut 0101 APS105 Pra 0101']) Here, because the lists have length 1, there is only one possible combination of course sections. This combination consists of 3 lecture sections, 1 tutorial section, and 1 practical section. Note that the indices of the two lists correspond. For example, the first element of the first list has times that correspond to the class sections in the first element of the second list. """ connection = Database.get_connection(DB_PATH, DB_NAME) cursor = connection.cursor() all_course_data = Database.get_course_data_by_cID_and_campus( cursor, course_code, campus) lecture_times = [] lecture_sections = [] tutorial_times = [] tutorial_sections = [] lab_times = [] lab_sections = [] for course_data in all_course_data: lec_num = course_data[10] lec_comps = lec_num.split(" ") lec_time = course_data[11] thing_to_append = [] for i in range(len(lec_time.split(" ")) // 2): thing_to_append.append(course_code + " " + lec_num) thing_to_append = " ".join(thing_to_append) if lec_comps[0] == "Lec": lecture_times.append(lec_time) lecture_sections.append(thing_to_append) elif lec_comps[0] == "Tut": tutorial_times.append(lec_time) tutorial_sections.append(thing_to_append) elif lec_comps[0] == "Pra": lab_times.append(lec_time) lab_sections.append(thing_to_append) else: # shouldn't happen raise ValueError all_possible_times = [] all_possible_section_combs = [] # course has both tutorial and lab sections if (tutorial_times != []) and (lab_times != []): all_times = list( itertools.product( lecture_times, tutorial_times, lab_times)) # all combinations of lecture/tutorial/lab all_section_combs = list( itertools.product(lecture_sections, tutorial_sections, lab_sections)) for i in range(len(all_times)): if (time_conflicts_check.no_time_conflict( all_times[i][0], all_times[i][1]) # check for internal time conflicts and time_conflicts_check.no_time_conflict( all_times[i][0], all_times[i][2]) and time_conflicts_check.no_time_conflict( all_times[i][1], all_times[i][2])): all_possible_times.append(" ".join(all_times[i])) all_possible_section_combs.append(" ".join( all_section_combs[i])) # course has lab sections but no tutorial sections elif (tutorial_times == []) and (lab_times != []): all_times = list(itertools.product( lecture_times, lab_times)) # all combinations of lecture/lab all_section_combs = list( itertools.product(lecture_sections, lab_sections)) for i in range(len(all_times)): if time_conflicts_check.no_time_conflict( all_times[i][0], all_times[i][1]): # check for internal time conflicts all_possible_times.append(" ".join(all_times[i])) all_possible_section_combs.append(" ".join( all_section_combs[i])) # course has tutorial sections but no lab sections elif (tutorial_times != []) and (lab_times == []): all_times = list(itertools.product( lecture_times, tutorial_times)) # all combinations of lecture/tutorial all_section_combs = [ list(i) for i in list( itertools.product(lecture_sections, tutorial_sections)) ] for i in range(len(all_times)): if time_conflicts_check.no_time_conflict( all_times[i][0], all_times[i][1]): # check for internal time conflicts all_possible_times.append(" ".join(all_times[i])) all_possible_section_combs.append(" ".join( all_section_combs[i])) # course only has lecture sections else: all_possible_times = lecture_times all_possible_section_combs = lecture_sections return (all_possible_times, all_possible_section_combs)