my-gradio-app / fitness_tracking /fitness_tracker.py
Nguyen Trong Lap
Recreate history without binary blobs
eeb0f9c
"""
Fitness Tracker - Progress tracking and adaptive workout recommendations
Monitors fitness progress and adjusts recommendations based on performance
"""
from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
from collections import Counter
from health_data import HealthContext
class FitnessTracker:
"""
Fitness progress tracking and adaptive workout planning
Monitors workouts, calculates metrics, and adapts recommendations
"""
def __init__(self, health_context: HealthContext):
self.health_context = health_context
self.user_id = health_context.user_id
# ===== Tracking Methods =====
def record_workout(self, workout_data: Dict[str, Any]) -> None:
"""Record a completed workout"""
self.health_context.add_fitness_record(workout_data)
def get_workout_history(self, days: int = 30) -> List[Dict[str, Any]]:
"""Get workout history"""
history = self.health_context.get_fitness_history(days)
return [w.to_dict() for w in history]
def calculate_adherence_rate(self, days: int = 30) -> float:
"""Calculate workout adherence rate (0-1)"""
return self.health_context.get_workout_adherence(days)
def calculate_progress_metrics(self, days: int = 30) -> Dict[str, Any]:
"""Calculate comprehensive progress metrics"""
history = self.health_context.get_fitness_history(days)
if not history:
return {
'total_workouts': 0,
'total_minutes': 0,
'avg_duration': 0,
'avg_intensity': 'none',
'adherence': 0.0,
'consistency_score': 0.0
}
# Calculate metrics
total_workouts = len(history)
total_minutes = sum(w.duration_minutes for w in history)
avg_duration = total_minutes / total_workouts if total_workouts > 0 else 0
# Calculate intensity distribution
intensity_counts = Counter(w.intensity for w in history)
avg_intensity = intensity_counts.most_common(1)[0][0] if intensity_counts else 'medium'
# Calculate adherence
adherence = self.calculate_adherence_rate(days)
# Calculate consistency (workouts spread across days)
unique_days = len(set(w.workout_date for w in history))
consistency_score = min(unique_days / (days / 7), 1.0) # Normalize to 0-1
return {
'total_workouts': total_workouts,
'total_minutes': total_minutes,
'avg_duration': round(avg_duration, 1),
'avg_intensity': avg_intensity,
'intensity_distribution': dict(intensity_counts),
'adherence': round(adherence, 2),
'consistency_score': round(consistency_score, 2),
'unique_days_active': unique_days,
'period_days': days
}
# ===== Adaptation Methods =====
def adjust_difficulty(self, current_plan: Dict[str, Any]) -> Dict[str, Any]:
"""Adjust workout difficulty based on progress"""
metrics = self.calculate_progress_metrics(days=30)
adherence = metrics['adherence']
adjusted_plan = current_plan.copy()
if adherence > 0.85:
# User is highly adherent - increase difficulty
adjusted_plan['difficulty_level'] = 'advanced'
adjusted_plan['adjustment_reason'] = 'High adherence detected'
adjusted_plan['recommendation'] = 'Increase intensity or add more challenging exercises'
adjusted_plan['suggested_changes'] = [
'Increase weight/resistance by 10%',
'Add 1-2 extra sets',
'Reduce rest periods by 15-30 seconds',
'Try advanced variations of exercises'
]
elif adherence > 0.6:
# User is moderately adherent - maintain
adjusted_plan['difficulty_level'] = 'intermediate'
adjusted_plan['adjustment_reason'] = 'Good adherence'
adjusted_plan['recommendation'] = 'Maintain current intensity'
adjusted_plan['suggested_changes'] = [
'Keep current routine',
'Focus on form and technique',
'Gradually increase volume'
]
else:
# User is struggling - decrease difficulty
adjusted_plan['difficulty_level'] = 'beginner'
adjusted_plan['adjustment_reason'] = 'Low adherence detected'
adjusted_plan['recommendation'] = 'Simplify routine for better adherence'
adjusted_plan['suggested_changes'] = [
'Reduce number of exercises',
'Decrease sets or reps',
'Increase rest periods',
'Focus on consistency over intensity'
]
adjusted_plan['metrics'] = metrics
adjusted_plan['adjusted_at'] = datetime.now().isoformat()
return adjusted_plan
def recommend_next_phase(self, current_plan: Dict[str, Any]) -> Dict[str, Any]:
"""Recommend next training phase"""
metrics = self.calculate_progress_metrics(days=60)
recommendation = {
'current_metrics': metrics,
'phase_recommendation': None,
'rationale': '',
'next_phase_details': {}
}
if metrics['adherence'] < 0.3:
recommendation['phase_recommendation'] = 'foundation'
recommendation['rationale'] = 'Build consistency before progressing'
recommendation['next_phase_details'] = {
'focus': 'Establish routine and build habit',
'duration': '4 weeks',
'frequency': '3 days/week',
'intensity': 'low to moderate'
}
elif metrics['adherence'] < 0.6:
recommendation['phase_recommendation'] = 'building'
recommendation['rationale'] = 'Increase volume and intensity gradually'
recommendation['next_phase_details'] = {
'focus': 'Build strength and endurance',
'duration': '6-8 weeks',
'frequency': '4 days/week',
'intensity': 'moderate'
}
elif metrics['adherence'] < 0.85:
recommendation['phase_recommendation'] = 'progression'
recommendation['rationale'] = 'Progress to more challenging workouts'
recommendation['next_phase_details'] = {
'focus': 'Increase intensity and complexity',
'duration': '8-12 weeks',
'frequency': '4-5 days/week',
'intensity': 'moderate to high'
}
else:
recommendation['phase_recommendation'] = 'advanced'
recommendation['rationale'] = 'Ready for advanced training'
recommendation['next_phase_details'] = {
'focus': 'Specialized training (strength, hypertrophy, endurance)',
'duration': '12+ weeks',
'frequency': '5-6 days/week',
'intensity': 'high'
}
return recommendation
def identify_plateaus(self) -> List[str]:
"""Identify fitness plateaus"""
plateaus = []
# Check for no progress in last 30 days
history_30 = self.health_context.get_fitness_history(days=30)
history_60 = self.health_context.get_fitness_history(days=60)
if len(history_30) == 0:
plateaus.append("No workouts recorded in last 30 days - restart training")
# Check for same intensity
if history_30:
intensities_30 = [w.intensity for w in history_30]
if len(set(intensities_30)) == 1:
plateaus.append(f"Same intensity ({intensities_30[0]}) for 30 days - increase difficulty")
# Check for declining adherence
adherence_30 = self.calculate_adherence_rate(days=30)
adherence_60 = self.calculate_adherence_rate(days=60)
if adherence_60 > 0.5 and adherence_30 < 0.3:
plateaus.append("Declining adherence - motivation may be dropping")
return plateaus
def suggest_workout_variations(self) -> List[str]:
"""Suggest workout variations to prevent boredom"""
history = self.health_context.get_fitness_history(days=30)
if not history:
return [
'Try cardio: running, cycling, swimming',
'Try strength: weight training, bodyweight exercises',
'Try flexibility: yoga, pilates, stretching'
]
# Analyze current workout types
workout_types = Counter(w.workout_type for w in history)
most_common = workout_types.most_common(1)[0][0] if workout_types else None
suggestions = []
if most_common == 'cardio':
suggestions = [
'Try strength training to build muscle',
'Add flexibility work (yoga, stretching)',
'Try HIIT for variety'
]
elif most_common == 'strength':
suggestions = [
'Add cardio for cardiovascular health',
'Try flexibility training',
'Experiment with different strength styles (powerlifting, bodybuilding)'
]
elif most_common == 'flexibility':
suggestions = [
'Add cardio for endurance',
'Add strength training for muscle',
'Try sports or recreational activities'
]
else:
suggestions = [
'Mix cardio, strength, and flexibility',
'Try group fitness classes',
'Explore new sports or activities'
]
return suggestions
# ===== Analysis Methods =====
def analyze_workout_effectiveness(self) -> Dict[str, Any]:
"""Analyze workout effectiveness"""
metrics = self.calculate_progress_metrics(days=60)
effectiveness = {
'overall_score': 0.0,
'factors': {},
'assessment': '',
'recommendations': []
}
# Score based on adherence
adherence_score = metrics['adherence'] * 0.4
# Score based on consistency
consistency_score = metrics['consistency_score'] * 0.3
# Score based on intensity
intensity_score = 0.3
if metrics['avg_intensity'] == 'high':
intensity_score = 0.9
elif metrics['avg_intensity'] == 'medium':
intensity_score = 0.7
else:
intensity_score = 0.4
intensity_score *= 0.3
overall_score = adherence_score + consistency_score + intensity_score
effectiveness['overall_score'] = round(overall_score, 2)
effectiveness['factors'] = {
'adherence_contribution': round(adherence_score, 2),
'consistency_contribution': round(consistency_score, 2),
'intensity_contribution': round(intensity_score, 2)
}
if overall_score > 0.8:
effectiveness['assessment'] = 'Excellent - Your workouts are very effective'
effectiveness['recommendations'] = ['Maintain current routine', 'Consider increasing intensity']
elif overall_score > 0.6:
effectiveness['assessment'] = 'Good - Your workouts are effective'
effectiveness['recommendations'] = ['Keep up the consistency', 'Try to increase intensity']
elif overall_score > 0.4:
effectiveness['assessment'] = 'Fair - Room for improvement'
effectiveness['recommendations'] = ['Increase workout frequency', 'Boost intensity']
else:
effectiveness['assessment'] = 'Needs improvement'
effectiveness['recommendations'] = ['Start with 3 workouts/week', 'Focus on consistency first']
return effectiveness
def correlate_fitness_health(self) -> Dict[str, Any]:
"""Correlate fitness progress with overall health"""
metrics = self.calculate_progress_metrics(days=30)
# Get health analysis
from health_analysis import HealthAnalyzer
analyzer = HealthAnalyzer(self.health_context)
health_status = analyzer.analyze_health_status()
correlation = {
'fitness_metrics': metrics,
'health_status': health_status,
'correlation_analysis': {},
'insights': []
}
# Analyze correlation
if metrics['adherence'] > 0.7 and health_status['overall_health_score'] > 0.7:
correlation['insights'].append('Strong positive correlation: High fitness adherence correlates with good health')
elif metrics['adherence'] < 0.3 and health_status['overall_health_score'] < 0.5:
correlation['insights'].append('Low fitness and health - increasing exercise could improve overall health')
return correlation