From d1057aa8ba548e24d54fd4f84df1939ae46af3f3 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Sun, 26 Jan 2025 21:10:22 +1100 Subject: [PATCH] Add more stats --- features/stats.py | 71 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/features/stats.py b/features/stats.py index 0eb85fd..56b74b5 100644 --- a/features/stats.py +++ b/features/stats.py @@ -1,29 +1,61 @@ -from collections import Counter +from collections import defaultdict from datetime import date + class Stats: def __init__(self, db_connection_method): self.execute = db_connection_method - + def get_stats_from_topsets(self, topsets): if not topsets: return [] - # Extracting necessary fields - workout_ids = [t['WorkoutId'] for t in topsets if t['WorkoutId']] - person_ids = [t['PersonId'] for t in topsets if t['PersonId']] - start_dates = [t['StartDate'] for t in topsets if t['StartDate']] + # Extract necessary fields + workout_ids = [t["WorkoutId"] for t in topsets if t["WorkoutId"]] + person_ids = [t["PersonId"] for t in topsets if t["PersonId"]] + start_dates = [t["StartDate"] for t in topsets if t["StartDate"]] + exercise_ids = [t["ExerciseId"] for t in topsets if t["ExerciseId"]] workout_count = len(set(workout_ids)) people_count = len(set(person_ids)) total_sets = len(topsets) + exercise_count = len(set(exercise_ids)) + + # Group sets by workout and exercise + sets_per_exercise_per_workout = defaultdict(lambda: defaultdict(int)) + for t in topsets: + if t["WorkoutId"] and t["ExerciseId"]: + sets_per_exercise_per_workout[t["WorkoutId"]][t["ExerciseId"]] += 1 + + # Calculate the average sets per exercise across all workouts + total_sets_per_exercise = [] + for workout_exercises in sets_per_exercise_per_workout.values(): + total_sets_per_exercise.extend(workout_exercises.values()) + + average_sets_per_exercise = round(sum(total_sets_per_exercise) / len(total_sets_per_exercise), 1) if total_sets_per_exercise else 0 + + # Group exercises by workout + exercises_by_workout = defaultdict(set) + for t in topsets: + if t["WorkoutId"] and t["ExerciseId"]: + exercises_by_workout[t["WorkoutId"]].add(t["ExerciseId"]) + + # Calculate average exercises per workout + average_exercises_per_workout = round( + sum(len(exercises) for exercises in exercises_by_workout.values()) / workout_count, 1 + ) if workout_count > 0 else 0 + + # Stats stats = [ {"Text": "Total Workouts", "Value": workout_count}, - {"Text": "Total Sets", "Value": total_sets} + {"Text": "Total Sets", "Value": total_sets}, + {"Text": "Total Exercises", "Value": exercise_count}, + {"Text": "Average Sets Per Exercise", "Value": average_sets_per_exercise}, + {"Text": "Average Exercises Per Workout", "Value": average_exercises_per_workout}, ] if people_count > 1: - stats.append({"Text": "People tracked", "Value": people_count}) + stats.append({"Text": "People Tracked", "Value": people_count}) if workout_count > 0: first_workout_date = min(start_dates) @@ -31,53 +63,56 @@ class Stats: current_date = date.today() stats.append({"Text": "Days Since First Workout", - "Value": (current_date - first_workout_date).days}) + "Value": (current_date - first_workout_date).days}) if workout_count >= 2: stats.append({"Text": "Days Since Last Workout", - "Value": (current_date - last_workout_date).days}) + "Value": (current_date - last_workout_date).days}) average_sets_per_workout = round(total_sets / workout_count, 1) - stats.append({"Text": "Average sets per workout", - "Value": average_sets_per_workout}) + stats.append({"Text": "Average Sets Per Workout", + "Value": average_sets_per_workout}) training_duration = last_workout_date - first_workout_date if training_duration.days > 0: average_workouts_per_week = round( workout_count / (training_duration.days / 7), 1) stats.append({"Text": "Average Workouts Per Week", - "Value": average_workouts_per_week}) + "Value": average_workouts_per_week}) return stats - def fetch_stats_for_person(self, person_id): query = """ SELECT t.workout_id AS "WorkoutId", w.person_id AS "PersonId", - w.start_date AS "StartDate" + w.start_date AS "StartDate", + e.exercise_id AS "ExerciseId" FROM topset t JOIN workout w ON t.workout_id = w.workout_id JOIN person p ON w.person_id = p.person_id + JOIN exercise e ON t.exercise_id = e.exercise_id WHERE p.person_id = %s """ workouts_data = self.execute(query, [person_id]) person_stats = self.get_stats_from_topsets(workouts_data) return person_stats - + def fetch_all_stats(self): query = """ SELECT t.workout_id AS "WorkoutId", w.person_id AS "PersonId", - w.start_date AS "StartDate" + w.start_date AS "StartDate", + e.exercise_id AS "ExerciseId" FROM topset t JOIN workout w ON t.workout_id = w.workout_id - JOIN person p ON w.person_id = p.person_id; + JOIN person p ON w.person_id = p.person_id + JOIN exercise e ON t.exercise_id = e.exercise_id """ workouts_data = self.execute(query, [])