def _select_exercise(exercise_filter, previous_exercise=None, retry_mode=False, logger=None): logger = logger or mock.MagicMock() if previous_exercise is not None: for related_muscle_group_set in MuscleGroup.get_rings(): if previous_exercise.muscle_group_id in related_muscle_group_set: logger.log_muscle_restriction(previous_exercise, related_muscle_group_set) exercise_filter.restrict_to_muscle_group_ids(related_muscle_group_set) break elif not retry_mode: logger.log_retry_mode() exercise_filter = exercise_filter.compound_only() elif retry_mode and previous_exercise is None: logger.log_rollback_mode() rollback_filter = exercise_filter.copy() exercise_filter = exercise_filter.compound_only() if exercise_filter.count() == 0: exercise_filter = rollback_filter if exercise_filter.count() == 0: raise DeadEndException("Need a bigger exercise pool to continue") exercise_list = [exercise for exercise in exercise_filter.query] logger.log_available_exercises(exercise_list) exercise_list = evenly_distribute_exercises_by_muscle_group(exercise_list) try: exercise = random.choice(exercise_list) except IndexError: raise NoExercisesAvailableException("No exercises left") logger.log_exercise_selection(exercise) return exercise
def test_evenly_distribute_exercises_by_muscle_group(self): exercise_list = Exercise().query distributed_exercise_list = evenly_distribute_exercises_by_muscle_group(exercise_list) muscle_group_counts = defaultdict(int) for exercise in distributed_exercise_list: muscle_group_counts[exercise.muscle_group_id] += 1 for count in muscle_group_counts.values(): self.assertEqual(count, 100)
def _select_superset_exercise(self, first_exercise): self.superset_filter.discard_exercise_id(first_exercise.id) self.superset_filter.discard_mutually_exclusive(first_exercise.id) possible_muscle_ids = [first_exercise.muscle_group_id] possible_muscle_ids += MuscleGroup.ALLOWABLE_RELATED_FOR_SUPERSETS.get(first_exercise.muscle_group_id, []) exercise_filter = self.superset_filter.copy().restrict_to_muscle_group_ids(possible_muscle_ids) exercise_list = [exercise for exercise in exercise_filter.query] self.logger.log_available_superset_exercise(exercise_list) exercise_list = evenly_distribute_exercises_by_muscle_group(exercise_list) try: exercise = random.choice(exercise_list) except IndexError: exercise = None self.logger.log_superset_exercise(exercise) return exercise