File size: 43,729 Bytes
0ef3c45 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | 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() |