File size: 16,297 Bytes
4448372 20ff2bf 4448372 6f9ac2a 20ff2bf 6f9ac2a 4448372 6f9ac2a 20ff2bf 4448372 20ff2bf 4448372 6f9ac2a 4c60ef8 4448372 6f9ac2a 4c60ef8 4448372 6f9ac2a 4c60ef8 4448372 20ff2bf 4c60ef8 4448372 4c60ef8 4448372 4c60ef8 4448372 4c60ef8 4448372 4c60ef8 6f9ac2a 20ff2bf 4c60ef8 4448372 4c60ef8 4448372 20ff2bf 4448372 6f9ac2a 4448372 b74efa9 | 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 | def calculate_bmi(weight, height):
h = height / 100
return weight / (h * h)
def bmi_category(bmi):
if bmi < 18.5: return "Underweight"
elif bmi < 25: return "Normal Weight"
elif bmi < 30: return "Overweight"
else: return "Obese"
def bmi_advice(category):
return {
"Underweight": "focus on caloric surplus, compound lifts, and muscle building. Avoid excessive cardio.",
"Normal Weight": "maintain current weight while building lean muscle and improving cardiovascular fitness.",
"Overweight": "incorporate cardio-strength circuits to burn fat while preserving muscle mass.",
"Obese": "prioritise low-impact cardio, mobility work, and progressive resistance training.",
}.get(category, "train consistently and progressively.")
# ββ Injury β forbidden movements mapping ββββββββββββββββββββββββββββββββββββββ
# For each injury, defines exercises/movements to AVOID and safe alternatives
INJURY_RESTRICTIONS = {
"knee": {
"avoid": [
"squats", "lunges", "leg press", "jump", "plyometric",
"running", "step-ups", "leg extension", "deep knee bend"
],
"replace_with": [
"seated leg curl", "hip thrust", "glute bridge", "upper body focus",
"swimming", "seated calf raise", "lying leg curl"
],
"note": "Avoid all deep knee flexion and high-impact lower body movements. "
"Focus on hamstrings, glutes, and upper body. No jumping or running."
},
"shoulder": {
"avoid": [
"overhead press", "military press", "shoulder press", "lateral raise",
"upright row", "behind neck press", "dips", "push press",
"handstand", "overhead squat"
],
"replace_with": [
"face pull", "external rotation", "low cable row", "chest-supported row",
"front raise (light)", "reverse fly", "lower body focus"
],
"note": "Avoid all overhead pressing and upright rows. "
"Focus on lower body, core, and horizontal pulling movements."
},
"back": {
"avoid": [
"deadlift", "barbell row", "good morning", "back squat",
"hyperextension", "heavy carry", "jefferson curl", "stiff-leg deadlift"
],
"replace_with": [
"lat pulldown", "seated cable row", "leg press", "goblet squat",
"plank", "bird dog", "cat-cow", "pallof press"
],
"note": "Avoid all heavy spinal loading. Use braced core on every movement. "
"Prefer machines over free weights for lower body."
},
"wrist": {
"avoid": [
"push-up", "barbell curl", "front rack", "handstand",
"wrist curl", "clean", "snatch", "dumbbell press (grip-heavy)"
],
"replace_with": [
"cable curl", "hammer curl with neutral grip", "machine press",
"tricep pushdown", "leg press", "lower body focus"
],
"note": "Avoid any exercise that loads the wrist in extension or flexion. "
"Use neutral grip or machine alternatives throughout."
},
"ankle": {
"avoid": [
"jump", "box jump", "running", "sprint", "calf raise",
"agility drill", "lunge (walking)", "step-up"
],
"replace_with": [
"seated leg curl", "leg press", "hip thrust", "glute bridge",
"upper body focus", "seated calf raise (light)"
],
"note": "Avoid all weight-bearing dynamic lower body movements. "
"Focus on seated and supine lower body exercises and upper body."
},
"elbow": {
"avoid": [
"tricep dip", "skull crusher", "close-grip bench", "preacher curl",
"pull-up (if painful)", "push-up (if painful)", "barbell curl"
],
"replace_with": [
"cable tricep pushdown", "cable curl", "neutral grip row",
"machine press", "leg press", "lower body focus"
],
"note": "Avoid full elbow extension under load and deep elbow flexion. "
"Use cables over free weights to reduce joint stress."
},
"hip": {
"avoid": [
"deep squat", "leg press (full range)", "hip flexor stretch",
"lunge", "step-up", "running", "sprint", "jump"
],
"replace_with": [
"glute bridge", "clamshell", "side-lying abduction",
"upper body focus", "seated leg curl", "light walking"
],
"note": "Avoid deep hip flexion and high-impact movements. "
"Focus on gentle hip strengthening and upper body work."
},
"neck": {
"avoid": [
"neck extension", "shrug", "overhead press", "behind-neck press",
"upright row", "any exercise causing neck strain"
],
"replace_with": [
"face pull", "chest-supported row", "lower body focus",
"plank", "dead bug", "pallof press"
],
"note": "Avoid all cervical loading and overhead work. "
"Keep head neutral on every exercise. No shrugs or overhead pressing."
},
"hamstring": {
"avoid": [
"deadlift", "stiff-leg deadlift", "leg curl (full range, high load)",
"sprint", "running", "jump", "good morning"
],
"replace_with": [
"leg press", "goblet squat", "hip thrust", "glute bridge",
"upper body focus", "light walking"
],
"note": "Avoid high hamstring tension under load. "
"Focus on quad-dominant lower body movements and upper body."
},
"calf": {
"avoid": [
"calf raise (heavy)", "jump", "box jump", "sprint",
"running", "agility drill"
],
"replace_with": [
"leg press", "hip thrust", "upper body focus",
"seated calf raise (very light)", "swimming"
],
"note": "Avoid all explosive and heavy plantarflexion. "
"Focus on upper body and non-impact lower body movements."
},
"rotator cuff": {
"avoid": [
"overhead press", "lateral raise (heavy)", "internal rotation under load",
"behind-neck pull-down", "upright row", "dip", "bench press (wide grip)"
],
"replace_with": [
"external rotation (band/cable)", "face pull", "chest-supported row",
"neutral grip row", "lower body focus", "light front raise"
],
"note": "Avoid overhead and impingement-risk positions. "
"Strengthen rotator cuff with low-load external rotation drills. "
"No heavy pressing until cleared."
},
"achilles": {
"avoid": [
"calf raise", "jump", "box jump", "sprint", "running",
"agility drill", "walking lunge", "step-up"
],
"replace_with": [
"seated leg curl", "leg press", "hip thrust",
"upper body focus", "light cycling (seated)"
],
"note": "Avoid all Achilles loading. Strictly no jumping, running, or calf work. "
"Focus on seated/supine lower body and upper body movements."
},
}
def build_injury_block(injuries):
"""
Build the injury restriction block for the AI prompt.
Returns empty string if no injuries.
"""
if not injuries:
return ""
lines = ["βββ INJURY & LIMITATION RESTRICTIONS βββ"]
lines.append(
f"β οΈ The client has the following injuries/limitations: "
f"{', '.join(i.upper() for i in injuries)}"
)
lines.append(
"You MUST apply ALL of the rules below. This is non-negotiable for client safety.\n"
)
all_avoid = []
all_replace = []
for injury in injuries:
key = injury.lower().strip()
if key in INJURY_RESTRICTIONS:
r = INJURY_RESTRICTIONS[key]
lines.append(f"β’ {injury.upper()} injury:")
lines.append(f" - NEVER include: {', '.join(r['avoid'])}")
lines.append(f" - Safe alternatives: {', '.join(r['replace_with'])}")
lines.append(f" - Rule: {r['note']}")
all_avoid.extend(r["avoid"])
all_replace.extend(r["replace_with"])
lines.append(
f"\nβ GLOBAL FORBIDDEN EXERCISES (across ALL {len(injuries)} injuries): "
+ ", ".join(sorted(set(all_avoid)))
)
lines.append(
"β
Preferred safe alternatives pool: "
+ ", ".join(sorted(set(all_replace)))
)
lines.append(
"\nπ INJURY COMPLIANCE RULES:"
"\n 1. Scan every exercise in your plan against the forbidden list above before including it."
"\n 2. If an exercise even partially loads the injured area, replace it."
"\n 3. Never suggest the user 'try' or 'attempt' a forbidden movement."
"\n 4. For warm-up and cool-down, also avoid stretches that stress the injured area."
"\n 5. Label injury-adapted exercises with '(injury-safe)' so the user knows."
)
return "\n".join(lines)
def build_diet_block(diet_type, cuisine_preference, cuisine_label,
cuisine_icon, cuisine_notes):
"""
Build the diet/cuisine/allergy block for the AI prompt.
"""
diet_display = "Vegetarian (no meat, no fish, no eggs)" if diet_type == "veg" \
else "Non-Vegetarian (chicken, egg, and fish only β NO red meat, NO pork)"
cuisine_str = f"{cuisine_icon} {cuisine_label}" if cuisine_label else "Standard"
lines = [
"βββ DIET & MEAL PLAN REQUIREMENTS βββ",
f"Diet Type : {diet_display}",
f"Cuisine Style : {cuisine_str}",
]
if cuisine_notes and cuisine_notes.strip():
lines.append(f"Allergies/Notes : {cuisine_notes.strip()}")
lines.append(
"\nβ οΈ ALLERGY & PREFERENCE RULES (STRICT):"
"\n 1. Read the Allergies/Notes above carefully."
"\n 2. NEVER include any ingredient the user has flagged as an allergy or exclusion."
"\n 3. If the user says 'no eggs' β zero egg-containing meals across all days."
"\n 4. If the user says 'lactose intolerant' β no dairy in any meal."
"\n 5. Treat every restriction as a hard medical requirement, not a preference."
"\n 6. When in doubt, substitute with a safe alternative and note it."
)
lines += [
"\nMEAL PLAN RULES:",
" β’ Every training day must include: Breakfast, Pre-Workout Snack, "
"Lunch, Post-Workout Meal, Dinner.",
" β’ Every rest day must include: Breakfast, Mid-Morning Snack, "
"Lunch, Afternoon Snack, Dinner.",
f" β’ All meals must match the {cuisine_str} cuisine style.",
" β’ Include approximate macros (protein / carbs / fat) for each meal.",
" β’ Include total daily calories.",
" β’ Meals must support the client's fitness goal (see CLIENT PROFILE).",
" β’ Do NOT suggest any ingredient excluded in Allergies/Notes above.",
]
return "\n".join(lines)
def build_prompt(name, gender, height, weight, goal, fitness_level, equipment,
days_per_week=5, months=1,
injuries=None, diet_type="nonveg",
cuisine_preference="", cuisine_label="",
cuisine_icon="", cuisine_notes=""):
"""
Build the full AI prompt for workout + diet plan generation.
New parameters vs old version:
injuries : list of injury strings e.g. ["knee", "shoulder"]
diet_type : "veg" or "nonveg"
cuisine_preference : cuisine id string e.g. "indian_nonveg"
cuisine_label : human-readable label e.g. "Indian"
cuisine_icon : emoji icon e.g. "π"
cuisine_notes : free-text allergies/preferences e.g. "no eggs, lactose intolerant"
"""
if injuries is None:
injuries = []
bmi = calculate_bmi(weight, height)
bmi_cat = bmi_category(bmi)
eq_list = ", ".join(equipment) if equipment else "Bodyweight only (no equipment)"
advice = bmi_advice(bmi_cat)
total_days = days_per_week * 4 * months
total_days = min(total_days, 30)
intensity_map = {
"Beginner": "2β3 working sets, moderate weight, longer rest (90s). Prioritise form over load.",
"Intermediate": "3β4 working sets, progressive overload, 60β75s rest.",
"Advanced": "4β5 working sets, heavy compound movements, 45β60s rest, supersets where appropriate.",
}
intensity = intensity_map.get(fitness_level, "3 sets, 60s rest.")
# Build optional blocks
injury_block = build_injury_block(injuries)
diet_block = build_diet_block(diet_type, cuisine_preference,
cuisine_label, cuisine_icon, cuisine_notes)
# Injury summary line for the rules section
injury_rule = ""
if injuries:
injury_rule = (
f"\n8. INJURIES: The client has {', '.join(injuries)} injuries. "
f"STRICTLY follow the injury restrictions block above. "
f"Mark every adapted exercise with '(injury-safe)'."
)
allergy_rule = ""
if cuisine_notes and cuisine_notes.strip():
allergy_rule = (
f"\n9. ALLERGIES: '{cuisine_notes.strip()}' β "
f"zero tolerance. Never include any flagged ingredient in any meal."
)
prompt = f"""You are an elite certified personal trainer, sports scientist, and registered nutritionist.
Create a complete, professional {total_days}-day personalised workout AND diet plan
({days_per_week} training days per week Γ {months} month{'s' if months > 1 else ''}).
βββ CLIENT PROFILE βββ
Name : {name}
Gender : {gender}
Height / Weight: {height} cm / {weight} kg
BMI : {bmi:.1f} ({bmi_cat})
Primary Goal : {goal}
Fitness Level : {fitness_level}
Equipment : {eq_list}
Plan Duration : {days_per_week} days/week for {months} month{'s' if months > 1 else ''} = {total_days} workout days total
βββ PROGRAMMING NOTES βββ
β’ BMI guidance : {advice}
β’ Intensity : {intensity}
β’ Equipment : Only use the equipment listed above. Substitute with bodyweight if needed.
β’ Progression : Each week should slightly increase intensity, volume or complexity.
β’ Rest days : Build rest days into the weekly cycle naturally ({days_per_week} days/week training).
{injury_block}
{diet_block}
βββ REQUIRED OUTPUT FORMAT βββ
Use EXACTLY this structure for ALL {total_days} days:
## Day 1 - [Muscle Group / Focus]
**Warm-Up (5 min)**
- Exercise 1: sets x reps
- Exercise 2: sets x reps
**Main Workout**
- Exercise 1 β sets x reps (rest 60s)
- Exercise 2 β sets x reps (rest 60s)
- Exercise 3 β sets x reps (rest 60s)
- Exercise 4 β sets x reps (rest 60s)
- Exercise 5 β sets x reps (rest 60s)
**Cool-Down (3 min)**
- Stretch 1
- Stretch 2
**Meals for the Day**
- Breakfast: [meal name] β [brief description] | Protein: Xg | Carbs: Xg | Fat: Xg
- Pre-Workout Snack: [meal] | Protein: Xg | Carbs: Xg | Fat: Xg
- Lunch: [meal] β [brief description] | Protein: Xg | Carbs: Xg | Fat: Xg
- Post-Workout Meal: [meal] | Protein: Xg | Carbs: Xg | Fat: Xg
- Dinner: [meal] β [brief description] | Protein: Xg | Carbs: Xg | Fat: Xg
- Daily Total: ~XXXX kcal | Protein: Xg | Carbs: Xg | Fat: Xg
[Continue this exact structure for Day 2 through Day {total_days}]
βββ FINAL SECTION βββ
End with ONE personalised motivational paragraph addressed directly to {name}.
βββ RULES βββ
1. Day headers must start with "## Day N -"
2. Include sets Γ reps for every exercise (e.g. 3 x 12 reps)
3. Rest periods in parentheses after each exercise
4. No exercises unsafe for {fitness_level} level
5. Ensure variety across all days β don't repeat same muscle groups back-to-back
6. Be specific β no vague instructions
7. Generate ALL {total_days} days β do not stop early{injury_rule}{allergy_rule}
"""
return prompt, bmi, bmi_cat |