FitAI / app.py
Anupam007's picture
Create app.py
0ef3c45 verified
Raw
History Blame Contribute Delete
43.7 kB
import pandas as pd
import numpy as np
import random
import gradio as gr
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import NearestNeighbors
import requests
from bs4 import BeautifulSoup
# Sample exercise database
exercises_df = pd.DataFrame({
'name': [
# Strength - Upper Body
'Push-ups', 'Bench Press', 'Shoulder Press', 'Pull-ups', 'Lat Pulldowns',
'Dumbbell Rows', 'Bicep Curls', 'Tricep Extensions', 'Chest Flyes',
# Strength - Lower Body
'Squats', 'Deadlifts', 'Lunges', 'Leg Press', 'Leg Extensions',
'Hamstring Curls', 'Calf Raises', 'Glute Bridges', 'Box Jumps',
# Cardio
'Running', 'Cycling', 'Elliptical', 'Jumping Rope', 'Swimming',
'Rowing', 'Stair Climbing', 'HIIT', 'Walking',
# Flexibility/Recovery
'Yoga', 'Stretching', 'Foam Rolling', 'Pilates', 'Tai Chi'
],
'category': [
# Strength - Upper Body
'strength', 'strength', 'strength', 'strength', 'strength',
'strength', 'strength', 'strength', 'strength',
# Strength - Lower Body
'strength', 'strength', 'strength', 'strength', 'strength',
'strength', 'strength', 'strength', 'strength',
# Cardio
'cardio', 'cardio', 'cardio', 'cardio', 'cardio',
'cardio', 'cardio', 'cardio', 'cardio',
# Flexibility/Recovery
'flexibility', 'flexibility', 'flexibility', 'flexibility', 'flexibility'
],
'muscle_group': [
# Strength - Upper Body
'chest', 'chest', 'shoulders', 'back', 'back',
'back', 'arms', 'arms', 'chest',
# Strength - Lower Body
'legs', 'legs', 'legs', 'legs', 'legs',
'legs', 'legs', 'legs', 'legs',
# Cardio
'full_body', 'lower_body', 'full_body', 'full_body', 'full_body',
'full_body', 'lower_body', 'full_body', 'lower_body',
# Flexibility/Recovery
'full_body', 'full_body', 'full_body', 'full_body', 'full_body'
],
'difficulty': [
# Strength - Upper Body
2, 3, 3, 4, 3,
2, 2, 2, 3,
# Strength - Lower Body
3, 4, 3, 3, 2,
2, 1, 2, 4,
# Cardio
3, 2, 2, 3, 4,
3, 3, 4, 1,
# Flexibility/Recovery
2, 1, 1, 3, 2
],
'equipment_needed': [
# Strength - Upper Body
'none', 'barbell', 'dumbbell', 'pull-up_bar', 'machine',
'dumbbell', 'dumbbell', 'dumbbell', 'dumbbell',
# Strength - Lower Body
'none', 'barbell', 'none', 'machine', 'machine',
'machine', 'machine', 'none', 'box',
# Cardio
'none', 'machine', 'machine', 'jump_rope', 'pool',
'machine', 'machine', 'none', 'none',
# Flexibility/Recovery
'mat', 'none', 'foam_roller', 'mat', 'none'
],
'calorie_burn_factor': [
# Strength - Upper Body
2, 3, 2, 3, 2,
2, 1, 1, 2,
# Strength - Lower Body
4, 5, 3, 4, 2,
2, 1, 2, 4,
# Cardio
5, 4, 4, 4, 5,
4, 4, 5, 2,
# Flexibility/Recovery
2, 1, 1, 2, 1
],
'muscle_building_factor': [
# Strength - Upper Body
3, 5, 4, 4, 4,
3, 3, 3, 3,
# Strength - Lower Body
5, 5, 4, 4, 3,
3, 2, 3, 3,
# Cardio
1, 1, 1, 1, 1,
1, 1, 2, 1,
# Flexibility/Recovery
1, 0, 0, 1, 0
],
'endurance_factor': [
# Strength - Upper Body
2, 1, 1, 2, 1,
1, 1, 1, 1,
# Strength - Lower Body
2, 1, 2, 1, 1,
1, 1, 1, 2,
# Cardio
5, 5, 5, 4, 5,
5, 4, 4, 3,
# Flexibility/Recovery
1, 0, 0, 1, 1
],
'flexibility_factor': [
# Strength - Upper Body
1, 0, 0, 1, 0,
0, 0, 0, 1,
# Strength - Lower Body
2, 1, 2, 0, 0,
1, 1, 1, 0,
# Cardio
1, 1, 1, 1, 2,
1, 1, 1, 1,
# Flexibility/Recovery
5, 5, 3, 4, 4
],
'injury_risk': [
# Strength - Upper Body
1, 3, 2, 3, 1,
2, 1, 1, 1,
# Strength - Lower Body
2, 4, 2, 2, 1,
1, 1, 1, 3,
# Cardio
3, 1, 1, 2, 1,
1, 2, 3, 1,
# Flexibility/Recovery
1, 1, 1, 1, 1
]
})
# Body type recommendations
body_type_recommendations = {
'ectomorph': {
'strength_focus': 0.6,
'cardio_focus': 0.2,
'flexibility_focus': 0.2,
'sets': 4,
'reps': '8-12',
'rest': '60-90 seconds',
'nutrition': 'High calorie, protein-rich diet. Focus on strength training with compound movements. Add extra calories for muscle building.'
},
'mesomorph': {
'strength_focus': 0.5,
'cardio_focus': 0.3,
'flexibility_focus': 0.2,
'sets': 3,
'reps': '8-15',
'rest': '45-60 seconds',
'nutrition': 'Balanced macronutrients with moderate protein. Mix of strength and cardio works well. Adjust calories based on specific goals.'
},
'endomorph': {
'strength_focus': 0.4,
'cardio_focus': 0.4,
'flexibility_focus': 0.2,
'sets': 3,
'reps': '12-15',
'rest': '30-45 seconds',
'nutrition': 'Calorie-controlled diet with higher protein. Include more cardio and circuit training. Focus on reducing processed carbs.'
}
}
# Goal-based recommendations
goal_recommendations = {
'weight_loss': {
'strength_focus': 0.3,
'cardio_focus': 0.5,
'flexibility_focus': 0.2,
'training_frequency': '4-5 days/week',
'nutrition': 'Calorie deficit of 500-750 per day. Higher protein intake (1.6-2g per kg). Focus on whole foods and fiber.'
},
'muscle_gain': {
'strength_focus': 0.7,
'cardio_focus': 0.1,
'flexibility_focus': 0.2,
'training_frequency': '4 days/week',
'nutrition': 'Calorie surplus of 250-500 per day. High protein intake (1.8-2.2g per kg). Carbs around workouts.'
},
'endurance': {
'strength_focus': 0.2,
'cardio_focus': 0.6,
'flexibility_focus': 0.2,
'training_frequency': '5-6 days/week',
'nutrition': 'Balanced calories. Higher carbohydrate intake (5-7g per kg). Timing nutrition around longer training sessions.'
},
'flexibility': {
'strength_focus': 0.3,
'cardio_focus': 0.2,
'flexibility_focus': 0.5,
'training_frequency': '3-4 days/week',
'nutrition': 'Balanced diet with anti-inflammatory foods. Adequate protein (1.4-1.6g per kg). Hydration is essential.'
},
'general_fitness': {
'strength_focus': 0.4,
'cardio_focus': 0.4,
'flexibility_focus': 0.2,
'training_frequency': '3-4 days/week',
'nutrition': 'Balanced diet with proper macronutrients. Focus on whole foods. Moderate protein (1.4-1.6g per kg).'
}
}
# Activity level calorie multipliers
activity_multipliers = {
'sedentary': 1.2,
'lightly_active': 1.375,
'moderately_active': 1.55,
'very_active': 1.725,
'extra_active': 1.9
}
# Health condition adjustments
health_condition_adjustments = {
'none': {},
'back_pain': {
'avoid': ['Deadlifts', 'Squats', 'Bench Press'],
'recommended': ['Swimming', 'Walking', 'Yoga', 'Pilates'],
'advice': 'Focus on core strengthening exercises. Avoid high-impact activities and heavy weights.'
},
'knee_pain': {
'avoid': ['Squats', 'Lunges', 'Running', 'Box Jumps'],
'recommended': ['Swimming', 'Cycling', 'Rowing', 'Upper Body Training'],
'advice': 'Low-impact cardio and avoid deep knee bending. Strengthen muscles around the knee with controlled movements.'
},
'shoulder_pain': {
'avoid': ['Shoulder Press', 'Push-ups', 'Pull-ups', 'Bench Press'],
'recommended': ['Leg Training', 'Core Work', 'Controlled Mobility', 'Walking'],
'advice': 'Avoid overhead movements and heavy pushing/pulling. Focus on rotator cuff strengthening and mobility.'
},
'hypertension': {
'avoid': ['HIIT', 'Heavy weight lifting', 'Exercises with head below heart'],
'recommended': ['Walking', 'Swimming', 'Cycling', 'Light weight training'],
'advice': 'Focus on moderate-intensity, steady-state cardio. Avoid holding breath during exercise.'
},
'diabetes': {
'avoid': [],
'recommended': ['Walking', 'Swimming', 'Cycling', 'Resistance Training'],
'advice': 'Regular moderate exercise helps control blood sugar. Monitor glucose levels before and after exercise.'
}
}
# Add diet recommendations
diet_recommendations = {
'weight_loss': {
'calorie_deficit': 500,
'protein_factor': 2.0, # g per kg of bodyweight
'carb_factor': 2.0, # g per kg of bodyweight
'fat_factor': 0.8, # g per kg of bodyweight
'meal_count': 4,
'sample_foods': {
'proteins': ['Chicken breast', 'Turkey', 'Fish', 'Tofu', 'Greek yogurt', 'Cottage cheese', 'Egg whites', 'Lean beef', 'Protein powder'],
'carbs': ['Brown rice', 'Quinoa', 'Sweet potato', 'Oatmeal', 'Whole grain bread', 'Beans', 'Lentils', 'Fruits'],
'fats': ['Avocado', 'Olive oil', 'Nuts', 'Seeds', 'Nut butters', 'Fatty fish'],
'vegetables': ['Broccoli', 'Spinach', 'Kale', 'Cauliflower', 'Peppers', 'Cucumbers', 'Asparagus', 'Zucchini'],
'snacks': ['Greek yogurt', 'Protein bar', 'Apple with peanut butter', 'Cottage cheese with berries', 'Veggie sticks with hummus']
},
'avoid': ['Sugary drinks', 'Processed foods', 'Refined carbs', 'Alcohol', 'Fried foods', 'High-sugar desserts'],
'tips': [
'Drink water before meals to increase fullness',
'Use smaller plates to control portion sizes',
'Fill half your plate with vegetables',
'Track your food intake with a journal or app',
'Allow yourself one treat meal per week to stay motivated'
]
},
'muscle_gain': {
'calorie_surplus': 300,
'protein_factor': 2.2, # g per kg of bodyweight
'carb_factor': 4.0, # g per kg of bodyweight
'fat_factor': 1.0, # g per kg of bodyweight
'meal_count': 5,
'sample_foods': {
'proteins': ['Chicken breast', 'Turkey', 'Fish', 'Lean beef', 'Eggs', 'Greek yogurt', 'Cottage cheese', 'Whey protein', 'Tofu'],
'carbs': ['Rice', 'Pasta', 'Potatoes', 'Oats', 'Bread', 'Quinoa', 'Bananas', 'Honey'],
'fats': ['Avocado', 'Olive oil', 'Nuts', 'Nut butters', 'Seeds', 'Whole eggs'],
'vegetables': ['Broccoli', 'Spinach', 'Kale', 'Peppers', 'Carrots', 'Peas', 'Green beans'],
'snacks': ['Protein shake with banana', 'Trail mix', 'Tuna on crackers', 'PB&J sandwich', 'Greek yogurt with granola']
},
'avoid': ['Alcohol', 'Low-nutrient processed foods', 'Excessive fiber before workouts'],
'tips': [
'Eat a protein and carb-rich meal within 30-60 minutes after training',
'Aim to gain 0.2-0.5kg per week to minimize fat gain',
'Focus on progressive overload in your training to stimulate muscle growth',
'Get 7-9 hours of quality sleep for maximum recovery and growth',
'Consider creatine monohydrate as a supplement (5g daily)'
]
},
'endurance': {
'calorie_balance': 0,
'protein_factor': 1.6, # g per kg of bodyweight
'carb_factor': 6.0, # g per kg of bodyweight
'fat_factor': 1.0, # g per kg of bodyweight
'meal_count': 5,
'sample_foods': {
'proteins': ['Chicken', 'Fish', 'Tofu', 'Beans', 'Lentils', 'Greek yogurt', 'Eggs', 'Lean meat'],
'carbs': ['Oats', 'Rice', 'Quinoa', 'Sweet potatoes', 'Pasta', 'Bananas', 'Dates', 'Whole grains'],
'fats': ['Avocado', 'Olive oil', 'Nuts', 'Seeds', 'Fatty fish'],
'vegetables': ['Leafy greens', 'Peppers', 'Carrots', 'Beets', 'Sweet potatoes', 'Tomatoes'],
'snacks': ['Banana with honey', 'Energy bars', 'Dried fruit and nuts', 'Rice cakes with nut butter', 'Smoothies']
},
'avoid': ['High-fiber foods before races/long training', 'New foods before competition', 'Heavy meals before workouts'],
'tips': [
'Carb-load 24-48 hours before long endurance events',
'Consume easily digestible carbs during sessions lasting over 60 minutes',
'Stay well-hydrated and consider electrolyte replacement during long sessions',
'Practice your race-day nutrition plan during training',
'Consume 30-60g of carbs per hour during endurance exercise lasting more than 90 minutes'
]
},
'flexibility': {
'calorie_balance': 0,
'protein_factor': 1.4, # g per kg of bodyweight
'carb_factor': 3.0, # g per kg of bodyweight
'fat_factor': 1.0, # g per kg of bodyweight
'meal_count': 3,
'sample_foods': {
'proteins': ['Fish', 'Chicken', 'Tofu', 'Beans', 'Lentils', 'Eggs', 'Greek yogurt'],
'carbs': ['Sweet potatoes', 'Brown rice', 'Quinoa', 'Fruits', 'Oats', 'Whole grains'],
'fats': ['Avocado', 'Olive oil', 'Nuts', 'Seeds', 'Coconut oil'],
'vegetables': ['Leafy greens', 'Peppers', 'Carrots', 'Cucumbers', 'Tomatoes'],
'snacks': ['Fruit with nut butter', 'Hummus with vegetables', 'Trail mix', 'Smoothies']
},
'avoid': ['Highly processed foods', 'Excessive alcohol', 'Sugar-sweetened beverages'],
'tips': [
'Stay well-hydrated to maintain joint and tissue health',
'Include foods rich in omega-3 fatty acids for their anti-inflammatory properties',
'Consider collagen supplements to support joint and connective tissue health',
'Include foods high in vitamin C to support collagen production',
'Maintain consistent meal timing to support recovery'
]
},
'general_fitness': {
'calorie_balance': 0,
'protein_factor': 1.6, # g per kg of bodyweight
'carb_factor': 3.0, # g per kg of bodyweight
'fat_factor': 0.9, # g per kg of bodyweight
'meal_count': 4,
'sample_foods': {
'proteins': ['Chicken', 'Fish', 'Eggs', 'Greek yogurt', 'Cottage cheese', 'Tofu', 'Lean beef', 'Turkey', 'Legumes'],
'carbs': ['Brown rice', 'Quinoa', 'Sweet potatoes', 'Oats', 'Whole grain bread', 'Fruits', 'Whole grain pasta'],
'fats': ['Avocado', 'Olive oil', 'Nuts', 'Seeds', 'Nut butters', 'Fatty fish'],
'vegetables': ['Broccoli', 'Spinach', 'Kale', 'Bell peppers', 'Carrots', 'Tomatoes', 'Cucumber', 'Zucchini'],
'snacks': ['Greek yogurt with berries', 'Apple with almond butter', 'Hummus with veggies', 'Hard-boiled eggs', 'Trail mix']
},
'avoid': ['Processed foods', 'Excessive sugar', 'Trans fats', 'Excessive alcohol'],
'tips': [
'Focus on whole, minimally processed foods',
'Stay hydrated throughout the day',
'Plan and prep meals ahead of time',
'Listen to your body\'s hunger and fullness cues',
'Aim for a colorful variety of fruits and vegetables'
]
}
}
# Add health condition dietary adjustments
health_condition_diet_adjustments = {
'none': {},
'back_pain': {
'beneficial_foods': ['Fatty fish (omega-3s)', 'Turmeric', 'Ginger', 'Berries', 'Green leafy vegetables', 'Nuts and seeds'],
'avoid_foods': ['Processed foods', 'Sugary foods', 'Alcohol', 'Excessive red meat'],
'advice': 'Focus on anti-inflammatory foods to reduce pain and inflammation. Stay well-hydrated and maintain a healthy weight to reduce strain on your back.'
},
'knee_pain': {
'beneficial_foods': ['Fatty fish', 'Olive oil', 'Nuts', 'Fruits', 'Vegetables', 'Whole grains', 'Ginger', 'Turmeric'],
'avoid_foods': ['Processed foods', 'Sugar', 'Refined carbohydrates', 'Alcohol', 'Saturated fats'],
'advice': 'Focus on anti-inflammatory foods and maintain a healthy weight to reduce stress on knee joints. Consider vitamin D and calcium supplements for joint health.'
},
'shoulder_pain': {
'beneficial_foods': ['Fatty fish', 'Berries', 'Olive oil', 'Nuts', 'Seeds', 'Dark leafy greens', 'Colorful vegetables'],
'avoid_foods': ['Processed foods', 'Sugar', 'Refined carbohydrates', 'Excessive alcohol'],
'advice': 'Anti-inflammatory diet can help reduce shoulder pain and inflammation. Consider protein timing around workouts to support tissue repair.'
},
'hypertension': {
'beneficial_foods': ['Bananas', 'Leafy greens', 'Berries', 'Beets', 'Oats', 'Garlic', 'Olive oil', 'Low-fat dairy', 'Seeds'],
'avoid_foods': ['Salt', 'Processed foods', 'Alcohol', 'Caffeine', 'Red meat', 'Sugar'],
'advice': 'Follow a DASH-style diet (Dietary Approaches to Stop Hypertension). Limit sodium to 1,500-2,300mg per day. Monitor caffeine intake and avoid excessive alcohol.'
},
'diabetes': {
'beneficial_foods': ['Leafy greens', 'Fatty fish', 'Nuts', 'Seeds', 'Beans', 'Whole grains', 'Berries', 'Avocados', 'Eggs'],
'avoid_foods': ['Sugar', 'Refined carbs', 'Sugary drinks', 'Fruit juices', 'Trans fats', 'Processed meats', 'Alcohol'],
'advice': 'Focus on low glycemic index foods and consistent carbohydrate intake throughout the day. Monitor blood glucose response to different foods and meal timing.'
}
}
def calculate_bmr(weight, height, age, gender):
"""Calculate Basal Metabolic Rate using the Mifflin-St Jeor Equation"""
if gender == 'male':
return 10 * weight + 6.25 * height - 5 * age + 5
else:
return 10 * weight + 6.25 * height - 5 * age - 161
def calculate_daily_calories(bmr, activity_level, goal):
"""Calculate daily calorie needs based on activity level and goal"""
activity_multiplier = activity_multipliers[activity_level]
tdee = bmr * activity_multiplier
if goal == 'weight_loss':
return int(tdee - 500)
elif goal == 'muscle_gain':
return int(tdee + 300)
else:
return int(tdee)
def filter_exercises_by_health_condition(exercises, health_condition):
"""Filter out exercises that should be avoided based on health condition"""
if health_condition == 'none':
return exercises
avoid_list = health_condition_adjustments[health_condition]['avoid']
return [ex for ex in exercises if ex['name'] not in avoid_list]
def get_exercise_recommendations(user_profile, available_equipment=None):
"""Generate exercise recommendations based on user profile"""
body_type = user_profile['body_type']
goal = user_profile['goal']
health_condition = user_profile['health_condition']
# Combine recommendations from body type and goal
body_rec = body_type_recommendations[body_type]
goal_rec = goal_recommendations[goal]
# Calculate focus distribution (weighted average)
strength_focus = 0.5 * body_rec['strength_focus'] + 0.5 * goal_rec['strength_focus']
cardio_focus = 0.5 * body_rec['cardio_focus'] + 0.5 * goal_rec['cardio_focus']
flexibility_focus = 0.5 * body_rec['flexibility_focus'] + 0.5 * goal_rec['flexibility_focus']
# Filter exercises by available equipment if specified
filtered_exercises = exercises_df
if available_equipment and 'any' not in available_equipment:
filtered_exercises = filtered_exercises[filtered_exercises['equipment_needed'].isin(['none'] + available_equipment)]
# Convert to list of dictionaries for easier manipulation
exercises_list = filtered_exercises.to_dict('records')
# Filter out exercises to avoid based on health condition
exercises_list = filter_exercises_by_health_condition(exercises_list, health_condition)
# Select exercises based on focus distribution
num_exercises = 12 # Total exercises in the plan
num_strength = max(1, int(num_exercises * strength_focus))
num_cardio = max(1, int(num_exercises * cardio_focus))
num_flexibility = max(1, num_exercises - num_strength - num_cardio)
# Further divide strength exercises by muscle group
strength_exercises = [ex for ex in exercises_list if ex['category'] == 'strength']
upper_body = [ex for ex in strength_exercises if ex['muscle_group'] in ['chest', 'back', 'shoulders', 'arms']]
lower_body = [ex for ex in strength_exercises if ex['muscle_group'] == 'legs']
num_upper = max(1, int(num_strength * 0.6))
num_lower = max(1, num_strength - num_upper)
# Select exercises
selected_upper = random.sample(upper_body, min(num_upper, len(upper_body)))
selected_lower = random.sample(lower_body, min(num_lower, len(lower_body)))
cardio_exercises = [ex for ex in exercises_list if ex['category'] == 'cardio']
selected_cardio = random.sample(cardio_exercises, min(num_cardio, len(cardio_exercises)))
flexibility_exercises = [ex for ex in exercises_list if ex['category'] == 'flexibility']
selected_flexibility = random.sample(flexibility_exercises, min(num_flexibility, len(flexibility_exercises)))
# Combine all selected exercises
selected_exercises = selected_upper + selected_lower + selected_cardio + selected_flexibility
# Create workout plan
workout_plan = {
'schedule': create_weekly_schedule(selected_exercises, goal_rec['training_frequency']),
'sets': body_rec['sets'],
'reps': body_rec['reps'],
'rest': body_rec['rest'],
'nutrition': combine_nutrition_advice(body_rec['nutrition'], goal_rec['nutrition']),
'health_advice': health_condition_adjustments[health_condition].get('advice', ''),
}
if health_condition != 'none':
workout_plan['recommended_exercises'] = health_condition_adjustments[health_condition]['recommended']
return workout_plan
def create_weekly_schedule(exercises, training_frequency):
"""Create a weekly workout schedule based on exercises and training frequency"""
# Parse training frequency to number of days
days_per_week = int(training_frequency.split('-')[0])
# Create empty schedule
schedule = {}
# Define workout days based on frequency
if days_per_week <= 3:
workout_days = ['Monday', 'Wednesday', 'Friday'][:days_per_week]
elif days_per_week <= 4:
workout_days = ['Monday', 'Tuesday', 'Thursday', 'Friday']
elif days_per_week <= 5:
workout_days = ['Monday', 'Tuesday', 'Wednesday', 'Friday', 'Saturday']
else:
workout_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
# Group exercises by category
strength_exercises = [ex for ex in exercises if ex['category'] == 'strength']
upper_body = [ex for ex in strength_exercises if ex['muscle_group'] in ['chest', 'back', 'shoulders', 'arms']]
lower_body = [ex for ex in strength_exercises if ex['muscle_group'] == 'legs']
cardio_exercises = [ex for ex in exercises if ex['category'] == 'cardio']
flexibility_exercises = [ex for ex in exercises if ex['category'] == 'flexibility']
# Distribute exercises based on number of days
if days_per_week <= 3:
# Full body workouts
for day in workout_days:
day_exercises = []
day_exercises.extend(random.sample(upper_body, min(2, len(upper_body))))
day_exercises.extend(random.sample(lower_body, min(2, len(lower_body))))
day_exercises.extend(random.sample(cardio_exercises, min(1, len(cardio_exercises))))
day_exercises.extend(random.sample(flexibility_exercises, min(1, len(flexibility_exercises))))
schedule[day] = day_exercises
elif days_per_week == 4:
# Upper/Lower split
upper_days = [workout_days[0], workout_days[2]]
lower_days = [workout_days[1], workout_days[3]]
for day in upper_days:
day_exercises = []
day_exercises.extend(random.sample(upper_body, min(4, len(upper_body))))
day_exercises.extend(random.sample(cardio_exercises, min(1, len(cardio_exercises))))
day_exercises.extend(random.sample(flexibility_exercises, min(1, len(flexibility_exercises))))
schedule[day] = day_exercises
for day in lower_days:
day_exercises = []
day_exercises.extend(random.sample(lower_body, min(3, len(lower_body))))
day_exercises.extend(random.sample(cardio_exercises, min(1, len(cardio_exercises))))
day_exercises.extend(random.sample(flexibility_exercises, min(1, len(flexibility_exercises))))
schedule[day] = day_exercises
else:
# Push/Pull/Legs or other specialized split
random.shuffle(strength_exercises)
split_size = len(strength_exercises) // (days_per_week - 1)
for i, day in enumerate(workout_days[:-1]):
start_idx = i * split_size
end_idx = (i + 1) * split_size if i < days_per_week - 2 else len(strength_exercises)
day_exercises = strength_exercises[start_idx:end_idx]
# Add some cardio to each day
day_exercises.extend(random.sample(cardio_exercises, min(1, len(cardio_exercises))))
schedule[day] = day_exercises
# Last day is cardio and flexibility
schedule[workout_days[-1]] = random.sample(cardio_exercises, min(2, len(cardio_exercises))) + flexibility_exercises
return schedule
def combine_nutrition_advice(body_type_advice, goal_advice):
"""Combine nutrition advice from body type and goal"""
return f"Body Type Recommendation: {body_type_advice}\n\nGoal-Based Recommendation: {goal_advice}"
def format_workout_plan(plan, user_profile):
"""Format the workout plan into a readable string"""
result = ""
# Add header with user stats
result += f"## PERSONALIZED WORKOUT PLAN\n\n"
result += f"### USER PROFILE\n"
result += f"- Age: {user_profile['age']}\n"
result += f"- Height: {user_profile['height']} cm\n"
result += f"- Weight: {user_profile['weight']} kg\n"
result += f"- Gender: {user_profile['gender'].capitalize()}\n"
result += f"- Body Type: {user_profile['body_type'].capitalize()}\n"
result += f"- Activity Level: {user_profile['activity_level'].replace('_', ' ').capitalize()}\n"
result += f"- Fitness Goal: {user_profile['goal'].replace('_', ' ').capitalize()}\n"
# Add BMI and calorie calculations
bmi = round(user_profile['weight'] / ((user_profile['height'] / 100) ** 2), 1)
bmr = calculate_bmr(user_profile['weight'], user_profile['height'], user_profile['age'], user_profile['gender'])
daily_calories = calculate_daily_calories(bmr, user_profile['activity_level'], user_profile['goal'])
result += f"- BMI: {bmi} "
if bmi < 18.5:
result += "(Underweight)"
elif bmi < 25:
result += "(Normal weight)"
elif bmi < 30:
result += "(Overweight)"
else:
result += "(Obese)"
result += f"\n- Recommended Daily Calories: {daily_calories} kcal\n\n"
# Add health condition advice if applicable
if user_profile['health_condition'] != 'none':
result += f"### HEALTH CONSIDERATIONS\n"
result += f"Based on your {user_profile['health_condition'].replace('_', ' ')}, please note:\n\n"
result += f"{plan['health_advice']}\n\n"
result += f"Recommended exercises for your condition:\n"
for ex in plan['recommended_exercises']:
result += f"- {ex}\n"
result += "\n"
# Add weekly schedule
result += f"### WEEKLY WORKOUT SCHEDULE\n\n"
for day, exercises in plan['schedule'].items():
result += f"#### {day}\n"
if exercises:
for i, ex in enumerate(exercises, 1):
result += f"{i}. {ex['name']} "
if ex['category'] == 'strength':
result += f"({plan['sets']} sets of {plan['reps']} reps, {plan['rest']} rest)"
elif ex['category'] == 'cardio':
if ex['name'] in ['HIIT', 'Circuit Training']:
result += "(20-30 minutes, including work/rest intervals)"
else:
result += "(30-45 minutes, moderate intensity)"
else: # flexibility
result += "(15-20 minutes)"
result += "\n"
else:
result += "Rest Day\n"
result += "\n"
# Add nutrition advice
result += f"### NUTRITION RECOMMENDATIONS\n\n"
result += f"{plan['nutrition']}\n\n"
# Add progression tips
result += f"### PROGRESSION TIPS\n\n"
result += "1. Increase weight by 5-10% when you can complete all sets and reps with good form\n"
result += "2. For cardio, gradually increase duration by 5 minutes or intensity by 5-10%\n"
result += "3. Track your workouts to ensure progressive overload\n"
result += "4. Aim for 7-9 hours of quality sleep per night for recovery\n"
result += "5. Stay hydrated with at least 3 liters of water daily\n\n"
result += "### NOTES\n"
result += "- Always warm up for 5-10 minutes before each workout\n"
result += "- Cool down with 5-10 minutes of light activity and stretching\n"
result += "- Listen to your body and adjust intensity as needed\n"
result += "- Consistency is more important than perfection\n"
return result
def generate_meal_plan(user_profile):
"""Generate a personalized meal plan based on user profile"""
weight = user_profile['weight']
goal = user_profile['goal']
health_condition = user_profile['health_condition']
body_type = user_profile['body_type']
# Get diet recommendations based on goal
diet_rec = diet_recommendations[goal]
# Calculate daily calorie needs
bmr = calculate_bmr(weight, user_profile['height'], user_profile['age'], user_profile['gender'])
activity_multiplier = activity_multipliers[user_profile['activity_level']]
tdee = bmr * activity_multiplier
# Adjust calories based on goal
if goal == 'weight_loss':
daily_calories = int(tdee - diet_rec['calorie_deficit'])
elif goal == 'muscle_gain':
daily_calories = int(tdee + diet_rec['calorie_surplus'])
else:
daily_calories = int(tdee)
# Adjust based on body type
if body_type == 'ectomorph' and goal == 'muscle_gain':
daily_calories += 200
elif body_type == 'endomorph' and goal == 'weight_loss':
daily_calories -= 100
# Calculate macronutrients
protein_grams = round(weight * diet_rec['protein_factor'])
carb_grams = round(weight * diet_rec['carb_factor'])
fat_grams = round(weight * diet_rec['fat_factor'])
# Adjust based on health condition if needed
health_adjustments = health_condition_diet_adjustments.get(health_condition, {})
# Calculate calories from each macro
protein_cals = protein_grams * 4
carb_cals = carb_grams * 4
fat_cals = fat_grams * 9
# Generate sample meals
meal_count = diet_rec['meal_count']
sample_meals = generate_sample_meals(diet_rec, meal_count, protein_grams, carb_grams, fat_grams, health_adjustments)
# Create the meal plan dictionary
meal_plan = {
'daily_calories': daily_calories,
'macros': {
'protein': {
'grams': protein_grams,
'calories': protein_cals,
'percentage': round((protein_cals / daily_calories) * 100)
},
'carbs': {
'grams': carb_grams,
'calories': carb_cals,
'percentage': round((carb_cals / daily_calories) * 100)
},
'fats': {
'grams': fat_grams,
'calories': fat_cals,
'percentage': round((fat_cals / daily_calories) * 100)
}
},
'meal_schedule': sample_meals,
'foods_to_include': diet_rec['sample_foods'],
'foods_to_avoid': diet_rec['avoid'],
'tips': diet_rec['tips'],
}
# Add health condition specific recommendations if applicable
if health_condition != 'none':
meal_plan['health_recommendations'] = {
'beneficial_foods': health_adjustments.get('beneficial_foods', []),
'avoid_foods': health_adjustments.get('avoid_foods', []),
'advice': health_adjustments.get('advice', '')
}
return meal_plan
def generate_sample_meals(diet_rec, meal_count, daily_protein, daily_carbs, daily_fats, health_adjustments=None):
"""Generate sample meals based on diet recommendations and macros"""
meals = {}
meal_names = ["Breakfast", "Morning Snack", "Lunch", "Afternoon Snack", "Dinner", "Evening Snack"]
# Adjust meal names based on meal count
if meal_count == 3:
selected_meals = ["Breakfast", "Lunch", "Dinner"]
elif meal_count == 4:
selected_meals = ["Breakfast", "Lunch", "Afternoon Snack", "Dinner"]
elif meal_count == 5:
selected_meals = ["Breakfast", "Morning Snack", "Lunch", "Afternoon Snack", "Dinner"]
else: # 6 meals
selected_meals = meal_names
# Get sample foods, considering health adjustments
proteins = diet_rec['sample_foods']['proteins']
carbs = diet_rec['sample_foods']['carbs']
fats = diet_rec['sample_foods']['fats']
vegetables = diet_rec['sample_foods']['vegetables']
snacks = diet_rec['sample_foods']['snacks']
# Filter out foods to avoid if health condition exists
if health_adjustments and 'avoid_foods' in health_adjustments:
avoid_foods = health_adjustments['avoid_foods']
proteins = [p for p in proteins if p not in avoid_foods]
carbs = [c for c in carbs if c not in avoid_foods]
fats = [f for f in fats if f not in avoid_foods]
vegetables = [v for v in vegetables if v not in avoid_foods]
snacks = [s for s in snacks if s not in avoid_foods and not any(avoid in s for avoid in avoid_foods)]
# Create basic meal templates based on meal type
for meal in selected_meals:
if "Snack" in meal:
# Snacks are simpler
meals[meal] = {
'description': random.choice(snacks),
'protein': round(daily_protein / meal_count / 2, 1),
'carbs': round(daily_carbs / meal_count / 2, 1),
'fats': round(daily_fats / meal_count / 2, 1)
}
elif meal == "Breakfast":
protein_choice = random.choice(proteins)
carb_choice = random.choice(carbs)
fat_choice = random.choice(fats)
meals[meal] = {
'description': f"{carb_choice} with {protein_choice} and {fat_choice}",
'protein': round(daily_protein * 0.25, 1),
'carbs': round(daily_carbs * 0.25, 1),
'fats': round(daily_fats * 0.2, 1)
}
elif meal == "Lunch" or meal == "Dinner":
protein_choice = random.choice(proteins)
carb_choice = random.choice(carbs)
fat_choice = random.choice(fats)
veg_choice = random.choice(vegetables)
meals[meal] = {
'description': f"{protein_choice} with {carb_choice}, {veg_choice}, and {fat_choice}",
'protein': round(daily_protein * 0.3, 1),
'carbs': round(daily_carbs * 0.3, 1),
'fats': round(daily_fats * 0.3, 1)
}
return meals
def format_meal_plan(meal_plan, user_profile):
"""Format the meal plan into a readable string"""
result = ""
# Add header
result += "## PERSONALIZED NUTRITION PLAN\n\n"
# Add summary of calories and macros
result += "### DAILY NUTRITIONAL TARGETS\n"
result += f"- Daily Calories: {meal_plan['daily_calories']} kcal\n"
result += f"- Protein: {meal_plan['macros']['protein']['grams']}g ({meal_plan['macros']['protein']['percentage']}% of calories)\n"
result += f"- Carbohydrates: {meal_plan['macros']['carbs']['grams']}g ({meal_plan['macros']['carbs']['percentage']}% of calories)\n"
result += f"- Fats: {meal_plan['macros']['fats']['grams']}g ({meal_plan['macros']['fats']['percentage']}% of calories)\n\n"
# Add health-specific recommendations if applicable
if user_profile['health_condition'] != 'none':
result += "### HEALTH-SPECIFIC RECOMMENDATIONS\n"
result += f"Based on your {user_profile['health_condition'].replace('_', ' ')}, please consider:\n\n"
result += f"{meal_plan['health_recommendations']['advice']}\n\n"
result += "Beneficial foods to include:\n"
for food in meal_plan['health_recommendations']['beneficial_foods']:
result += f"- {food}\n"
result += "\nFoods to limit or avoid:\n"
for food in meal_plan['health_recommendations']['avoid_foods']:
result += f"- {food}\n"
result += "\n"
# Add sample meal plan
result += "### SAMPLE MEAL PLAN\n\n"
for meal_name, meal_info in meal_plan['meal_schedule'].items():
result += f"#### {meal_name}\n"
result += f"{meal_info['description']}\n"
result += f"- Protein: {meal_info['protein']}g\n"
result += f"- Carbs: {meal_info['carbs']}g\n"
result += f"- Fats: {meal_info['fats']}g\n\n"
# Add recommended foods list
result += "### RECOMMENDED FOODS\n\n"
result += "#### Protein Sources\n"
for food in meal_plan['foods_to_include']['proteins']:
result += f"- {food}\n"
result += "\n#### Carbohydrate Sources\n"
for food in meal_plan['foods_to_include']['carbs']:
result += f"- {food}\n"
result += "\n#### Healthy Fat Sources\n"
for food in meal_plan['foods_to_include']['fats']:
result += f"- {food}\n"
result += "\n#### Vegetables\n"
for food in meal_plan['foods_to_include']['vegetables']:
result += f"- {food}\n"
# Add foods to avoid
result += "\n### FOODS TO LIMIT OR AVOID\n"
for food in meal_plan['foods_to_avoid']:
result += f"- {food}\n"
# Add nutrition tips
result += "\n### NUTRITION TIPS\n"
for i, tip in enumerate(meal_plan['tips'], 1):
result += f"{i}. {tip}\n"
return result
# Update the generate_workout_plan function to include diet plan
def generate_workout_plan(age, weight, height, gender, body_type, activity_level, goal, health_condition):
"""Main function to generate a workout and diet plan based on user inputs"""
user_profile = {
'age': age,
'weight': weight,
'height': height,
'gender': gender,
'body_type': body_type,
'activity_level': activity_level,
'goal': goal,
'health_condition': health_condition
}
# Get workout recommendations
workout_plan = get_exercise_recommendations(user_profile)
# Get diet recommendations
diet_plan = generate_meal_plan(user_profile)
# Format the plans into readable strings
formatted_workout_plan = format_workout_plan(workout_plan, user_profile)
formatted_diet_plan = format_meal_plan(diet_plan, user_profile)
# Combine the two plans
combined_plan = formatted_workout_plan + "\n\n" + formatted_diet_plan
return combined_plan
# Update the Gradio interface to include diet plan options
def create_gradio_interface():
with gr.Blocks(title="AI Fitness & Nutrition Plan Generator") as app:
gr.Markdown("# AI Fitness & Nutrition Plan Generator")
gr.Markdown("Enter your details below to get a personalized workout and diet plan")
with gr.Row():
with gr.Column():
age = gr.Slider(label="Age", minimum=16, maximum=80, value=30, step=1)
weight = gr.Slider(label="Weight (kg)", minimum=40, maximum=150, value=70, step=1)
height = gr.Slider(label="Height (cm)", minimum=140, maximum=220, value=175, step=1)
gender = gr.Radio(label="Gender", choices=["male", "female"], value="male")
body_type = gr.Radio(
label="Body Type",
choices=["ectomorph", "mesomorph", "endomorph"],
value="mesomorph",
info="Ectomorph (slim), Mesomorph (athletic), Endomorph (broader)"
)
activity_level = gr.Radio(
label="Activity Level",
choices=["sedentary", "lightly_active", "moderately_active", "very_active", "extra_active"],
value="moderately_active",
info="Daily activity level excluding planned workouts"
)
goal = gr.Radio(
label="Primary Fitness Goal",
choices=["weight_loss", "muscle_gain", "endurance", "flexibility", "general_fitness"],
value="general_fitness"
)
health_condition = gr.Radio(
label="Health Condition",
choices=["none", "back_pain", "knee_pain", "shoulder_pain", "hypertension", "diabetes"],
value="none",
info="Select any condition that might affect your exercise selection"
)
# Add dietary preference options
dietary_preference = gr.Radio(
label="Dietary Preference",
choices=["standard", "vegetarian", "vegan", "pescatarian", "keto", "paleo"],
value="standard",
info="Select your dietary preference for meal planning"
)
food_allergies = gr.CheckboxGroup(
label="Food Allergies/Intolerances",
choices=["none", "gluten", "dairy", "nuts", "shellfish", "eggs", "soy"],
value=["none"],
info="Select any food allergies or intolerances"
)
generate_button = gr.Button("Generate Fitness & Nutrition Plan")
# Exercise data search
exercise_name = gr.Textbox(label="Exercise Name to Search on MyFitnessPal")
get_exercise_data_button = gr.Button("Get Exercise Data from MyFitnessPal")
with gr.Column():
output = gr.Markdown(label="Your Personalized Fitness & Nutrition Plan")
mfp_output = gr.JSON(label="MyFitnessPal Exercise Data")
# Update the function call to include the new parameters
generate_button.click(
generate_workout_plan,
inputs=[age, weight, height, gender, body_type, activity_level, goal, health_condition],
outputs=output
)
get_exercise_data_button.click(
scrape_myfitnesspal_exercise_data,
inputs=exercise_name,
outputs=mfp_output
)
return app
# Launch the app
if __name__ == "__main__":
app = create_gradio_interface()
app.launch()