import gradio as gr import pandas as pd import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots import time import math def convert_weight_to_kg(weight, unit): """Convert weight to kg""" if unit == "lbs" or unit == "pound": return weight * 0.453592 return weight def convert_height_to_cm(height, unit): """Convert height to cm""" if unit == "feet/inches": # Assuming height is in feet (e.g., 5.8 for 5'8") feet = int(height) inches = (height - feet) * 10 return (feet * 12 + inches) * 2.54 return height def calculate_bmr(gender, weight_kg, height_cm, age): """Calculate BMR using Mifflin-St Jeor Equation""" if gender == "Male": bmr = 10 * weight_kg + 6.25 * height_cm - 5 * age + 5 else: bmr = 10 * weight_kg + 6.25 * height_cm - 5 * age - 161 return bmr def calculate_tdee(bmr, activity_level): """Calculate TDEE based on activity level""" activity_multipliers = { "Sedentary, 0 workouts a week": 1.2, "Light, 1 workout a week": 1.375, "Moderate, 1-2 workouts a week": 1.55, "Active, 2-4 workouts a week": 1.725, "Very Active, 4-6 workouts a week": 1.9 } return bmr * activity_multipliers[activity_level] def get_weekly_weight_loss(activity_level): """Get weekly weight loss rate based on activity level""" rates = { "Sedentary, 0 workouts a week": 0.5, "Light, 1 workout a week": 0.625, "Moderate, 1-2 workouts a week": 0.875, "Active, 2-4 workouts a week": 1.125, "Very Active, 4-6 workouts a week": 1.375 } return rates[activity_level] def calculate_macros(total_calories, goal_type): """Calculate macronutrient breakdown""" if goal_type == "lose": # Higher protein for weight loss protein_pct = 35 carbs_pct = 30 fat_pct = 35 else: # Higher carbs for weight gain protein_pct = 25 carbs_pct = 45 fat_pct = 30 protein_calories = total_calories * protein_pct / 100 carbs_calories = total_calories * carbs_pct / 100 fat_calories = total_calories * fat_pct / 100 protein_grams = protein_calories / 4 carbs_grams = carbs_calories / 4 fat_grams = fat_calories / 9 return { 'protein_pct': protein_pct, 'carbs_pct': carbs_pct, 'fat_pct': fat_pct, 'protein_calories': protein_calories, 'carbs_calories': carbs_calories, 'fat_calories': fat_calories, 'protein_grams': protein_grams, 'carbs_grams': carbs_grams, 'fat_grams': fat_grams } def create_timeline(current_weight, target_weight, activity_level): """Create weight progression timeline""" weekly_rate = get_weekly_weight_loss(activity_level) timeline = [] current = current_weight week = 0 # Add starting weight timeline.append({"Week": week, "Weight (kg)": round(current, 1)}) # Determine if losing or gaining weight if current_weight > target_weight: # Losing weight while current > target_weight: week += 1 current -= weekly_rate if current < target_weight: current = target_weight timeline.append({"Week": week, "Weight (kg)": round(current, 1)}) if current == target_weight: break else: # Gaining weight while current < target_weight: week += 1 current += weekly_rate if current > target_weight: current = target_weight timeline.append({"Week": week, "Weight (kg)": round(current, 1)}) if current == target_weight: break return timeline def create_macro_pie_chart(macros): """Create macronutrient pie chart""" fig = go.Figure(data=[go.Pie( labels=['Protein', 'Carbs', 'Fat'], values=[macros['protein_pct'], macros['carbs_pct'], macros['fat_pct']], hole=0.4, marker_colors=['#FF6B6B', '#4ECDC4', '#45B7D1'] )]) fig.update_layout( title="Macronutrient Breakdown", font=dict(size=14), showlegend=True, height=400, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)' ) return fig def create_timeline_chart(timeline_data): """Create timeline weight progression chart""" df = pd.DataFrame(timeline_data) fig = go.Figure() fig.add_trace(go.Scatter( x=df['Week'], y=df['Weight (kg)'], mode='lines+markers', line=dict(color='#FF6B6B', width=3), marker=dict(size=8, color='#FF6B6B'), name='Weight Progression' )) fig.update_layout( title="Weight Progression Timeline", xaxis_title="Week", yaxis_title="Weight (kg)", font=dict(size=14), height=400, paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)', xaxis=dict(gridcolor='lightgray'), yaxis=dict(gridcolor='lightgray') ) return fig def simulate_loading(): """Simulate loading progress""" for i in range(101): time.sleep(0.02) yield i def calculate_fitness_metrics(gender, current_weight, current_weight_unit, target_weight, target_weight_unit, height, height_unit, age, activity_level, progress=gr.Progress()): """Main calculation function""" # Simulate loading for i in progress.tqdm(range(100), desc="Calculating your fitness plan..."): time.sleep(0.02) # Convert units current_weight_kg = convert_weight_to_kg(current_weight, current_weight_unit) target_weight_kg = convert_weight_to_kg(target_weight, target_weight_unit) height_cm = convert_height_to_cm(height, height_unit) # Calculate BMR and TDEE bmr = calculate_bmr(gender, current_weight_kg, height_cm, age) tdee = calculate_tdee(bmr, activity_level) # Determine goal type goal_type = "lose" if current_weight_kg > target_weight_kg else "gain" # Calculate daily calories (adjust by 300-400 max) weight_diff = abs(current_weight_kg - target_weight_kg) if goal_type == "lose": daily_calories = max(tdee - 400, bmr * 1.2) # Don't go below 1.2x BMR else: daily_calories = min(tdee + 400, tdee * 1.3) # Don't exceed 1.3x TDEE # Calculate macros macros = calculate_macros(daily_calories, goal_type) # Create timeline timeline_data = create_timeline(current_weight_kg, target_weight_kg, activity_level) # Create charts macro_chart = create_macro_pie_chart(macros) timeline_chart = create_timeline_chart(timeline_data) # Format results with improved styling results_text = f"""
{daily_calories:.0f}
calories per day
{len(timeline_data)-1}
weeks to goal
{macros['protein_grams']:.1f}g
({macros['protein_calories']:.0f} cal)
{macros['carbs_grams']:.1f}g
({macros['carbs_calories']:.0f} cal)
{macros['fat_grams']:.1f}g
({macros['fat_calories']:.0f} cal)