def _sort_group(self, list_of_students: List[Student], survey: Survey) -> Group: """ Returns a Group of students with length equal or less than self.group_size. With a given list of Student: 1. select the first student in the list that hasn't already been put into a group and put this student in a new group_list. 2. select the student in the list that hasn't already been put into group_list that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group_list. 3. repeat steps 1 - 2 until length of group_list is equal or less than self.group_size For every student added to group_list, they should also be removed from the original given list. === Precondition === <list_of_students> is not empty """ group_list = [list_of_students.pop(0)] score = 0.0 while (len(group_list) < self.group_size) and \ (len(list_of_students) != 0): best_student = list_of_students[0] for student in list_of_students: group_list.append(student) if survey.score_students(group_list) > score: score = survey.score_students(group_list) best_student = student group_list.remove(student) group_list.append(best_student) list_of_students.remove(best_student) return Group(group_list)
def _find_best_window(self, survey: Survey, windows_: List[List[Any]], lst_students: List[Student]) -> List: """" Return a list, first element is the new group to be added to window, second element is the new windows list """ for index, window in enumerate(windows_): if index + 1 == len(windows_): wind_curr_score = survey.score_students(window) wind_first = survey.score_students(windows_[0]) if wind_curr_score >= wind_first: new_lst = self._new_windows(window, lst_students) return [window, new_lst] else: window = windows_[0] new_lst = self._new_windows(window, lst_students) return [window, new_lst] else: wind_curr_score = survey.score_students(window) wind_next_score = survey.score_students(windows_[index + 1]) if wind_curr_score >= wind_next_score: new_lst = self._new_windows(window, lst_students) return [window, new_lst] return None
def _window_helper(self, lst_windows: list, survey: Survey, students: list, grouping: Grouping) -> None: ''' For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. ''' i = 0 found = False while i < len(lst_windows) and not found: window = lst_windows[i] score = survey.score_students(window) if i == len(lst_windows) - 1: next_score = survey.score_students(lst_windows[0]) else: next_score = survey.score_students(lst_windows[i + 1]) if score >= next_score: found = True group = Group(window) for member in window: students.remove(member) grouping.add_group(group) lst_windows = windows(students, self.group_size) else: i += 1
def test_score_students() -> None: q = CheckboxQuestion(1, "choose", [1, 2, 3, 4]) s1 = Student(1, "John") s2 = Student(2, "Carl") s3 = Student(3, "Anne") a1 = Answer([1, 2, 3, 4]) a2 = Answer([1]) a3 = Answer([1]) s1.set_answer(q, a1) s2.set_answer(q, a2) s3.set_answer(q, a3) c = LonelyMemberCriterion() sur = Survey([q]) sur.set_weight(1, q) sur.set_criterion(c, q) assert sur.score_students([s1, s2, s3]) == 0.0 q_2 = CheckboxQuestion(2, "choose", [1, 2, 3, 4]) a4 = Answer([1, 2]) a5 = Answer([1, 2]) a6 = Answer([1, 2]) s1.set_answer(q_2, a4) s2.set_answer(q_2, a5) s3.set_answer(q_2, a6) sur1 = Survey([q_2]) sur2 = Survey([q, q_2]) sur2.set_weight(1, q_2) sur2.set_criterion(c, q_2) assert sur1.score_students([s1, s2, s3]) == 1 assert sur2.score_students([s1, s2, s3]) == 0.5
def bigval(s: List[Student], lst: List[Student], survey: Survey) -> Any: bigval = -99999 big = None for i in lst: if survey.score_students(s + [i]) > bigval: big = i bigval = survey.score_students(s + [i]) return big
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ grouping = Grouping() students = list(course.get_students()) lst = list() add_score = None next_student = None curr_score = 0.0 while len(students) > 0: if len(lst) == 0: student = students[0] lst.append(student) students.remove(student) curr_score = survey.score_students(lst) continue for student in students: lst.append(student) score = survey.score_students(lst) if add_score is None: add_score = score - curr_score next_student = student elif score - curr_score > add_score: add_score = score - curr_score next_student = student lst.remove(student) lst.append(next_student) if len(lst) == self.group_size or len(students) == 0: grouping.add_group(Group(lst)) lst = list() add_score = None next_student = None curr_score = 0.0 return grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ # TODO: complete the body of this method stu = list(course.get_students()) g = Grouping() while len(stu) > self.group_size: wds = windows(stu, self.group_size) for i in range(len(wds)): curr_score1 = survey.score_students(wds[i]) if i == len(wds) - 1: idx_next = 0 else: idx_next = i + 1 curr_score2 = survey.score_students(wds[idx_next]) if curr_score1 >= curr_score2: g.add_group(Group(wds[i])) #remove students that are assigned group from the stu list for s in wds[i]: stu.remove(s) break if 0 < len(stu) <= self.group_size: g.add_group(Group(stu)) return g
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ if len(course.students) <= self.group_size: g = Grouping() group = Group(course.students.copy()) g.add_group(group) return g lst = course.students.copy() win = windows(lst, self.group_size) g = Grouping() while True: for i in range(0, len(win)): if i + 1 < len(win): if survey.score_students(win[i]) >= survey.score_students(win[i+1]): group = Group(win[i]) g.add_group(group) for p in win[i]: lst.remove(p) break else: group = Group(win[i]) g.add_group(group) for p in win[i]: lst.remove(p) break if len(lst) <= self.group_size: group = Group(lst) g.add_group(group) return g win = windows(lst, self.group_size)
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ # assuming list is sorted by id as per get_students() docstring all_students = list(course.get_students()) final_grouping = Grouping() while len(all_students) != 0: my_windows = windows(all_students, self.group_size) index_found = -1 i = 0 while i in range(len(my_windows) - 1) and index_found == -1: score_i = survey.score_students(my_windows[i]) score_j = survey.score_students(my_windows[i + 1]) if score_i >= score_j: index_found = i if index_found == -1: group_to_add = Group(my_windows[-1]) final_grouping.add_group(group_to_add) else: group_to_add = Group(my_windows[0]) final_grouping.add_group(group_to_add) for student in group_to_add.get_members(): all_students.remove(student) return final_grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ grouping = Grouping() student_list = list(course.get_students()) while student_list != []: if len(student_list) < self.group_size: grouping.add_group(Group(student_list)) student_list = [] window = windows(student_list, self.group_size) window_length = len(window) for i in range(0, window_length): if i == (window_length - 1): win3 = survey.score_students(window[0]) win4 = survey.score_students(window[i]) if win4 >= win3: grouping.add_group(Group(window[i])) for j in range(0, len(window[i])): student_list.remove(window[i][j]) break win1 = survey.score_students(window[i]) win2 = survey.score_students(window[i + 1]) if win1 >= win2: grouping.add_group(Group(window[i])) for j in range(0, len(window[i])): student_list.remove(window[i][j]) break return grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ grouping = Grouping() list_of_students = list(course.get_students()) list_of_groups = [] index = 0 windowed_list = windows(list_of_students, self.group_size) while index < len(windowed_list): if index + 1 == len(windowed_list): score1 = survey.score_students(windowed_list[index]) score2 = survey.score_students(windowed_list[0]) else: score1 = survey.score_students(windowed_list[index]) score2 = survey.score_students(windowed_list[index + 1]) if score1 >= score2: list_of_groups.append(windowed_list[index]) for student in windowed_list[index]: list_of_students.remove(student) windowed_list = windows(list_of_students, self.group_size) index = 0 elif score1 < score2: index += 1 for group in list_of_groups: grouping.add_group(Group(group)) if len(list_of_students) != 0: grouping.add_group(Group(list_of_students)) return grouping
def _grouper_helper(self, to_add: List, students: List, survey: Survey)\ -> None: while len(to_add) < self.group_size and len(students) != 0: current_score = survey.score_students(to_add) new = survey.score_students(to_add + [students[0]]) max_delta = new - current_score best_student = students[0] for student in students: comparator = to_add + [student] new_score = survey.score_students(comparator) delta = new_score - current_score if delta > max_delta: max_delta = delta best_student = student to_add.append(best_student) students.remove(best_student)
def find_local_max_window(self, students_list: List[Student], survey: Survey) -> List[Student]: """ Find the first window of size group_size with the highest score before and after """ student_windows = windows(students_list, self.group_size) # For each window and index for i, window in enumerate(student_windows): # If we're at last window, this has to be max if i == len(student_windows) - 1: return window # Check score of current window and next one if survey.score_students(window) > survey.score_students( student_windows[i + 1]): return window
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ students = list(course.get_students()) grouping = Grouping() while len(students) != 0: window = windows(students, self.group_size) if len(window) == 1: group = Group(window[0]) grouping.add_group(group) for student in window[0]: students.remove(student) for index in range(len(window)): first = window[index] if index == len(window) - 1: second = window[0] else: second = window[index + 1] first_score = survey.score_students(first) second_score = survey.score_students(second) if first_score >= second_score: group = Group(first) grouping.add_group(group) for student in first: students.remove(student) break return grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ # TODO: complete the body of this method stu = list(course.get_students()) stu_size = len(stu) g = Grouping() while stu != []: if (stu_size - len(stu)) % self.group_size == 0: first_stu = stu.pop(0) new_group = Group([first_stu]) if self.group_size == 1: g.add_group(new_group) continue curr_max_score = -1000 for candidate in stu: test_group = new_group.get_members() + [candidate] score = survey.score_students(test_group) if score > curr_max_score: curr_max_score = score curr_best_candidate = candidate if stu: new_group._members.append(curr_best_candidate) stu.remove(curr_best_candidate) if len(new_group._members) == self.group_size: g.add_group(new_group) if 0 < len(new_group) <= self.group_size: g.add_group(new_group) return g
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ students = list(course.get_students()) grouping = Grouping() while len(students) > 0: wins = windows(students, self.group_size) next_wins = None for i in range(len(wins)): score = survey.score_students(wins[i]) if i == len(wins) - 1: next_score = survey.score_students(wins[0]) else: next_score = survey.score_students(wins[i + 1]) if score >= next_score: grouping.add_group(Group(wins[i])) next_wins = wins[i] break for student in next_wins: students.remove(student) return grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ all_students = list(course.get_students()) final_grouping = Grouping() grouped_students = [] # need to check if empty while len(all_students) != 0: student = all_students.pop(0) if len(grouped_students) == self.group_size: group_to_add = Group(grouped_students) final_grouping.add_group(group_to_add) grouped_students = [] grouped_students.append(student) best_score = -1 best_student = student for partner in all_students: potential_score = survey.score_students(grouped_students + [partner]) if potential_score > best_score: best_student = partner best_score = potential_score grouped_students.append(best_student) all_students.remove(best_student) if len(grouped_students) != 0: group_to_add = Group(grouped_students) final_grouping.add_group(group_to_add) return final_grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ students_list = list(course.get_students()) return_grouping = Grouping() while len(students_list) > 0: st = students_list.pop(0) group_students = [st] for _ in range(1, self.group_size): # Find a list of tuples of (student, score) scores = [(other_st, survey.score_students(group_students + [other_st])) for j, other_st in enumerate(students_list)] # Find max student (max_st, _) = max(scores, key=lambda item: item[1]) # Then add it (also remove from original list) students_list.remove(max_st) group_students.append(max_st) return_grouping.add_group(Group(group_students)) return return_grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ tup_students = course.get_students() free_students = list(tup_students) grouping = Grouping() while len(free_students) > self.group_size: first_student = free_students.pop(0) group = [first_student] while not len(group) == self.group_size: group_scores = {} for student in free_students: try_group = group + [student] score = survey.score_students(try_group) group_scores[score] = student max_score = max(group_scores.keys()) next_student = group_scores[max_score] group.append(next_student) free_students.remove(next_student) group = Group(group) grouping.add_group(group) last_group = Group(free_students) grouping.add_group(last_group) return grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ # TODO: complete the body of this method students = list(course.get_students()) grouper = Grouping() members = [] while students: if len(members) == 0: members.append(students.pop(0)) if len(students) == 0: grouper.add_group(Group(members[:])) break if len(members) < self.group_size: score = [] for student in students: score.append(survey.score_students(members + [student])) members.append(students.pop(score.index(max(score)))) if len(members) == self.group_size: grouper.add_group(Group(members[:])) members *= 0 return grouper
def test_survey_survey_score_student() -> None: """A test for score_student() in class Survey.""" q1 = YesNoQuestion(1, 'BBC') q2 = MultipleChoiceQuestion(2, 'ABC', ['A', 'B', 'C']) a1 = Answer(True) a2 = Answer('A') a3 = Answer(True) a4 = Answer('C') stu1 = Student(100, 'Jack') stu2 = Student(200, 'Mike') stu1.set_answer(q1, a1) stu1.set_answer(q2, a2) stu2.set_answer(q1, a3) stu2.set_answer(q2, a4) s = Survey([q1, q2]) c = HomogeneousCriterion() s.set_weight(2.0, q1) s.set_criterion(c, q1) s.set_criterion(c, q2) assert s.score_students([stu1, stu2]) == 1.0
def _get_max_student(lst1: List[Student], lst2: List[Student], survey: Survey) -> Optional[Student]: """ Return the student in lst1 such that when moved him to lst2, the score of survey will be the highest compare to other students in lst1 Precondition: len(lst1) > 0 and len(lst2) > 0 """ if len(lst1) == 0: return None scores = {} for student in lst1: lst2.append(student) new_score = survey.score_students(lst2) if new_score not in scores.keys(): scores[new_score] = [student] else: scores[new_score].append(student) lst2.remove(student) max_students = scores[max(tuple(scores.keys()))] sort_students(max_students, 'id') return max_students[0]
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. # which would make the group the best group 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ to_return = Grouping() lst_of_studs = [] for stud in course.get_students(): lst_of_studs.append(stud) if len(lst_of_studs) == 0: return to_return lst_of_studs = sort_students(lst_of_studs, "id") i = 0 while i < (len(course.get_students()) - 1): group_lst = [] while len(group_lst) != self.group_size and len(lst_of_studs) != 0: # important stopping conditions student1 = lst_of_studs[1] tups_of_scores_and_studs = [] if len(group_lst) == 0: group_lst.append(lst_of_studs[i]) lst_of_studs.pop(i) # first student to add for stud in lst_of_studs: tups_of_scores_and_studs.append( (survey.score_students(group_lst + [stud]), stud)) # appedning the sore of the group with the student lst_of_scores = [] for tup in tups_of_scores_and_studs: lst_of_scores.append(tup[0]) ind_of_highest = lst_of_scores.index(max(lst_of_scores)) # find the index of the tup with this score lst_of_studs.pop( lst_of_studs.index( tups_of_scores_and_studs[ind_of_highest][1])) # removing the student with the highest score from lst of studs group_lst.append(tups_of_scores_and_studs[ind_of_highest][1]) # adding that student to group_lst if student1 not in lst_of_studs: # for starting from beggining i += 1 else: i = 0 if len(group_lst) != 0: group = Group(group_lst) to_return.add_group(group) if len(lst_of_studs) == 0: i += 1 if len(lst_of_studs) != 0: lst = [] for stud in lst_of_studs: lst.append(stud) to_return.add_group(Group(lst)) # for dealing with the remainder return to_return
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ n = self.group_size tup_of_studs = course.get_students() lst_of_studs = [] to_return = Grouping() for stud in tup_of_studs: lst_of_studs.append(stud) if len(lst_of_studs) == 0: return to_return lst_of_studs = sort_students(lst_of_studs, "id") lst_of_windows = windows(lst_of_studs, n) shallow_lst_of_windows = [] for window in lst_of_windows: shallow_lst_of_windows.append(window) i = 0 while i < len(shallow_lst_of_windows) - 1: if survey.score_students(shallow_lst_of_windows[i]) >= \ survey.score_students(shallow_lst_of_windows[i + 1]): to_return.add_group(Group(shallow_lst_of_windows[i])) # add group to grouping for stud in shallow_lst_of_windows[i]: # this avoids repeats lst_of_studs.remove(stud) shallow_lst_of_windows = windows(lst_of_studs, n) i = 0 else: # have to start comparing from the beggining again i += 1 if len(shallow_lst_of_windows) != 0: # comparing the last with the first if survey.score_students(shallow_lst_of_windows[-1]) >= \ survey.score_students(shallow_lst_of_windows[0]): to_return.add_group(Group(shallow_lst_of_windows[-1])) shallow_lst_of_windows.pop(-1) if len(shallow_lst_of_windows) != 0: # if some did not get matched for lst in shallow_lst_of_windows: to_return.add_group(Group(lst)) # want to increment return to_return
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. select the first student in the tuple that hasn't already been put into a group and put this student in a new group. 2. select the student in the tuple that hasn't already been put into a group that, if added to the new group, would increase the group's score the most (or reduce it the least), add that student to the new group. 3. repeat step 2 until there are N students in the new group where N is equal to self.group_size. 4. repeat steps 1-3 until all students have been placed in a group. In step 2 above, use the <survey>.score_students method to determine the score of each group of students. The final group created may have fewer than N members if that is required to make sure all students in <course> are members of a group. """ # TODO: complete the body of this method nameD = course.get_students() scoresD = survey.score_students(nameD) grouping = [] new_group = [] while scoresD != []: new_group.append(nameD[0]) if scoresD[0] == max(scoresD): nameD.remove(nameD[0]) scoresD.remove(scoresD[0]) while len(new_group) < self.group_size and nameD != []: #find the second max score after nameD[0] second_max_index = scoresD.index(max(scoresD)) new_group.append(nameD[second_max_index]) nameD.pop(second_max_index) scoresD.pop(second_max_index) grouping.append(new_group) new_group = [] elif scoresD[0] == min(scoresD): nameD.remove(nameD[0]) scoresD.remove(scoresD[0]) while len(new_group) < self.group_size and nameD != []: #find the second max score after nameD[0] max_index = scoresD.index(max(scoresD)) new_group.append(nameD[max_index]) nameD.pop(max_index) scoresD.pop(max_index) grouping.append(new_group) new_group = [] else: nameD.remove(nameD[0]) scoresD.remove(scoresD[0]) while len(new_group) < self.group_size and nameD != []: if scoresD[0] != max(scoresD): max_index = scoresD.index(max(scoresD)) new_group.append(nameD[max_index]) nameD.pop(max_index) scoresD.pop(max_index) elif scoresD[0] == max(scoresD): scoresD[0].pop(0) nameD[0].pop(0) max_index = scoresD.index(max(scoresD)) new_group.append(nameD[max_index]) nameD.pop(max_index) scoresD.pop(max_index) grouping.append(new_group) new_group = [] return grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ return_groups = [] n = self.group_size # list of all student student = course.get_students() all_student = [] for s in student: all_student.append(s) # list of windows w = windows(list(course.get_students()), n) # grouping in progress in_progress = True while in_progress: # calculate window scores w_score = [] for group in w: w_score.append(survey.score_students(group)) # a counter flag = 0 # w_score = [20, 40, 60, 80] # len(w_score) = 4 # we want to stop at 60 i.e. w_score[2] while flag < len(w_score) - 1: if w_score[flag] > w_score[flag] + 1: return_groups.append(Group(w[flag])) break else: flag += 1 # flag reached last window, add this group directly if flag == len(w_score) - 1: return_groups.append(Group(w[-1])) # remove all students that has a group for group in return_groups: for student in group.get_members(): all_student.remove(student) # get a new list of windows w = windows(list(all_student), n) # left only one window, add to groups directly if len(w) == 1: return_groups.append(Group(w[0])) in_progress = False return_grouping = Grouping() for group in return_groups: return_grouping.add_group(group) return return_grouping
def make_grouping(self, course: Course, survey: Survey) -> Grouping: """ Return a grouping for all students in <course>. Starting with a tuple of all students in <course> obtained by calling the <course>.get_students() method, create groups of students using the following algorithm: 1. Get the windows of the list of students who have not already been put in a group. 2. For each window in order, calculate the current window's score as well as the score of the next window in the list. If the current window's score is greater than or equal to the next window's score, make a group out of the students in current window and start again at step 1. If the current window is the last window, compare it to the first window instead. In step 2 above, use the <survey>.score_students to determine the score of each window (list of students). In step 1 and 2 above, use the windows function to get the windows of the list of students. If there are any remaining students who have not been put in a group after repeating steps 1 and 2 above, put the remaining students into a new group. """ # TODO: complete the body of this method students = list(course.get_students()) grouper = Grouping() index = 0 while students: # If we have students just for one group or less # Then we form group and break and return grouper if len(students) <= self.group_size: grouper.add_group(Group(students[:])) break end = index + self.group_size + 1 # this means we are in the last window # in which case we need to compare it with the first window if end > len(students): current_group = survey.score_students(students[index:end]) next_group = survey.score_students( students[:self.group_size - 1]) if current_group >= next_group: grouper.add_group(Group(students[index:end])) students = [student for student in students if student not in students[index:end]] index = 0 student_windows = windows( students[index:end], self.group_size) current_group = survey.score_students(student_windows[0]) next_group = survey.score_students(student_windows[1]) if current_group >= next_group: grouper.add_group(Group(student_windows[0])) students = [student for student in students if student not in student_windows[0]] else: index += 1 return grouper