diff --git a/utils.py b/utils.py index 698bf21..e58a41a 100644 --- a/utils.py +++ b/utils.py @@ -47,59 +47,76 @@ def get_all_exercises_from_topsets(topsets): return list(exercises_dict.values()) def get_topsets_for_person(person_topsets): - person_exercises = get_all_exercises_from_topsets(person_topsets) + # Group topsets by ExerciseId + grouped_topsets = {} + for topset in person_topsets: + exercise_id = topset['ExerciseId'] + if exercise_id in grouped_topsets: + grouped_topsets[exercise_id].append(topset) + else: + grouped_topsets[exercise_id] = [topset] + # Process each group of topsets exercises_topsets = [] - for e in person_exercises: - exercise_topsets = [t for t in person_topsets if t['ExerciseId'] == e['ExerciseId']] - + for exercise_id, topsets in grouped_topsets.items(): # Sort topsets by StartDate in descending order - sorted_topsets = sorted(exercise_topsets, key=lambda x: x['StartDate'], reverse=True) + sorted_topsets = sorted(topsets, key=lambda x: x['StartDate'], reverse=True) # Extracting values and calculating value ranges for SVG dimensions - estimated_1rm = [t['Estimated1RM'] for t in exercise_topsets] - repetitions = [t['Repetitions'] for t in exercise_topsets] - weight = [t['Weight'] for t in exercise_topsets] - start_dates = [t['StartDate'] for t in exercise_topsets] - messages = [f'{t["Repetitions"]} x {t["Weight"]}kg ({t["Estimated1RM"]}kg E1RM) on {t["StartDate"].strftime("%d %b %y")}' for t in exercise_topsets] + estimated_1rm = [t['Estimated1RM'] for t in sorted_topsets] + repetitions = [t['Repetitions'] for t in sorted_topsets] + weight = [t['Weight'] for t in sorted_topsets] + start_dates = [t['StartDate'] for t in sorted_topsets] + messages = [f'{t["Repetitions"]} x {t["Weight"]}kg ({t["Estimated1RM"]}kg E1RM) on {t["StartDate"].strftime("%d %b %y")}' for t in sorted_topsets] epoch = 'All' - person_id = exercise_topsets[0]['PersonId'] - exercise_id = exercise_topsets[0]['ExerciseId'] + person_id = sorted_topsets[0]['PersonId'] + exercise_name = sorted_topsets[0]['ExerciseName'] - exercise_progress = get_exercise_graph_model(exercise_topsets[0]['ExerciseName'], estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id) + exercise_progress = get_exercise_graph_model(exercise_name, estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id) exercises_topsets.append({ - 'ExerciseId': e['ExerciseId'], - 'ExerciseName': e['ExerciseName'], + 'ExerciseId': exercise_id, + 'ExerciseName': exercise_name, 'Topsets': sorted_topsets, 'ExerciseProgressGraph': exercise_progress }) return exercises_topsets - - def get_people_and_exercise_rep_maxes(topsets, selected_person_ids, selected_exercise_ids, min_date, max_date): - # Get all unique workout_ids (No duplicates) - people_ids = set([t['PersonId'] - for t in topsets]) - filtered_people_ids = [p for p in people_ids if p in selected_person_ids] + # Filter topsets once based on the criteria + filtered_topsets = [ + t for t in topsets if t['PersonId'] in selected_person_ids + and t['ExerciseId'] in selected_exercise_ids + and min_date <= t['StartDate'] <= max_date + ] + + # Group the filtered topsets by PersonId + grouped_by_person = {} + for t in filtered_topsets: + person_id = t['PersonId'] + if person_id in grouped_by_person: + grouped_by_person[person_id].append(t) + else: + grouped_by_person[person_id] = [t] - # Group topsets into workouts people = [] - for person_id in filtered_people_ids: - workouts_for_person = [ - t for t in topsets if t['PersonId'] == person_id and t['ExerciseId'] in selected_exercise_ids and t['StartDate'] >= min_date and t['StartDate'] <= max_date] - if workouts_for_person: - people.append({ - 'PersonId': person_id, - 'PersonName': workouts_for_person[0]['PersonName'], - 'NumberOfWorkouts': len(list(set([t['WorkoutId'] for t in workouts_for_person if t['WorkoutId'] is not None]))), - 'Exercises': get_topsets_for_person(workouts_for_person) - }) + for person_id, person_topsets in grouped_by_person.items(): + person_name = person_topsets[0]['PersonName'] + workout_ids = {t['WorkoutId'] for t in person_topsets if t['WorkoutId']} + number_of_workouts = len(workout_ids) + + people.append({ + 'PersonId': person_id, + 'PersonName': person_name, + 'NumberOfWorkouts': number_of_workouts, + 'Exercises': get_topsets_for_person(person_topsets) + }) + return {"People": people, "Stats": get_stats_from_topsets(topsets)} + def get_stats_from_topsets(topsets): workout_count = len(set([t['WorkoutId'] for t in topsets if t['WorkoutId'] is not None])) @@ -147,9 +164,21 @@ def convert_str_to_date(date_str, format='%Y-%m-%d'): def get_earliest_and_latest_workout_date(person): - if len(person['Workouts']) > 0: - return (min(person['Workouts'], key=lambda x: x['StartDate'])['StartDate'], max(person['Workouts'], key=lambda x: x['StartDate'])['StartDate']) - return (datetime.now().date(), datetime.now().date()) + workouts = person.get('Workouts', []) + if workouts: + # Initialize earliest and latest dates with the first workout's start date + earliest_date = latest_date = workouts[0]['StartDate'] + for workout in workouts[1:]: + date = workout['StartDate'] + if date < earliest_date: + earliest_date = date + if date > latest_date: + latest_date = date + return (earliest_date, latest_date) + + # Return the current date for both if no workouts are present + current_date = datetime.now().date() + return (current_date, current_date) def filter_workout_topsets(workout, selected_exercise_ids): @@ -158,11 +187,6 @@ def filter_workout_topsets(workout, selected_exercise_ids): return workout -def get_exercise_ids_from_workouts(workouts): - return list(set(flatten_list(list(map(lambda x: list( - map(lambda y: y['ExerciseId'], x['TopSets'])), workouts))))) - - def flatten_list(list_of_lists): return [item for sublist in list_of_lists for item in sublist]