def test_semester_schedule_with_schedule(): student = Student('hpeng2021', 'Michael') student.schedules = {1: {'A': 'glee', 'B': '', 'C': 'see', 'D': 'dee'}} output = student.semester_schedule(1) assert output == student.schedules[1] assert student.semester_schedule(2) is None
def show_schedule(viewer: Student, target: Student, semester: Semester) -> SemesterSchedule: """ Missing blocks means 'Private'; MissingScheduleError means not available """ schedule = target.semester_schedule(semester) if schedule is None: raise MissingScheduleError(target) if target.is_public: return schedule viewer_schedule = viewer.semester_schedule(semester) if viewer_schedule is None: return {} return dict(set(schedule.items()) & set(viewer_schedule.items()))
def _generate_day_events(student: Student, day: datetime.date) -> List[Event]: output = [] time = arrow.get(datetime.datetime.combine(day, START_TIME, TIMEZONE)) for block in BLOCK_SEQ[time.weekday()]: output.append(IcsCalendarCase._generate_event( block, teacher=student.semester_schedule(2)[block], begin=time)) time += BLOCK_LEN + BLOCK_SPACING return output
def show_classmates(self, viewer: Student, semester: Semester, block: Block) -> Iterable[Student]: schedule = viewer.semester_schedule(semester) if schedule is None: raise MissingScheduleError(viewer) roster = self.student_repo.students_in_class(semester, block, schedule[block]) return roster
def show_lunch_number(self, target: Student, semester: Semester, block: Block) -> Optional[LunchNumber]: """ None: teacher does not have this lunch recorded MissingScheduleError: viewer has no schedule """ schedule = target.semester_schedule(semester) if schedule is None: raise MissingScheduleError(target) klass = self.class_repo.load(schedule[block], block, semester) if klass is None: return None return klass.lunch
def match_score(a: Student, b: Student): name_score = ((name_hash(a.name) + name_hash(b.name)) % 117) / 117 shared_classes = 0 for semester in [1, 2]: schedule_a = a.semester_schedule(semester) schedule_b = b.semester_schedule(semester) if schedule_a is None or schedule_b is None: break for block in BLOCKS: if schedule_a[block] == schedule_b[block]: shared_classes += 1 # max theoretical shared classes: BLOCKS*2 # use a sqrt curve classes_score = -4 / (0.8 * shared_classes * shared_classes + 4) + 1 # same grade? grade_score = (3 - abs(a.graduating_year() - b.graduating_year())) / 3 print(f"match score query between {a.handle} and {b.handle}: name_score={name_score:.3f} classes_score={classes_score:.3f} grade_score={grade_score:.3f}") return name_score * 0.4 + classes_score * 0.4 + grade_score * 0.2
def update_lunches(self, student: Student, update: Dict[Semester, SemesterLunches]): batch_update: List[Class] = [] for (semester, lunches) in update.items(): schedule = student.semester_schedule(semester) if schedule is None: raise MissingScheduleError(student) for (block, number) in lunches.items(): batch_update.append( Class(schedule[block], block, semester, lunch=number)) self.class_repo.update_batch(batch_update)
def show_lunchmates(self, viewer: Student, semester: Semester, block: Block, number: LunchNumber) -> Iterable[Student]: schedule = viewer.semester_schedule(semester) if schedule is None: raise MissingScheduleError(viewer) # TODO restrict teachers = self.class_repo.names_of_teachers_in_lunch( semester, block, number) for teacher in teachers: yield from self.student_repo.students_in_class( semester, block, teacher)
def own_schedule(student: Student, semester: Semester) -> SemesterSchedule: output = student.semester_schedule(semester) if output is None: raise MissingScheduleError(student) return output
def test_semester_schedule_without_schedule(): student = Student('hpeng2021', 'Michael') student.schedules = None assert student.semester_schedule(1) is None