AlaaElsayed commited on
Commit
8b7d0a4
·
1 Parent(s): 74ad615

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -0
app.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, make_response
2
+ import pandas as pd
3
+ import joblib
4
+ from flask_cors import CORS
5
+ from collections import OrderedDict
6
+ import json
7
+
8
+ app = Flask(__name__)
9
+ CORS(app) # Enables cross-origin requests (e.g., from Flutter)
10
+
11
+ # Load models and encoders
12
+ food_model = joblib.load("goal_classifier.pkl")
13
+ exercise_model = joblib.load("exercise_classifier.pkl")
14
+ encoders = joblib.load("encoders.pkl")
15
+ df = pd.read_csv("fitness_meal_plan_with_exercises.csv")
16
+
17
+ # Load individual encoders
18
+ le_gender = encoders['gender']
19
+ le_workout = encoders['workout']
20
+ le_goal = encoders['goal']
21
+ le_exercise = encoders['exercise']
22
+ preprocessor = encoders['preprocessor']
23
+
24
+ # --- Utilities ---
25
+ def calculate_bmi(weight_kg, height_cm):
26
+ return weight_kg / ((height_cm / 100) ** 2)
27
+
28
+ def get_meal_plan(week, day):
29
+ filtered = df[(df['Week'] == week) & (df['Day'] == day)]
30
+ if not filtered.empty:
31
+ row = filtered.iloc[0]
32
+ return OrderedDict([
33
+ ("Breakfast", {"Meal": row["Breakfast"], "Calories": int(row["Calories_Breakfast"])}),
34
+ ("Snack_1", {"Meal": row["Snack_1"], "Calories": int(row["Calories_Snack_1"])}),
35
+ ("Lunch", {"Meal": row["Lunch"], "Calories": int(row["Calories_Lunch"])}),
36
+ ("Snack_2", {"Meal": row["Snack_2"], "Calories": int(row["Calories_Snack_2"])}),
37
+ ("Dinner", {"Meal": row["Dinner"], "Calories": int(row["Calories_Dinner"])})
38
+ ])
39
+ return OrderedDict()
40
+
41
+ def get_exercise(week, day):
42
+ filtered = df[(df['Week'] == week) & (df['Day'] == day)]
43
+ if not filtered.empty:
44
+ row = filtered.iloc[0]
45
+ # Decode label if encoded
46
+ try:
47
+ row['Exercise_Name'] = le_exercise.inverse_transform([row['Exercise_Name']])[0]
48
+ except:
49
+ pass
50
+ return row[['Exercise_Name', 'Exercise_Description', 'Exercise_Duration']].to_dict()
51
+ return {}
52
+
53
+ # --- Main API Endpoint ---
54
+ @app.route("/recommend", methods=["POST"])
55
+ def recommend():
56
+ data = request.get_json()
57
+
58
+ try:
59
+ # Encode inputs
60
+ user_input = {
61
+ 'Gender': le_gender.transform([data['Gender']])[0],
62
+ 'Age': data['Age'],
63
+ 'Height_cm': data['Height_cm'],
64
+ 'Weight_kg': data['Weight_kg'],
65
+ 'Workout_History': le_workout.transform([data['Workout_History']])[0],
66
+ 'Goal': le_goal.transform([data['Goal']])[0],
67
+ 'Week': data['Week'],
68
+ 'Day': data['Day']
69
+ }
70
+
71
+ # Add BMI for potential future use
72
+ user_input['BMI'] = calculate_bmi(user_input['Weight_kg'], user_input['Height_cm'])
73
+
74
+ # Prepare input for prediction (not used in current response)
75
+ user_df = pd.DataFrame([user_input])
76
+ user_X = preprocessor.transform(user_df)
77
+
78
+ # Perform predictions (optional if not needed in response)
79
+ food_model.predict(user_X)
80
+ exercise_model.predict(user_X)
81
+
82
+ # Return either meal or exercise plan
83
+ if data['choice'] == 'meal':
84
+ meal_plan = get_meal_plan(user_input['Week'], user_input['Day'])
85
+ response_data = {
86
+ "Meal_Plan": meal_plan,
87
+ "Total_Calories": sum(meal["Calories"] for meal in meal_plan.values())
88
+ }
89
+
90
+ elif data['choice'] == 'exercise':
91
+ exercise = get_exercise(user_input['Week'], user_input['Day'])
92
+ response_data = {"Exercise": exercise}
93
+
94
+ else:
95
+ return jsonify({"error": "Invalid choice. Must be 'meal' or 'exercise'"}), 400
96
+
97
+ return make_response(json.dumps(response_data, ensure_ascii=False), 200, {'Content-Type': 'application/json'})
98
+
99
+ except Exception as e:
100
+ return jsonify({'error': str(e)}), 400
101
+
102
+ # --- Run the Flask app ---
103
+ if __name__ == '__main__':
104
+ app.run(host='0.0.0.0', port=5000, debug=True)