132 lines
5.3 KiB
Python
132 lines
5.3 KiB
Python
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 []
|
|
|
|
# Extract necessary fields
|
|
workout_ids = [t["workout_id"] for t in topsets if t["workout_id"]]
|
|
person_ids = [t["person_id"] for t in topsets if t["person_id"]]
|
|
start_dates = [t["start_date"] for t in topsets if t["start_date"]]
|
|
exercise_ids = [t["exercise_id"] for t in topsets if t["exercise_id"]]
|
|
|
|
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["workout_id"] and t["exercise_id"]:
|
|
sets_per_exercise_per_workout[t["workout_id"]][t["exercise_id"]] += 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["workout_id"] and t["exercise_id"]:
|
|
exercises_by_workout[t["workout_id"]].add(t["exercise_id"])
|
|
|
|
# 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": "Average Sets Per Exercise", "value": average_sets_per_exercise}
|
|
]
|
|
|
|
if exercise_count > 1:
|
|
stats.append({"text": "Total Exercises", "value": exercise_count})
|
|
stats.append({"text": "Average Exercises Per Workout", "value": average_exercises_per_workout})
|
|
|
|
if people_count > 1:
|
|
stats.append({"text": "People Tracked", "value": people_count})
|
|
|
|
if workout_count > 0:
|
|
first_workout_date = min(start_dates)
|
|
last_workout_date = max(start_dates)
|
|
current_date = date.today()
|
|
|
|
stats.append({"text": "Days Since First Workout",
|
|
"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})
|
|
|
|
average_sets_per_workout = round(total_sets / workout_count, 1)
|
|
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})
|
|
|
|
return stats
|
|
|
|
def fetch_stats(self, selected_people_ids=None, min_date=None, max_date=None, selected_exercise_ids=None):
|
|
# Base query
|
|
query = """
|
|
SELECT
|
|
t.workout_id,
|
|
w.person_id,
|
|
w.start_date,
|
|
e.exercise_id
|
|
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
|
|
"""
|
|
|
|
# Parameters for the query
|
|
params = []
|
|
|
|
# Add optional filters
|
|
conditions = [] # Collect conditions dynamically
|
|
if selected_people_ids:
|
|
placeholders = ", ".join(["%s"] * len(selected_people_ids))
|
|
conditions.append(f"p.person_id IN ({placeholders})")
|
|
params.extend(selected_people_ids)
|
|
if min_date:
|
|
conditions.append("w.start_date >= %s")
|
|
params.append(min_date)
|
|
if max_date:
|
|
conditions.append("w.start_date <= %s")
|
|
params.append(max_date)
|
|
if selected_exercise_ids:
|
|
placeholders = ", ".join(["%s"] * len(selected_exercise_ids))
|
|
conditions.append(f"e.exercise_id IN ({placeholders})")
|
|
params.extend(selected_exercise_ids)
|
|
|
|
# Add conditions to the query
|
|
if conditions:
|
|
query += " WHERE " + " AND ".join(conditions)
|
|
|
|
# Execute the query
|
|
workouts_data = self.execute(query, params)
|
|
|
|
# Generate stats from the retrieved data
|
|
stats = self.get_stats_from_topsets(workouts_data)
|
|
return stats
|