File size: 11,076 Bytes
2f6effc
 
 
58b4d1b
2f6effc
74ed72f
2f6effc
 
f430353
55b5c0f
f430353
 
 
55b5c0f
 
 
 
 
f430353
 
 
55b5c0f
 
 
f430353
 
 
 
 
55b5c0f
f430353
55b5c0f
 
 
 
f430353
 
 
55b5c0f
f430353
 
55b5c0f
f430353
 
55b5c0f
f430353
 
 
55b5c0f
f430353
55b5c0f
 
 
 
 
 
f430353
 
 
55b5c0f
f430353
55b5c0f
f430353
55b5c0f
f430353
 
 
55b5c0f
 
f430353
55b5c0f
f430353
 
 
 
55b5c0f
 
f430353
 
55b5c0f
f430353
 
55b5c0f
f430353
 
 
 
55b5c0f
f430353
 
55b5c0f
74ed72f
58b4d1b
74ed72f
a78d19b
7821ae6
55b5c0f
 
7821ae6
55b5c0f
7821ae6
55b5c0f
7821ae6
 
 
55b5c0f
7821ae6
55b5c0f
 
 
 
 
 
92cf4ac
f430353
74ed72f
f430353
 
 
74ed72f
92cf4ac
f430353
 
74ed72f
f430353
 
 
 
 
 
 
 
55b5c0f
f430353
a78d19b
74ed72f
a78d19b
f430353
55b5c0f
a78d19b
74ed72f
a78d19b
55b5c0f
 
a78d19b
55b5c0f
 
 
 
 
f430353
55b5c0f
f430353
55b5c0f
 
f430353
55b5c0f
 
 
f430353
 
55b5c0f
f430353
 
 
 
55b5c0f
f430353
 
 
 
 
 
74ed72f
55b5c0f
74ed72f
f430353
55b5c0f
a78d19b
f430353
 
55b5c0f
f430353
55b5c0f
f430353
a78d19b
7d003a9
f430353
74ed72f
 
7d003a9
 
 
2f6effc
74ed72f
2f6effc
74ed72f
58b4d1b
55b5c0f
2f6effc
f430353
2f6effc
74ed72f
2f6effc
74ed72f
2f6effc
 
 
f430353
2f6effc
 
f430353
2f6effc
 
55b5c0f
 
2f6effc
55b5c0f
 
7821ae6
 
 
 
 
 
 
 
 
 
 
 
 
2f6effc
 
 
f430353
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
import gradio as gr
import joblib
import pandas as pd
import random

# 1. Load Model
model = joblib.load('fitness_model.joblib')

# ==========================================
#        CONFIG DICTIONARIES
# ==========================================

GOAL_CONFIG = {
    "Strength": {"sets": 5, "reps": "3-5", "rest": "3 min", "intensity": "Heavy"},
    "Muscle Gain": {"sets": 3, "reps": "8-12", "rest": "90 sec", "intensity": "Moderate"},
    "Weight Loss": {"sets": 4, "reps": "15-20", "rest": "45 sec", "intensity": "High Tempo"},
    "Endurance": {"sets": 2, "reps": "20-25", "rest": "30 sec", "intensity": "Light"},
    "General Health": {"sets": 3, "reps": "12-15", "rest": "60 sec", "intensity": "Moderate"}
}

LEVEL_CONFIG = {
    "Beginner": {"tier": 0},
    "Intermediate": {"tier": 1},
    "Advanced": {"tier": 2}
}

EXERCISE_DB = {
    "Chest": [
        {"name": "Barbell Bench Press", "equip": ["Barbell", "Gym"], "bad": ["Shoulder"], "level": 1, "ratio": 0.9},
        {"name": "Dumbbell Chest Press", "equip": ["Dumbbells", "Gym"], "bad": [], "level": 0, "ratio": 0.35},
        {"name": "Incline Dumbbell Press", "equip": ["Dumbbells", "Gym"], "bad": ["Shoulder"], "level": 1, "ratio": 0.3},
        {"name": "Machine Chest Press", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0.6},
        {"name": "Push-ups", "equip": ["Bodyweight"], "bad": ["Wrist"], "level": 0, "ratio": 0},
        {"name": "Cable Flys", "equip": ["Gym"], "bad": [], "level": 1, "ratio": 0.15},
        {"name": "Dumbbell Flys", "equip": ["Dumbbells"], "bad": ["Shoulder"], "level": 0, "ratio": 0.12},
        {"name": "Weighted Dips", "equip": ["Gym"], "bad": ["Shoulder"], "level": 2, "ratio": 0},
    ],
    "Back": [
        {"name": "Deadlift", "equip": ["Barbell", "Gym"], "bad": ["Back"], "level": 2, "ratio": 1.4},
        {"name": "Lat Pulldown", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0.6},
        {"name": "Seated Cable Row", "equip": ["Gym"], "bad": ["Back"], "level": 0, "ratio": 0.6},
        {"name": "Barbell Bent Over Row", "equip": ["Barbell", "Gym"], "bad": ["Back"], "level": 1, "ratio": 0.7},
        {"name": "Single Arm Dumbbell Row", "equip": ["Dumbbells", "Gym"], "bad": [], "level": 0, "ratio": 0.3},
        {"name": "Pull-ups", "equip": ["Bodyweight", "Gym"], "bad": ["Shoulder"], "level": 1, "ratio": 0},
        {"name": "Chest Supported Row", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0.5},
        {"name": "Inverted Row", "equip": ["Bodyweight"], "bad": [], "level": 0, "ratio": 0},
    ],
    "Legs": [
        {"name": "Barbell Squat", "equip": ["Barbell", "Gym"], "bad": ["Back", "Knee"], "level": 2, "ratio": 1.1},
        {"name": "Leg Press", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 1.8},
        {"name": "Goblet Squat", "equip": ["Dumbbells", "Gym"], "bad": ["Knee"], "level": 0, "ratio": 0.4},
        {"name": "Walking Lunges", "equip": ["Dumbbells", "Bodyweight"], "bad": ["Knee"], "level": 1, "ratio": 0.15},
        {"name": "Romanian Deadlift", "equip": ["Barbell", "Dumbbells"], "bad": ["Back"], "level": 1, "ratio": 0.8},
        {"name": "Lying Leg Curl", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0.35},
        {"name": "Leg Extensions", "equip": ["Gym"], "bad": ["Knee"], "level": 0, "ratio": 0.35},
        {"name": "Bulgarian Split Squat", "equip": ["Dumbbells"], "bad": ["Knee"], "level": 2, "ratio": 0.2},
        {"name": "Glute Bridges", "equip": ["Bodyweight"], "bad": [], "level": 0, "ratio": 0},
    ],
    "Shoulders": [
        {"name": "Overhead Barbell Press", "equip": ["Barbell", "Gym"], "bad": ["Shoulder", "Back"], "level": 2, "ratio": 0.5},
        {"name": "Seated Dumbbell Press", "equip": ["Dumbbells", "Gym"], "bad": ["Shoulder"], "level": 0, "ratio": 0.25},
        {"name": "Lateral Raises", "equip": ["Dumbbells", "Gym"], "bad": [], "level": 0, "ratio": 0.08},
        {"name": "Face Pulls", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0.2},
        {"name": "Front Raises", "equip": ["Dumbbells"], "bad": [], "level": 0, "ratio": 0.08},
    ],
    "Arms": [
        {"name": "Barbell Curls", "equip": ["Barbell", "Gym"], "bad": ["Wrist"], "level": 0, "ratio": 0.25},
        {"name": "Dumbbell Hammer Curls", "equip": ["Dumbbells", "Gym"], "bad": [], "level": 0, "ratio": 0.12},
        {"name": "Tricep Rope Pushdown", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0.25},
        {"name": "Skullcrushers", "equip": ["Barbell", "Dumbbells"], "bad": ["Elbow"], "level": 1, "ratio": 0.2},
        {"name": "Dips", "equip": ["Bodyweight"], "bad": ["Shoulder"], "level": 1, "ratio": 0},
    ],
    "Core": [
        {"name": "Plank", "equip": ["Bodyweight"], "bad": [], "level": 0, "ratio": 0},
        {"name": "Cable Woodchoppers", "equip": ["Gym"], "bad": ["Back"], "level": 1, "ratio": 0.3},
        {"name": "Russian Twists", "equip": ["Bodyweight"], "bad": ["Back"], "level": 0, "ratio": 0},
        {"name": "Hanging Leg Raises", "equip": ["Gym"], "bad": ["Shoulder"], "level": 2, "ratio": 0},
    ],
    "Cardio": [
        {"name": "Treadmill Run", "equip": ["Gym"], "bad": ["Knee"], "level": 0, "ratio": 0},
        {"name": "Elliptical", "equip": ["Gym"], "bad": [], "level": 0, "ratio": 0},
        {"name": "Burpees", "equip": ["Bodyweight"], "bad": ["Back", "Knee"], "level": 2, "ratio": 0},
        {"name": "Jump Rope", "equip": ["Bodyweight"], "bad": ["Knee", "Ankle"], "level": 1, "ratio": 0},
    ]
}

# ==========================================
#           LOGIC ENGINE (CALCULATOR)
# ==========================================

def calculate_weight(base_ratio, user_weight, gender, level_tier, muscle_group):
    if base_ratio == 0: return "Bodyweight"
    
    load = user_weight * base_ratio
    
    # Gender Logic
    if gender == "Female":
        if muscle_group in ["Legs", "Core"]:
            load *= 0.75
        else:
            load *= 0.55
    
    # Level Logic
    if level_tier == 0: load *= 0.6
    if level_tier == 2: load *= 1.3
    
    # Rounding
    if load < 10:
        final_load = round(load)
    else:
        final_load = 2.5 * round(load / 2.5)
        
    return f"{int(final_load)} kg"

def get_exercises(muscle, equipment, injury, level_tier, count=1):
    my_gear = []
    if equipment == "Gym Membership": my_gear = ["Gym", "Barbell", "Dumbbells", "Bodyweight"]
    elif equipment == "Full Home Gym (Rack+Barbell)": my_gear = ["Barbell", "Dumbbells", "Bodyweight"]
    elif equipment == "Home Dumbbells": my_gear = ["Dumbbells", "Bodyweight"]
    else: my_gear = ["Bodyweight"]

    pool = EXERCISE_DB.get(muscle, [])
    valid = []
    
    for ex in pool:
        if not any(g in my_gear for g in ex["equip"]): continue
        if injury in ex["bad"]: continue
        if level_tier < ex["level"]: continue
        valid.append(ex)
    
    random.shuffle(valid)
    
    if not valid: return [{"name": f"Standard {muscle} Move", "ratio": 0}]
    return valid[:count]

def generate_routine(plan_name, age, gender, weight, goal, equipment, injury, experience):
    
    goal_settings = GOAL_CONFIG[goal]
    level_tier = LEVEL_CONFIG[experience]["tier"]
    
    slots = []
    if "Upper" in plan_name or "Push" in plan_name:
        slots = ["Chest", "Back", "Shoulders", "Arms", "Core"]
        title = "Upper Body Focus"
    elif "Lower" in plan_name or "Legs" in plan_name:
        slots = ["Legs", "Legs", "Legs", "Core", "Cardio"]
        title = "Lower Body Focus"
    else:
        slots = ["Legs", "Chest", "Back", "Shoulders", "Core"]
        title = "Full Body Mix"

    text = f"WORKOUT PLAN: {title}\n"
    text += f"User: {age}y | {gender} | {weight}kg | {experience}\n"
    text += f"Goal: {goal} | Equip: {equipment}\n"
    text += "="*40 + "\n\n"
    
    text += f"WARM-UP (5-8 mins):\n"
    if injury == "Knee": text += "- Arm Circles & Torso Twists\n- Glute Bridges\n\n"
    else: text += "- Jumping Jacks\n- Dynamic Stretching\n\n"
    
    text += f"MAIN WORKOUT:\n"
    text += f"Sets: {goal_settings['sets']} | Reps: {goal_settings['reps']} | Rest: {goal_settings['rest']}\n\n"
    
    used_names = []
    
    for i, muscle in enumerate(slots):
        candidates = get_exercises(muscle, equipment, injury, level_tier, count=3)
        selected = candidates[0]
        for cand in candidates:
            if cand['name'] not in used_names:
                selected = cand
                break
        used_names.append(selected['name'])
        
        load = calculate_weight(selected['ratio'], weight, gender, level_tier, muscle)
        
        text += f"{i+1}. {selected['name']} ({muscle})\n"
        text += f"   Rec. Load: {load}\n\n"
        
    text += f"FINISHER:\n"
    if goal in ["Weight Loss", "Endurance"]:
        text += "HIIT: 30s Work / 30s Rest (5 Rounds)"
    else:
        text += "Core Stability: 3 Sets to Failure"

    return text

# 6. WRAPPER
def predict_wrapper(age, gender, weight, height, goal, equipment, injury, experience):
    input_df = pd.DataFrame({
        'Age': [age], 'Gender': [gender], 'Weight_kg': [weight], 
        'Height_cm': [height], 'Goal': [goal], 'Equipment': [equipment], 
        'Injury': [injury], 'Experience': [experience]
    })
    plan_name = model.predict(input_df)[0]
    
    routine = generate_routine(plan_name, age, gender, weight, goal, equipment, injury, experience)
    
    return routine, f"AI Strategy: {plan_name}"

# 7. LAUNCH
iface = gr.Interface(
    fn=predict_wrapper,
    inputs=[
        gr.Slider(18, 80, step=1, value=25, label="Age"),
        gr.Radio(["Male", "Female"], label="Gender", value="Male"),
        gr.Number(label="Weight (kg)", value=75),
        gr.Number(label="Height (cm)", value=175),
        gr.Dropdown(list(GOAL_CONFIG.keys()), label="Goal", value="Muscle Gain"),
        gr.Dropdown(['Gym Membership', 'Home Dumbbells', 'Bodyweight Only', 'Full Home Gym (Rack+Barbell)'], label="Equipment", value="Gym Membership"),
        gr.Dropdown(['None', 'Knee', 'Back', 'Shoulder', 'Ankle'], label="Injury", value="None"),
        gr.Dropdown(list(LEVEL_CONFIG.keys()), label="Experience", value="Intermediate")
    ],
    outputs=[
        gr.Textbox(label="Generated Workout", lines=20),
        gr.Textbox(label="AI Note")
    ],
    title="SmartFit AI - Biological Engine",
    description="Advanced generator with gender-specific strength standards.",
    # ======================================================
    # THIS IS THE NEW PART - THE 3 QUICK STARTERS
    # ======================================================
    examples=[
        # Example 1: The Bodybuilder (Young Male, Gym, No Injury)
        [24, "Male", 80, 180, "Muscle Gain", "Gym Membership", "None", "Advanced"],
        
        # Example 2: The Rehab/Home User (Female, Knee Injury, Home)
        [35, "Female", 65, 165, "Weight Loss", "Home Dumbbells", "Knee", "Beginner"],
        
        # Example 3: The Senior Health (Older Male, Bodyweight, Back safe)
        [60, "Male", 85, 175, "General Health", "Bodyweight Only", "Back", "Beginner"]
    ],
    theme="soft"
)

iface.launch()