Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -24,8 +24,6 @@ LEVEL_CONFIG = {
|
|
| 24 |
"Advanced": {"tier": 2}
|
| 25 |
}
|
| 26 |
|
| 27 |
-
# EXERCISE DATABASE with Base Strength Ratios
|
| 28 |
-
# Ratio 1.0 means an intermediate male can lift 100% of his bodyweight in this exercise.
|
| 29 |
EXERCISE_DB = {
|
| 30 |
"Chest": [
|
| 31 |
{"name": "Barbell Bench Press", "equip": ["Barbell", "Gym"], "bad": ["Shoulder"], "level": 1, "ratio": 0.9},
|
|
@@ -91,27 +89,22 @@ EXERCISE_DB = {
|
|
| 91 |
# ==========================================
|
| 92 |
|
| 93 |
def calculate_weight(base_ratio, user_weight, gender, level_tier, muscle_group):
|
| 94 |
-
"""
|
| 95 |
-
Calculates precise weight based on Gender Physiology.
|
| 96 |
-
"""
|
| 97 |
if base_ratio == 0: return "Bodyweight"
|
| 98 |
|
| 99 |
load = user_weight * base_ratio
|
| 100 |
|
| 101 |
-
#
|
| 102 |
if gender == "Female":
|
| 103 |
-
# Women are relatively stronger in lower body than upper body
|
| 104 |
if muscle_group in ["Legs", "Core"]:
|
| 105 |
-
load *= 0.75
|
| 106 |
else:
|
| 107 |
-
load *= 0.55
|
| 108 |
|
| 109 |
-
#
|
| 110 |
-
if level_tier == 0: load *= 0.6
|
| 111 |
-
if level_tier == 2: load *= 1.3
|
| 112 |
|
| 113 |
-
#
|
| 114 |
-
# Round to nearest 2.5kg (plate size) or 1kg (dumbbell size)
|
| 115 |
if load < 10:
|
| 116 |
final_load = round(load)
|
| 117 |
else:
|
|
@@ -120,7 +113,6 @@ def calculate_weight(base_ratio, user_weight, gender, level_tier, muscle_group):
|
|
| 120 |
return f"{int(final_load)} kg"
|
| 121 |
|
| 122 |
def get_exercises(muscle, equipment, injury, level_tier, count=1):
|
| 123 |
-
# Filter available gear
|
| 124 |
my_gear = []
|
| 125 |
if equipment == "Gym Membership": my_gear = ["Gym", "Barbell", "Dumbbells", "Bodyweight"]
|
| 126 |
elif equipment == "Full Home Gym (Rack+Barbell)": my_gear = ["Barbell", "Dumbbells", "Bodyweight"]
|
|
@@ -131,14 +123,11 @@ def get_exercises(muscle, equipment, injury, level_tier, count=1):
|
|
| 131 |
valid = []
|
| 132 |
|
| 133 |
for ex in pool:
|
| 134 |
-
# Filter Logic
|
| 135 |
if not any(g in my_gear for g in ex["equip"]): continue
|
| 136 |
if injury in ex["bad"]: continue
|
| 137 |
if level_tier < ex["level"]: continue
|
| 138 |
-
|
| 139 |
valid.append(ex)
|
| 140 |
|
| 141 |
-
# SHUFFLE to ensure variety every time
|
| 142 |
random.shuffle(valid)
|
| 143 |
|
| 144 |
if not valid: return [{"name": f"Standard {muscle} Move", "ratio": 0}]
|
|
@@ -146,11 +135,9 @@ def get_exercises(muscle, equipment, injury, level_tier, count=1):
|
|
| 146 |
|
| 147 |
def generate_routine(plan_name, age, gender, weight, goal, equipment, injury, experience):
|
| 148 |
|
| 149 |
-
# Configs
|
| 150 |
goal_settings = GOAL_CONFIG[goal]
|
| 151 |
level_tier = LEVEL_CONFIG[experience]["tier"]
|
| 152 |
|
| 153 |
-
# Structure based on Plan Category
|
| 154 |
slots = []
|
| 155 |
if "Upper" in plan_name or "Push" in plan_name:
|
| 156 |
slots = ["Chest", "Back", "Shoulders", "Arms", "Core"]
|
|
@@ -162,7 +149,6 @@ def generate_routine(plan_name, age, gender, weight, goal, equipment, injury, ex
|
|
| 162 |
slots = ["Legs", "Chest", "Back", "Shoulders", "Core"]
|
| 163 |
title = "Full Body Mix"
|
| 164 |
|
| 165 |
-
# Build Text
|
| 166 |
text = f"WORKOUT PLAN: {title}\n"
|
| 167 |
text += f"User: {age}y | {gender} | {weight}kg | {experience}\n"
|
| 168 |
text += f"Goal: {goal} | Equip: {equipment}\n"
|
|
@@ -178,10 +164,7 @@ def generate_routine(plan_name, age, gender, weight, goal, equipment, injury, ex
|
|
| 178 |
used_names = []
|
| 179 |
|
| 180 |
for i, muscle in enumerate(slots):
|
| 181 |
-
# Fetch exercise
|
| 182 |
candidates = get_exercises(muscle, equipment, injury, level_tier, count=3)
|
| 183 |
-
|
| 184 |
-
# Pick unique
|
| 185 |
selected = candidates[0]
|
| 186 |
for cand in candidates:
|
| 187 |
if cand['name'] not in used_names:
|
|
@@ -189,7 +172,6 @@ def generate_routine(plan_name, age, gender, weight, goal, equipment, injury, ex
|
|
| 189 |
break
|
| 190 |
used_names.append(selected['name'])
|
| 191 |
|
| 192 |
-
# Calculate Load
|
| 193 |
load = calculate_weight(selected['ratio'], weight, gender, level_tier, muscle)
|
| 194 |
|
| 195 |
text += f"{i+1}. {selected['name']} ({muscle})\n"
|
|
@@ -235,6 +217,19 @@ iface = gr.Interface(
|
|
| 235 |
],
|
| 236 |
title="SmartFit AI - Biological Engine",
|
| 237 |
description="Advanced generator with gender-specific strength standards.",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 238 |
theme="soft"
|
| 239 |
)
|
| 240 |
|
|
|
|
| 24 |
"Advanced": {"tier": 2}
|
| 25 |
}
|
| 26 |
|
|
|
|
|
|
|
| 27 |
EXERCISE_DB = {
|
| 28 |
"Chest": [
|
| 29 |
{"name": "Barbell Bench Press", "equip": ["Barbell", "Gym"], "bad": ["Shoulder"], "level": 1, "ratio": 0.9},
|
|
|
|
| 89 |
# ==========================================
|
| 90 |
|
| 91 |
def calculate_weight(base_ratio, user_weight, gender, level_tier, muscle_group):
|
|
|
|
|
|
|
|
|
|
| 92 |
if base_ratio == 0: return "Bodyweight"
|
| 93 |
|
| 94 |
load = user_weight * base_ratio
|
| 95 |
|
| 96 |
+
# Gender Logic
|
| 97 |
if gender == "Female":
|
|
|
|
| 98 |
if muscle_group in ["Legs", "Core"]:
|
| 99 |
+
load *= 0.75
|
| 100 |
else:
|
| 101 |
+
load *= 0.55
|
| 102 |
|
| 103 |
+
# Level Logic
|
| 104 |
+
if level_tier == 0: load *= 0.6
|
| 105 |
+
if level_tier == 2: load *= 1.3
|
| 106 |
|
| 107 |
+
# Rounding
|
|
|
|
| 108 |
if load < 10:
|
| 109 |
final_load = round(load)
|
| 110 |
else:
|
|
|
|
| 113 |
return f"{int(final_load)} kg"
|
| 114 |
|
| 115 |
def get_exercises(muscle, equipment, injury, level_tier, count=1):
|
|
|
|
| 116 |
my_gear = []
|
| 117 |
if equipment == "Gym Membership": my_gear = ["Gym", "Barbell", "Dumbbells", "Bodyweight"]
|
| 118 |
elif equipment == "Full Home Gym (Rack+Barbell)": my_gear = ["Barbell", "Dumbbells", "Bodyweight"]
|
|
|
|
| 123 |
valid = []
|
| 124 |
|
| 125 |
for ex in pool:
|
|
|
|
| 126 |
if not any(g in my_gear for g in ex["equip"]): continue
|
| 127 |
if injury in ex["bad"]: continue
|
| 128 |
if level_tier < ex["level"]: continue
|
|
|
|
| 129 |
valid.append(ex)
|
| 130 |
|
|
|
|
| 131 |
random.shuffle(valid)
|
| 132 |
|
| 133 |
if not valid: return [{"name": f"Standard {muscle} Move", "ratio": 0}]
|
|
|
|
| 135 |
|
| 136 |
def generate_routine(plan_name, age, gender, weight, goal, equipment, injury, experience):
|
| 137 |
|
|
|
|
| 138 |
goal_settings = GOAL_CONFIG[goal]
|
| 139 |
level_tier = LEVEL_CONFIG[experience]["tier"]
|
| 140 |
|
|
|
|
| 141 |
slots = []
|
| 142 |
if "Upper" in plan_name or "Push" in plan_name:
|
| 143 |
slots = ["Chest", "Back", "Shoulders", "Arms", "Core"]
|
|
|
|
| 149 |
slots = ["Legs", "Chest", "Back", "Shoulders", "Core"]
|
| 150 |
title = "Full Body Mix"
|
| 151 |
|
|
|
|
| 152 |
text = f"WORKOUT PLAN: {title}\n"
|
| 153 |
text += f"User: {age}y | {gender} | {weight}kg | {experience}\n"
|
| 154 |
text += f"Goal: {goal} | Equip: {equipment}\n"
|
|
|
|
| 164 |
used_names = []
|
| 165 |
|
| 166 |
for i, muscle in enumerate(slots):
|
|
|
|
| 167 |
candidates = get_exercises(muscle, equipment, injury, level_tier, count=3)
|
|
|
|
|
|
|
| 168 |
selected = candidates[0]
|
| 169 |
for cand in candidates:
|
| 170 |
if cand['name'] not in used_names:
|
|
|
|
| 172 |
break
|
| 173 |
used_names.append(selected['name'])
|
| 174 |
|
|
|
|
| 175 |
load = calculate_weight(selected['ratio'], weight, gender, level_tier, muscle)
|
| 176 |
|
| 177 |
text += f"{i+1}. {selected['name']} ({muscle})\n"
|
|
|
|
| 217 |
],
|
| 218 |
title="SmartFit AI - Biological Engine",
|
| 219 |
description="Advanced generator with gender-specific strength standards.",
|
| 220 |
+
# ======================================================
|
| 221 |
+
# THIS IS THE NEW PART - THE 3 QUICK STARTERS
|
| 222 |
+
# ======================================================
|
| 223 |
+
examples=[
|
| 224 |
+
# Example 1: The Bodybuilder (Young Male, Gym, No Injury)
|
| 225 |
+
[24, "Male", 80, 180, "Muscle Gain", "Gym Membership", "None", "Advanced"],
|
| 226 |
+
|
| 227 |
+
# Example 2: The Rehab/Home User (Female, Knee Injury, Home)
|
| 228 |
+
[35, "Female", 65, 165, "Weight Loss", "Home Dumbbells", "Knee", "Beginner"],
|
| 229 |
+
|
| 230 |
+
# Example 3: The Senior Health (Older Male, Bodyweight, Back safe)
|
| 231 |
+
[60, "Male", 85, 175, "General Health", "Bodyweight Only", "Back", "Beginner"]
|
| 232 |
+
],
|
| 233 |
theme="soft"
|
| 234 |
)
|
| 235 |
|