From b4ec0ed81f3463684f034e7a7380d16d758b5f63 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Sat, 1 Oct 2022 20:49:16 +1000 Subject: [PATCH] Display workout stats --- app.py | 5 ++-- db.py | 3 ++- templates/base.html | 11 +++++--- templates/index.html | 63 ++++++++++++++++++++++++------------------- templates/person.html | 46 +++++++++++++++++++++++++++++++ utils.py | 59 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 153 insertions(+), 34 deletions(-) diff --git a/app.py b/app.py index b0dae5d..2e87abe 100644 --- a/app.py +++ b/app.py @@ -2,7 +2,7 @@ import os from flask import Flask, render_template, redirect, request, url_for from decorators import validate_person, validate_topset, validate_workout from db import DataBase -from utils import get_people_and_exercise_rep_maxes +from utils import get_people_and_exercise_rep_maxes, get_dashboard_stats app = Flask(__name__) app.config.from_pyfile('config.py') @@ -15,7 +15,8 @@ def dashboard(): all_topsets = db.get_all_topsets() people_and_exercise_rep_maxes = get_people_and_exercise_rep_maxes( all_topsets) - return render_template('index.html', model=people_and_exercise_rep_maxes) + stats = get_dashboard_stats(all_topsets) + return render_template('index.html', model=people_and_exercise_rep_maxes, stats=stats) @ app.route("/person/") diff --git a/db.py b/db.py index b18a555..9597015 100644 --- a/db.py +++ b/db.py @@ -4,7 +4,7 @@ from psycopg2.extras import RealDictCursor from datetime import datetime from urllib.parse import urlparse -from utils import get_all_exercises_from_topsets, get_people_and_exercise_rep_maxes, get_workouts +from utils import get_all_exercises_from_topsets, get_people_and_exercise_rep_maxes, get_workouts, get_person_stats class DataBase(): @@ -145,6 +145,7 @@ class DataBase(): return { 'PersonId': next((t['PersonId'] for t in topsets), -1), 'PersonName': next((t['PersonName'] for t in topsets), 'Unknown'), + 'Stats': get_person_stats(topsets), 'Exercises': get_all_exercises_from_topsets(topsets), 'Workouts': get_workouts(topsets) } diff --git a/templates/base.html b/templates/base.html index 3199176..0199a58 100644 --- a/templates/base.html +++ b/templates/base.html @@ -9,10 +9,15 @@ diff --git a/templates/index.html b/templates/index.html index 914aba7..84eb1ea 100644 --- a/templates/index.html +++ b/templates/index.html @@ -28,6 +28,12 @@ + {% if p['NumberOfWorkouts'] == 0 %} + + {% endif %} + {% for e in p['Exercises'] %}
@@ -84,55 +90,56 @@
-
+
- 3 + {{ stats['TotalWorkouts'] + }}

Total workouts tracked

-
- 14.6% - - - +
+
+
+
+
+ {{ + stats['AverageWorkoutsPerWeek'] + }} +

Avg. weekly workouts

- 1 -

New rep max this week

+ {{ stats['NumberOfPeople'] + }} +

People tracked

-
- 32.9% - - - +
+
+ {% if stats['TotalWorkouts'] > 0 %} +
+
+
+ {{ + stats['DaysSinceFirstWorkout'] + }} +

Days since first workout

- 2 -

Tracking two people

-
-
- -2.7% - - - + {{ stats['DaysSinceLastWorkout'] + }} +

Days since last workout

+ {% endif %}
{% endblock %} \ No newline at end of file diff --git a/templates/person.html b/templates/person.html index c47acaf..110dc3c 100644 --- a/templates/person.html +++ b/templates/person.html @@ -95,4 +95,50 @@
+ +
+
+
+
+ {{ + person['Stats']['NumberOfWorkouts'] }} +

Total workouts tracked

+
+
+
+ +
+
+
+ {{ + person['Stats']['TrainingDurationInDays'] }} +

Duration of workout tracking

+
+
+
+ +
+
+
+ {{ + person['Stats']['AverageWorkoutsPerWeek'] }} +

Average weekly workouts

+
+
+
+ + {% if person['Stats']['NumberOfWorkouts'] > 0 %} +
+
+
+ {{ + person['Stats']['DaysSinceLastWorkout'] }} +

Days since last workout

+
+
+
+ {% endif %} + +
+ {% endblock %} \ No newline at end of file diff --git a/utils.py b/utils.py index c1af6ec..6bba74a 100644 --- a/utils.py +++ b/utils.py @@ -82,6 +82,65 @@ def get_people_and_exercise_rep_maxes(topsets): 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_rep_maxes_for_person(workouts_for_person) }) return people + + +def get_person_stats(topsets): + workout_start_dates = [datetime.strptime( + workout['StartDate'], '%Y-%m-%d') for workout in topsets if workout['StartDate'] is not None] + if not workout_start_dates: + return { + 'FirstWorkout': None, + 'LastWorkout': None, + 'NumberOfWorkouts': 0, + 'TrainingDurationInDays': 0, + 'AverageWorkoutsPerWeek': 0, + 'DaysSinceLastWorkout': None, + } + first_workout_date = min(workout_start_dates) + last_workout_date = max(workout_start_dates) + training_duration = last_workout_date - first_workout_date + no_of_workouts = len(list(set([t['WorkoutId'] for t in topsets]))) + return { + 'FirstWorkout': first_workout_date.strftime("%b %d %Y"), + 'LastWorkout': last_workout_date.strftime("%b %d %Y"), + 'NumberOfWorkouts': no_of_workouts, + 'TrainingDurationInDays': training_duration.days, + 'AverageWorkoutsPerWeek': round(no_of_workouts / (training_duration.days / 7), 2), + 'DaysSinceLastWorkout': (datetime.now() - last_workout_date).days, + } + + +def get_dashboard_stats(topsets): + workout_count = len(set([t['WorkoutId'] + for t in topsets if t['WorkoutId'] is not None])) + people_count = len(set([t['PersonId'] + for t in topsets if t['PersonId'] is not None])) + workout_start_dates = [datetime.strptime( + t['StartDate'], '%Y-%m-%d') for t in topsets if t['StartDate'] is not None] + + if workout_count == 0: + return { + 'TotalWorkouts': workout_count, + 'NumberOfPeople': people_count, + 'DaysSinceLastWorkout': None, + 'AverageWorkoutsPerWeek': 0, + } + + first_workout_date = min(workout_start_dates) + last_workout_date = max(workout_start_dates) + training_duration = last_workout_date - first_workout_date + average_workouts_per_week = round( + workout_count / (training_duration.days / 7), 2) + + stats = { + 'TotalWorkouts': workout_count, + 'NumberOfPeople': people_count, + 'DaysSinceFirstWorkout': (datetime.now() - first_workout_date).days, + 'DaysSinceLastWorkout': training_duration.days, + 'AverageWorkoutsPerWeek': average_workouts_per_week, + } + return stats