Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
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.
        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
Ejemplo n.º 7
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. 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
Ejemplo n.º 8
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. 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)
Ejemplo n.º 9
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. 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
Ejemplo n.º 10
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. 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
Ejemplo n.º 11
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. 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
Ejemplo n.º 12
0
 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)
Ejemplo n.º 13
0
 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
Ejemplo n.º 14
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. 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
Ejemplo n.º 15
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.
        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
Ejemplo n.º 16
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. 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
Ejemplo n.º 17
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.
        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
Ejemplo n.º 18
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.
        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
Ejemplo n.º 19
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.
        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
Ejemplo n.º 20
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.
        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
Ejemplo n.º 21
0
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
Ejemplo n.º 22
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]
Ejemplo n.º 23
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
Ejemplo n.º 24
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. 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
Ejemplo n.º 25
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.
        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
Ejemplo n.º 26
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. 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
Ejemplo n.º 27
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. 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