diff --git a/analyze_grades.py b/analyze_grades.py
index aa2e9e20f3d40d550e6de94ec531d6ccd03fc324..3eaa57fb576d85c5b53b45f6a823968b2c550974 100755
--- a/analyze_grades.py
+++ b/analyze_grades.py
@@ -49,7 +49,9 @@ def create_semester_filter() -> str:
     return f'1{str(year)[-2:]}{month}'  # introducing a y2.1k problem
 
 
-def select_students_for_material_collection(assignment, student_subset) -> Tuple[CanvasUser, CanvasUser, CanvasUser]:
+def select_students_for_material_collection(assignment,
+                                            scores: Dict[CanvasUser, Optional[float]],
+                                            student_subset) -> Tuple[CanvasUser, CanvasUser, CanvasUser]:
     points_possible: float = assignment.get_points_possible()
     grade_thresholds: Dict[str, float] = {
         'A': 0.93 * points_possible,
@@ -66,37 +68,39 @@ def select_students_for_material_collection(assignment, student_subset) -> Tuple
     c_student: Optional[CanvasUser] = None
     candidates_for_material_collection: Set[CanvasUser] = \
         {student for student in student_subset
-         if assignment.get_score(student) is not None
-         and assignment.get_score(student) >= grade_thresholds['A']}
+         if scores[student] is not None
+         and scores[student] >= grade_thresholds['A']}
     if len(candidates_for_material_collection) == 0:
         candidates_for_material_collection = \
             {student for student in student_subset
-             if assignment.get_score(student) is not None
-             and assignment.get_score(student) >= grade_thresholds['A-']}
+             if scores[student] is not None
+             and scores[student] >= grade_thresholds['A-']}
     if len(candidates_for_material_collection) > 0:
         a_student = candidates_for_material_collection.pop()
     candidates_for_material_collection = \
-        {student for student in student_subset if assignment.get_score(student) is not None
-         and grade_thresholds['B'] <= assignment.get_score(student) < grade_thresholds['B+']}
+        {student for student in student_subset if scores[student] is not None
+         and grade_thresholds['B'] <= scores[student] < grade_thresholds['B+']}
     if len(candidates_for_material_collection) == 0:
         candidates_for_material_collection = \
-            {student for student in student_subset if assignment.get_score(student) is not None
-             and grade_thresholds['B-'] <= assignment.get_score(student) < grade_thresholds['A-']}
+            {student for student in student_subset if scores[student] is not None
+             and grade_thresholds['B-'] <= scores[student] < grade_thresholds['A-']}
     if len(candidates_for_material_collection) > 0:
         b_student = candidates_for_material_collection.pop()
     candidates_for_material_collection = \
-        {student for student in student_subset if assignment.get_score(student) is not None
-         and grade_thresholds['C'] <= assignment.get_score(student) < grade_thresholds['C+']}
+        {student for student in student_subset if scores[student] is not None
+         and grade_thresholds['C'] <= scores[student] < grade_thresholds['C+']}
     if len(candidates_for_material_collection) == 0:
         candidates_for_material_collection = \
-            {student for student in student_subset if assignment.get_score(student) is not None
-             and grade_thresholds['C-'] <= assignment.get_score(student) < grade_thresholds['B-']}
+            {student for student in student_subset if scores[student] is not None
+             and grade_thresholds['C-'] <= scores[student] < grade_thresholds['B-']}
     if len(candidates_for_material_collection) > 0:
         c_student = candidates_for_material_collection.pop()
     return a_student, b_student, c_student
 
 
-def print_sample_scores(assignment: CanvasAssignment, majors: Set[Major],
+def print_sample_scores(assignment: CanvasAssignment,
+                        scores: Dict[CanvasUser, Optional[float]],
+                        majors: Set[Major],
                         major_partitions: Dict[Major, Set[CanvasUser]],
                         students: Optional[List[CanvasUser]] = None) -> None:
     points_possible: float = assignment.get_points_possible()
@@ -104,7 +108,7 @@ def print_sample_scores(assignment: CanvasAssignment, majors: Set[Major],
     b_student: Optional[CanvasUser] = None
     c_student: Optional[CanvasUser] = None
     for major in majors:
-        student_subset: Set[CanvasUser] = major_partitions[major] if students is None \
+        student_subset: Set[CanvasUser] = major_partitions[major].copy() if students is None \
             else major_partitions[major].intersection(students)
         selected_students: Set[CanvasUser] = set()
         if len(student_subset) == 0:
@@ -112,12 +116,14 @@ def print_sample_scores(assignment: CanvasAssignment, majors: Set[Major],
         elif len(student_subset) <= 30:
             print(f'{major.name} has {len(student_subset)} students: reporting scores for all students.')
             selected_students = student_subset
-            a_student, b_student, c_student = select_students_for_material_collection(assignment, student_subset)
+            a_student, b_student, c_student = select_students_for_material_collection(assignment, scores,
+                                                                                      student_subset)
         else:
             print(
                 f'{major.name} has {len(student_subset)} students: reporting scores for 30 randomly-selected students.')
             # let's make sure there are an 'A', a 'B', and a 'C' student in the mix
-            a_student, b_student, c_student = select_students_for_material_collection(assignment, student_subset)
+            a_student, b_student, c_student = select_students_for_material_collection(assignment, scores,
+                                                                                      student_subset)
             for student in (a_student, b_student, c_student):
                 if student is not None:
                     student_subset.remove(student)
@@ -127,27 +133,29 @@ def print_sample_scores(assignment: CanvasAssignment, majors: Set[Major],
                 selected_students.add(student)
         i = 1
         for student in selected_students:
-            print(f'Student {i:>2} -- raw score: {assignment.get_score(student)}'
-                  f'\tscaled score: {100 * assignment.get_score(student) / points_possible}')
+            print(f'Student {i:>2} -- raw score: {scores[student]}'
+                  f'\tscaled score: {100 * scores[student] / points_possible}')
+            i += 1
         print('Collect sample materials --')
-        print(f'"A" student: {a_student.get_name()}')
-        print(f'"B" student: {b_student.get_name()}')
-        print(f'"C" student: {c_student.get_name()}')
-        i += 1
+        print(f'"A" student: {a_student.get_name() if a_student is not None else a_student}')
+        print(f'"B" student: {b_student.get_name() if b_student is not None else b_student}')
+        print(f'"C" student: {c_student.get_name() if c_student is not None else c_student}')
         print()
 
 
-def print_statistics_for_some_majors(assignment: CanvasAssignment, majors: Set[Major],
+def print_statistics_for_some_majors(assignment: CanvasAssignment,
+                                     scores: Dict[CanvasUser, Optional[float]],
+                                     majors: Set[Major],
                                      major_partitions: Dict[Major, Set[CanvasUser]],
                                      students: Optional[List[CanvasUser]] = None) -> None:
     points_possible: float = assignment.get_points_possible()
     for major in majors:
         student_subset: Set[CanvasUser] = major_partitions[major] if students is None \
             else major_partitions[major].intersection(students)
-        scores: List[float] = [assignment.get_score(student) for student in student_subset
-                               if assignment.get_score(student) is not None]
+        valued_scores: List[float] = [scores[student] for student in student_subset
+                                      if scores[student] is not None]
         try:
-            average_score: float = statistics.mean(scores)
+            average_score: float = statistics.mean(valued_scores)
             scaled_average_score: float = 100 * average_score / points_possible
             print(f'{major.name:27}students:{len(major_partitions[major]):>3}   '
                   f'scaled mean score: {scaled_average_score:.2f}%')
@@ -155,20 +163,24 @@ def print_statistics_for_some_majors(assignment: CanvasAssignment, majors: Set[M
             print(f'{major.name:27}students:{len(major_partitions[major]):>3}   no mean score computed: {exception}')
 
 
-def print_statistics(assignment: CanvasAssignment, major_partitions: Dict[Major, Set[CanvasUser]]) -> None:
+def print_statistics(assignment: CanvasAssignment,
+                     scores: Dict[CanvasUser, Optional[float]],
+                     major_partitions: Dict[Major, Set[CanvasUser]]) -> None:
     if assignment.get_points_possible() == 0:
         print(f'WARNING: {assignment} is a 0-point assignment; cannot compute scaled mean score.')
     else:
         print(f'Statistics for {assignment}:')
         computing_majors: Set[Major] = {major for major in Major.majors if major.is_computing_major}
         non_computing_majors: Set[Major] = {major for major in major_partitions.keys() if not major.is_computing_major}
-        print_statistics_for_some_majors(assignment, computing_majors, major_partitions)
-        print_statistics_for_some_majors(assignment, non_computing_majors, major_partitions)
+        print_statistics_for_some_majors(assignment, scores, computing_majors, major_partitions)
+        print_statistics_for_some_majors(assignment, scores, non_computing_majors, major_partitions)
         print()
-        print_sample_scores(assignment, computing_majors, major_partitions)
+        print_sample_scores(assignment, scores, computing_majors, major_partitions)
 
 
-def print_statistics_by_section(course: CanvasCourse, assignment: CanvasAssignment,
+def print_statistics_by_section(course: CanvasCourse,
+                                assignment: CanvasAssignment,
+                                scores: Dict[CanvasUser, Optional[float]],
                                 major_partitions: Dict[Major, Set[CanvasUser]]) -> None:
     print(f'Statistics for {assignment}:')
     computing_majors: Set[Major] = {major for major in Major.majors if major.is_computing_major}
@@ -182,10 +194,10 @@ def print_statistics_by_section(course: CanvasCourse, assignment: CanvasAssignme
         for student in students:
             non_computing_majors.update({major for major in all_non_computing_majors
                                          if student in major_partitions[major]})
-        print_statistics_for_some_majors(assignment, computing_majors, major_partitions, students)
-        print_statistics_for_some_majors(assignment, non_computing_majors, major_partitions, students)
+        print_statistics_for_some_majors(assignment, scores, computing_majors, major_partitions, students)
+        print_statistics_for_some_majors(assignment, scores, non_computing_majors, major_partitions, students)
         print()
-        print_sample_scores(assignment, computing_majors, major_partitions, students)
+        print_sample_scores(assignment, scores, computing_majors, major_partitions, students)
         print()
 
 
@@ -197,10 +209,18 @@ def assess_assignments(course: CanvasCourse, major_partitions: Dict[Major, Set[C
         assignment_group: CanvasAssignmentGroup = \
             select_from_list(course.get_assignment_groups(), 'assignment group')
         oat_assignment: CanvasAssignment = select_from_list(assignment_group.get_assignments(), 'assignment')
+        assignment_scores: Dict[CanvasUser, Optional[float]] = {}
+        print('Retrieving scores ', end='')
+        sys.stdout.flush()
+        for student in course.get_students():
+            print('.', end='')
+            sys.stdout.flush()
+            assignment_scores[student] = oat_assignment.get_score(student)
+        print()
         if not print_section_statistics:
-            print_statistics(oat_assignment, major_partitions)
+            print_statistics(oat_assignment, assignment_scores, major_partitions)
         else:
-            print_statistics_by_section(course, oat_assignment, major_partitions)
+            print_statistics_by_section(course, oat_assignment, assignment_scores, major_partitions)
         print()
         answer = input('Assess additional assignments? [Y/n] ')