def _trim_most_worked_muscles(self, target_time): if self.get_total_time() < target_time: return non_supersets = [_we for _we in self._workout__exercise_list if _we.first_super_set_workout_exercise_id is None] while self.get_total_time() > target_time: # SBL MOVE THIS LOGIC TO ITS OWN FUNCTION muscle_id_to_ring = {} ring_to_count = {} for muscle_id_set in MuscleGroup.get_rings(): muscle_id_tuple = tuple(muscle_id_set) for muscle_id in muscle_id_tuple: muscle_id_to_ring[muscle_id] = muscle_id_tuple ring_to_count[muscle_id_tuple] = 0 for _we in non_supersets: exercise = Exercise.get_by_id(_we.exercise_id) muscle_id_tuple = muscle_id_to_ring[exercise.muscle_group_id] if _we.sets: ring_to_count[muscle_id_tuple] += 1 muscle_ring__count = sorted(ring_to_count.items(), key=lambda t: t[1], reverse=True) for _we in non_supersets: exercise = Exercise.get_by_id(_we.exercise_id) if _we.sets and exercise.muscle_group_id in muscle_ring__count[0][0]: _we.sets = 0 if _we.second_exercise: _we.second_exercise.sets = 0 break
def _get_workout_component_to_exercises(self): workout_component_to_exercises = defaultdict(list) first_exercise_superset = [_we for _we in self._workout__exercise_list if _we.first_super_set_workout_exercise_id is None] second_exercise_superset = [_we for _we in self._workout__exercise_list if _we.first_super_set_workout_exercise_id is not None] for _workout__exercise in first_exercise_superset: exercise = Exercise.get_by_id(_workout__exercise.exercise_id) workout_component_to_exercises[exercise.workout_component_id].append(_workout__exercise) for _workout__exercise in second_exercise_superset: exercise = Exercise.get_by_id(_workout__exercise.exercise_id) for _workout__exercise_initial in workout_component_to_exercises[exercise.workout_component_id]: if _workout__exercise_initial.id == _workout__exercise.first_super_set_workout_exercise_id: _workout__exercise_initial.second_exercise = _workout__exercise break return workout_component_to_exercises
def _generate_workout(day_framework_id, user, workout_component_list, cardio_level, previous_workouts_by_distance): user.workout_logger.log_start_workout(workout_component_list) if not workout_component_list and cardio_level is None: user.workout_logger.log_empty_workout() return EmptyWorkout() cardio_session = None if cardio_level: cardio_session = _generate_cardio(user, cardio_level) user.workout_logger.log_initial_cardio_session(cardio_session) user_exercise_filter = (Exercise(). for_fitness_level(user.fitness_level). for_experience(user.experience). for_phase(user.current_phase_id). for_equipment_list(user.get_available_equipment_ids())) user.workout_logger.log_user_exercise_filter(user_exercise_filter) workout = Workout.create_new(day_framework_id, user.current_phase_id, cardio_session=cardio_session) workout_component_list = [w for w in workout_component_list if w != WorkoutComponent.FLEXIBILITY] today_exercise_filter = _get_today_exercise_filter(user_exercise_filter, previous_workouts_by_distance, logger=user.workout_logger) user.workout_logger.log_initial_today_exercise_filter(today_exercise_filter) max_retries = 5 for workout_component_id in workout_component_list: temp_filter = today_exercise_filter for dead_end_count in xrange(max_retries): rollback_filter_generator = _rollback_filter_generator(user, previous_workouts_by_distance, workout_component_id) try: _add_exercises_for_component(workout_component_id, temp_filter, user, workout, rollback_filter_generator=rollback_filter_generator) break except DeadEndException: user.workout_logger.log_recreate_filter() temp_filter = _get_today_exercise_filter(user_exercise_filter, previous_workouts_by_distance, retry_count=dead_end_count, logger=user.workout_logger) user.workout_logger.log_retry_today_exercise_filter(temp_filter) # re-gain state with temp_filter today_exercise_filter = Exercise.join_and(today_exercise_filter, temp_filter) target_time = user.minutes_per_day cardio_time = (0 if not cardio_session else cardio_session.get_total_time()) skip_workout_component_ids = set() for workout_component_id in (10 * workout_component_list): if workout_component_id in skip_workout_component_ids: continue total_time = cardio_time + workout.get_total_time() if total_time >= target_time - 5: break user.workout_logger.log_add_more_time(target_time, total_time, workout_component_id) try: _add_exercises_for_component(workout_component_id, today_exercise_filter, user, workout, force_one=True) except (DeadEndException, MaxVolumeReached) as e: user.workout_logger.log_no_more_for_component(workout_component_id, e) skip_workout_component_ids.add(workout_component_id) continue _add_flexibility_to_workout(workout, user_exercise_filter.copy(), logger=user.workout_logger) user.workout_logger.log_finish_workout(workout) return workout
def _trim_lonely_muscle_groups(self, target_time): if self.get_total_time() < target_time: return non_supersets = [_we for _we in self._workout__exercise_list if _we.first_super_set_workout_exercise_id is None] muscle_id_to_ring = {} ring_to_count = {} for muscle_id_set in MuscleGroup.get_rings(): muscle_id_tuple = tuple(muscle_id_set) for muscle_id in muscle_id_tuple: muscle_id_to_ring[muscle_id] = muscle_id_tuple ring_to_count[muscle_id_tuple] = 0 for _we in non_supersets: exercise = Exercise.get_by_id(_we.exercise_id) muscle_id_tuple = muscle_id_to_ring[exercise.muscle_group_id] ring_to_count[muscle_id_tuple] += 1 for muscle_ring, count in ring_to_count.items(): if count == 1: for _we in non_supersets: _we.sets = 0 if self.get_total_time() < target_time: break else: continue break
def get_total_time(self): total_time = 0.0 workout_component_to_exercises = self._get_workout_component_to_exercises() for workout_component_id, exercise_list in workout_component_to_exercises.items(): if workout_component_id == WorkoutComponent.FLEXIBILITY: continue workout_component = WorkoutComponent.get_by_id(workout_component_id) for _workout__exercise in exercise_list: seconds_rest = workout_component.get_rest(self.phase) minutes_rest = float(seconds_rest) / 60 minutes_rest *= _workout__exercise.sets total_time += minutes_rest for _we in [_workout__exercise, _workout__exercise.second_exercise]: if _we is None: continue exercise = Exercise.get_by_id(_we.exercise_id) if exercise.timed: total_time += _we.sets * SECONDS_FOR_TIMED_EXERCISE / 60.0 else: total_reps = _we.reps * _we.sets rep_minutes = total_reps * self.phase.tempo.seconds_per_rep / 60.0 total_time += rep_minutes total_time *= TIME_FUDGE_FACTOR return total_time
def get_rep_prescriptions_for_muscle(self, muscle_id): rep_list = [] for _workout__exercise in self._workout__exercise_list: exercise = Exercise.get_by_id(_workout__exercise.exercise_id) if exercise.muscle_group_id == muscle_id: rep_list.append(_workout__exercise.reps) return rep_list
def get_muscle_ids_used(self): muscle_ids = self.get_primary_muscle_ids_used() for _workout__exercise in self._workout__exercise_list: exercise = Exercise.get_by_id(_workout__exercise.exercise_id) muscle_ids.extend(exercise.muscle_group_ids) muscle_ids = list(set(muscle_ids)) return muscle_ids
def get_primary_muscle_ids_used(self, workout_component_id=None): muscle_ids = [] for _workout__exercise in self._workout__exercise_list: exercise = Exercise.get_by_id(_workout__exercise.exercise_id) if workout_component_id is None or exercise.workout_component_id == workout_component_id: muscle_ids.append(exercise.muscle_group_id) muscle_ids = list(set(muscle_ids)) return muscle_ids
def get_exercise_ids_used(self, workout_component_id=None): exercise_ids = [] for _we in self._workout__exercise_list: if workout_component_id: exercise = Exercise.get_by_id(_we.exercise_id) if exercise.workout_component_id != workout_component_id: continue exercise_ids.append(_we.exercise_id) return exercise_ids
def _trim_isolated_exercises(self, target_time): if self.get_total_time() < target_time: return non_supersets = [_we for _we in self._workout__exercise_list if _we.first_super_set_workout_exercise_id is None] for _we in non_supersets: exercise = Exercise.get_by_id(_we.exercise_id) if not _we.second_exercise and exercise.compound: _we.sets = 0 if self.get_total_time() < target_time: break
def _prioritize_unused_muscle_groups(today_exercise_filter, previous_workouts_by_distance): component_filters = [] for workout_component_id in WorkoutComponent.WORKOUT_ORDER: muscle_tuple_to_should_use = _get_muscle_tuple_to_should_use(today_exercise_filter, workout_component_id) _discard_or_reset_muscle_tuples(muscle_tuple_to_should_use, previous_workouts_by_distance, workout_component_id) remaining_muscle_group_ids = _get_remaining_muscle_groups(muscle_tuple_to_should_use) non_repeating_component_filter = (today_exercise_filter.copy(). for_workout_component(workout_component_id). restrict_to_muscle_group_ids(remaining_muscle_group_ids)) component_filters.append(non_repeating_component_filter) non_repeating_exercise_filter = Exercise.join(*component_filters) return non_repeating_exercise_filter
def _workout__exercise_to_json(self, _workout__exercise): if _workout__exercise is None: return None if _workout__exercise.first_super_set_workout_exercise_id is None and _workout__exercise.sets == 0: # sets can be reduced to 0 via time trimming return None return { "exercise": Exercise.get_by_id(_workout__exercise.exercise_id).to_json(), "reps": _workout__exercise.reps, "sets": _workout__exercise.sets, "superset": self._workout__exercise_to_json(_workout__exercise.second_exercise) }