Anupam007 commited on
Commit
93a433f
·
verified ·
1 Parent(s): 6926480

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -326
app.py CHANGED
@@ -4,427 +4,232 @@ import numpy as np
4
  from sklearn.metrics.pairwise import cosine_similarity
5
  from datasets import load_dataset
6
  import warnings
 
7
  warnings.filterwarnings('ignore')
8
 
9
- # Load the Indian food dataset from Hugging Face
10
- # Note: You need to be logged in to Hugging Face to access this dataset
11
- # Run this in a separate cell first: `huggingface-cli login`
12
  try:
13
  ds = load_dataset("Anupam007/nutarian-Indianfood")
14
- # Convert the dataset to a pandas DataFrame
15
  food_df = pd.DataFrame(ds['train'])
16
- print(f"Successfully loaded the dataset with {len(food_df)} items")
17
 
18
- # Display the first few rows to understand the structure
19
- print("Dataset columns:", food_df.columns.tolist())
20
-
21
- # Clean and prepare the dataset
22
- # Assuming the dataset has columns like name, calories, protein, carbs, fat, etc.
23
- # Adjust these column names based on the actual dataset structure
24
  required_columns = ['name', 'calories', 'protein', 'carbohydrates', 'fat']
25
-
26
- # Display sample of the data to see what we're working with
27
- print(food_df.head())
28
-
29
- # Rename columns if necessary to match our application's expectations
30
- # This is a placeholder - adjust based on actual column names
31
- column_mapping = {
32
- 'Name': 'name',
33
- 'Calories': 'calories',
34
- 'Protein': 'protein',
35
- 'Carbs': 'carbohydrates',
36
- 'Fats': 'fat',
37
- 'Category': 'food_group'
38
- }
39
-
40
- # Apply the mapping for columns that exist
41
  for old_col, new_col in column_mapping.items():
42
  if old_col in food_df.columns:
43
  food_df = food_df.rename(columns={old_col: new_col})
44
-
45
- # Add a default serving size if not present
46
  if 'serving_size' not in food_df.columns:
47
- food_df['serving_size'] = 100 # Default serving in grams
48
-
49
- # Ensure numeric columns are properly typed
50
  numeric_cols = ['calories', 'protein', 'carbohydrates', 'fat', 'serving_size']
51
  for col in numeric_cols:
52
  if col in food_df.columns:
53
  food_df[col] = pd.to_numeric(food_df[col], errors='coerce')
54
-
55
- # Handle any missing values
56
  food_df = food_df.dropna(subset=['name', 'calories'])
57
-
58
- print(f"Prepared dataset with {len(food_df)} items")
59
-
60
  except Exception as e:
61
- print(f"Error loading dataset: {e}")
62
- print("Falling back to sample data...")
63
-
64
- # Create a sample Indian food database with nutritional information as fallback
65
  food_data = {
66
- 'name': [
67
- 'Aloo Gobi', 'Butter Chicken', 'Chana Masala', 'Dal Makhani', 'Palak Paneer',
68
- 'Roti', 'Naan', 'Basmati Rice', 'Idli', 'Dosa',
69
- 'Sambar', 'Raita', 'Biryani', 'Tandoori Chicken', 'Vada',
70
- 'Uttapam', 'Upma', 'Poha', 'Pav Bhaji', 'Chole Bhature'
71
- ],
72
- 'calories': [
73
- 150, 325, 180, 230, 190,
74
- 120, 260, 150, 58, 133,
75
- 152, 75, 292, 165, 97,
76
- 188, 185, 270, 210, 427
77
- ],
78
- 'protein': [
79
- 3.5, 28, 7.5, 9, 11,
80
- 3, 9, 3.5, 2, 3.7,
81
- 3.8, 3.5, 9.5, 31, 2.2,
82
- 5.3, 3.5, 5.2, 6, 13.2
83
- ],
84
- 'carbohydrates': [
85
- 15, 10, 30, 31, 6,
86
- 18, 33, 32, 12, 25.2,
87
- 28, 3.5, 46, 0, 16.3,
88
- 28.5, 31, 44, 22.7, 57.2
89
- ],
90
- 'fat': [
91
- 8, 17, 6, 9, 12.5,
92
- 3.7, 11, 0.5, 0.2, 3.8,
93
- 5.6, 5, 9, 3.6, 3.9,
94
- 7.2, 7, 12, 12, 20
95
- ],
96
- 'serving_size': [
97
- 100, 100, 100, 100, 100,
98
- 30, 80, 100, 40, 100,
99
- 100, 100, 100, 100, 35,
100
- 100, 100, 100, 100, 120
101
- ],
102
- 'food_group': [
103
- 'Vegetable', 'Protein', 'Protein', 'Protein', 'Protein',
104
- 'Grain', 'Grain', 'Grain', 'Grain', 'Grain',
105
- 'Vegetable', 'Dairy', 'Mixed', 'Protein', 'Snack',
106
- 'Grain', 'Grain', 'Grain', 'Mixed', 'Mixed'
107
- ]
108
  }
109
-
110
- # Convert to DataFrame
111
  food_df = pd.DataFrame(food_data)
112
- print(f"Created fallback dataset with {len(food_df)} items")
113
 
114
- # Function to calculate daily caloric needs based on Harris-Benedict Equation
 
 
 
 
 
 
 
115
  def calculate_caloric_needs(weight, height, age, gender, activity_level):
 
 
116
  if gender.lower() == 'male':
117
  bmr = 88.362 + (13.397 * weight) + (4.799 * height) - (5.677 * age)
118
  else:
119
  bmr = 447.593 + (9.247 * weight) + (3.098 * height) - (4.330 * age)
120
-
121
- activity_multipliers = {
122
- 'sedentary': 1.2,
123
- 'lightly active': 1.375,
124
- 'moderately active': 1.55,
125
- 'very active': 1.725,
126
- 'extra active': 1.9
127
- }
128
-
129
  return round(bmr * activity_multipliers[activity_level.lower()])
130
 
131
- # Function to calculate macronutrient distribution based on goals
132
  def calculate_macros(caloric_needs, goal):
133
  macros = {}
134
-
135
  if goal.lower() == 'weight loss':
136
- caloric_needs = caloric_needs * 0.85 # 15% deficit
137
- macros['protein'] = (caloric_needs * 0.30) / 4 # 30% protein
138
- macros['fat'] = (caloric_needs * 0.30) / 9 # 30% fat
139
- macros['carbs'] = (caloric_needs * 0.40) / 4 # 40% carbs
140
-
141
  elif goal.lower() == 'maintenance':
142
- macros['protein'] = (caloric_needs * 0.25) / 4 # 25% protein
143
- macros['fat'] = (caloric_needs * 0.30) / 9 # 30% fat
144
- macros['carbs'] = (caloric_needs * 0.45) / 4 # 45% carbs
145
-
146
  elif goal.lower() == 'muscle gain':
147
- caloric_needs = caloric_needs * 1.10 # 10% surplus
148
- macros['protein'] = (caloric_needs * 0.30) / 4 # 30% protein
149
- macros['fat'] = (caloric_needs * 0.25) / 9 # 25% fat
150
- macros['carbs'] = (caloric_needs * 0.45) / 4 # 45% carbs
151
-
152
- return {
153
- 'calories': round(caloric_needs),
154
- 'protein': round(macros['protein']),
155
- 'carbs': round(macros['carbs']),
156
- 'fat': round(macros['fat'])
157
- }
158
 
159
- # Function to recommend Indian meals based on nutritional requirements and preferences
160
  def recommend_meals(caloric_needs, macros, restrictions, meals_per_day, meal_preferences):
161
- """
162
- Generate Indian meal recommendations based on user's nutritional needs
163
- """
164
- # Filter foods based on dietary restrictions
165
  filtered_foods = food_df.copy()
166
-
167
  if 'vegetarian' in restrictions:
168
- if 'food_group' in filtered_foods.columns:
169
- filtered_foods = filtered_foods[~filtered_foods['food_group'].str.contains('Non-veg|Meat',
170
- case=False,
171
- na=False)]
172
  if 'vegan' in restrictions:
173
- if 'food_group' in filtered_foods.columns:
174
- filtered_foods = filtered_foods[~filtered_foods['food_group'].str.contains('Non-veg|Meat|Dairy',
175
- case=False,
176
- na=False)]
177
-
178
- # Apply meal preferences (North Indian, South Indian, etc.)
179
- if meal_preferences and 'region' in filtered_foods.columns:
180
- if meal_preferences != "All":
181
- filtered_foods = filtered_foods[filtered_foods['region'].str.contains(meal_preferences,
182
- case=False,
183
- na=False)]
184
-
185
- # If we've filtered too aggressively, reset to the original dataset
186
  if len(filtered_foods) < 10:
187
  filtered_foods = food_df.copy()
188
- print("Warning: Too many filters applied, using complete dataset")
189
-
190
- # Determine typical meal patterns for Indian cuisine
191
- meal_types = {
192
- "Breakfast": ["Idli", "Dosa", "Poha", "Upma", "Paratha", "Uttapam"],
193
- "Lunch": ["Rice", "Dal", "Curry", "Roti", "Sabzi", "Biryani"],
194
- "Dinner": ["Roti", "Sabzi", "Curry", "Rice", "Dal"],
195
- "Snack": ["Vada", "Samosa", "Dhokla", "Chaat"]
196
- }
197
 
198
- # Determine per-meal nutritional targets
 
199
  per_meal_calories = caloric_needs / meals_per_day
200
- per_meal_protein = macros['protein'] / meals_per_day
201
- per_meal_carbs = macros['carbs'] / meals_per_day
202
- per_meal_fat = macros['fat'] / meals_per_day
203
-
204
- # Create meal plans
205
  meal_plan = []
206
- daily_meal_names = ["Breakfast", "Lunch", "Evening Snack", "Dinner"]
207
-
208
- # Make sure we don't exceed the number of meal names we have
209
  if meals_per_day > len(daily_meal_names):
210
- for i in range(len(daily_meal_names), meals_per_day):
211
- daily_meal_names.append(f"Meal {i+1}")
212
-
213
- # Select meal names based on meals_per_day
214
- selected_meal_names = daily_meal_names[:meals_per_day]
215
 
216
- # For each meal, select foods that roughly match the macros
217
- for meal_num, meal_name in enumerate(selected_meal_names):
218
- # Determine meal type
219
- if "Breakfast" in meal_name:
220
- meal_category = "Breakfast"
221
- elif "Lunch" in meal_name:
222
- meal_category = "Lunch"
223
- elif "Dinner" in meal_name:
224
- meal_category = "Dinner"
225
- elif "Snack" in meal_name:
226
- meal_category = "Snack"
227
- else:
228
- meal_category = "Lunch" # Default to lunch for other meals
229
-
230
- # Select 2-4 items that together meet the nutritional requirements
231
- selected_items = []
232
- current_nutrition = {'calories': 0, 'protein': 0, 'carbs': 0, 'fat': 0}
233
-
234
- # Try to find food items that correspond to the meal type
235
- if 'name' in filtered_foods.columns and meal_types.get(meal_category):
236
- potential_items = filtered_foods[filtered_foods['name'].str.contains('|'.join(meal_types[meal_category]),
237
- case=False,
238
- na=False)]
239
- else:
240
- # If we can't filter by meal type, just sample from all foods
241
- potential_items = filtered_foods
242
-
243
- # If too few items match, use the full dataset
244
  if len(potential_items) < 5:
245
  potential_items = filtered_foods
246
-
247
- # Randomly select 2-4 items
248
  num_items = np.random.randint(2, 5)
249
- if len(potential_items) < num_items:
250
- selected_food_items = potential_items.sample(frac=1)
251
- else:
252
- selected_food_items = potential_items.sample(num_items)
253
 
254
- # Calculate total nutrition from selected items
 
255
  for _, food in selected_food_items.iterrows():
256
- # Adjust serving size to meet caloric target
257
- base_calories = food.get('calories', 0)
258
- if base_calories == 0:
259
- continue
260
-
261
- # Start with a reasonable serving size
262
  serving_multiplier = 1.0
263
-
264
- # Add to the meal plan
265
- food_name = food.get('name', "Unknown Food")
266
  serving_size = food.get('serving_size', 100) * serving_multiplier
267
-
268
- # Calculate nutrition
269
  item_calories = food.get('calories', 0) * serving_multiplier
270
  item_protein = food.get('protein', 0) * serving_multiplier
271
  item_carbs = food.get('carbohydrates', 0) * serving_multiplier
272
  item_fat = food.get('fat', 0) * serving_multiplier
273
-
274
  current_nutrition['calories'] += item_calories
275
  current_nutrition['protein'] += item_protein
276
  current_nutrition['carbs'] += item_carbs
277
  current_nutrition['fat'] += item_fat
278
-
279
- selected_items.append({
280
- 'name': food_name,
281
- 'serving': round(serving_size),
282
- 'calories': item_calories,
283
- 'protein': item_protein,
284
- 'carbs': item_carbs,
285
- 'fat': item_fat
286
- })
287
 
288
- # Scale all servings to meet the calorie target
289
  if current_nutrition['calories'] > 0:
290
  scaling_factor = per_meal_calories / current_nutrition['calories']
291
-
292
- # Apply scaling to all selected items
293
  for item in selected_items:
294
  item['serving'] = round(item['serving'] * scaling_factor)
295
  item['calories'] = item['calories'] * scaling_factor
296
  item['protein'] = item['protein'] * scaling_factor
297
  item['carbs'] = item['carbs'] * scaling_factor
298
  item['fat'] = item['fat'] * scaling_factor
299
-
300
- current_nutrition = {
301
- 'calories': sum(item['calories'] for item in selected_items),
302
- 'protein': sum(item['protein'] for item in selected_items),
303
- 'carbs': sum(item['carbs'] for item in selected_items),
304
- 'fat': sum(item['fat'] for item in selected_items)
305
- }
306
 
307
- # Create the meal plan entry
308
- meal_plan.append({
309
- 'name': meal_name,
310
- 'items': selected_items,
311
- 'nutrition': {
312
- 'calories': round(current_nutrition['calories']),
313
- 'protein': round(current_nutrition['protein']),
314
- 'carbs': round(current_nutrition['carbs']),
315
- 'fat': round(current_nutrition['fat'])
316
- }
317
- })
318
-
319
  return meal_plan
320
 
321
- # Function to format the meal plan output
322
  def format_meal_plan(meal_plan, daily_targets):
323
- output = "# Your Personalized Indian Cuisine Nutrition Plan\n\n"
324
-
325
- output += "## Daily Nutritional Targets\n"
326
- output += f"- Calories: {daily_targets['calories']} kcal\n"
327
- output += f"- Protein: {daily_targets['protein']}g\n"
328
- output += f"- Carbohydrates: {daily_targets['carbs']}g\n"
329
- output += f"- Fats: {daily_targets['fat']}g\n\n"
330
-
331
- output += "## Meal Plan\n\n"
332
-
333
  total_nutrition = {'calories': 0, 'protein': 0, 'carbs': 0, 'fat': 0}
334
 
335
  for meal in meal_plan:
336
  output += f"### {meal['name']}\n"
337
  for item in meal['items']:
338
  output += f"- {item['name']} ({item['serving']}g) - {round(item['calories'])} kcal\n"
339
-
 
340
  nutrition = meal['nutrition']
341
- total_nutrition['calories'] += nutrition['calories']
342
- total_nutrition['protein'] += nutrition['protein']
343
- total_nutrition['carbs'] += nutrition['carbs']
344
- total_nutrition['fat'] += nutrition['fat']
345
-
346
- output += f"\n**Meal Nutrition:** {nutrition['calories']} kcal, {nutrition['protein']}g protein, "
347
- output += f"{nutrition['carbs']}g carbs, {nutrition['fat']}g fats\n\n"
348
-
349
- output += "## Daily Nutrition Summary\n"
350
- output += f"- Total Calories: {total_nutrition['calories']} kcal (Target: {daily_targets['calories']} kcal)\n"
351
- output += f"- Total Protein: {total_nutrition['protein']}g (Target: {daily_targets['protein']}g)\n"
352
- output += f"- Total Carbs: {total_nutrition['carbs']}g (Target: {daily_targets['carbs']}g)\n"
353
- output += f"- Total Fats: {total_nutrition['fat']}g (Target: {daily_targets['fat']}g)\n"
354
-
355
- # Add some healthy eating tips for Indian cuisine
356
- output += "\n## Healthy Indian Eating Tips\n"
357
- output += "1. **Portion Control**: Traditional Indian thalis often contain a balanced variety of foods in moderate portions\n"
358
- output += "2. **Cooking Methods**: Opt for steaming, roasting, or baking instead of deep frying\n"
359
- output += "3. **Spice Benefits**: Many Indian spices like turmeric, cumin, and coriander have health benefits\n"
360
- output += "4. **Vegetable Variety**: Include a wide variety of vegetables in your diet\n"
361
- output += "5. **Whole Grains**: Choose whole grain options like brown rice, whole wheat roti, or millet\n"
362
 
 
363
  return output
364
 
365
- # Main function to create the nutrition plan
366
- def create_nutrition_plan(weight, height, age, gender, activity_level, goal,
367
- dietary_restrictions, meals_per_day, regional_preference):
368
- # Calculate caloric needs
369
  caloric_needs = calculate_caloric_needs(weight, height, age, gender, activity_level)
370
-
371
- # Calculate macronutrient distribution
372
  macros = calculate_macros(caloric_needs, goal)
373
-
374
- # Parse dietary restrictions
375
  restrictions = dietary_restrictions.lower().split(', ') if dietary_restrictions else []
376
-
377
- # Generate meal recommendations
378
  meal_plan = recommend_meals(macros['calories'], macros, restrictions, meals_per_day, regional_preference)
379
-
380
- # Format the meal plan output
381
- formatted_plan = format_meal_plan(meal_plan, macros)
382
-
383
- return formatted_plan
 
 
 
 
 
 
 
 
384
 
385
- # Create the Gradio interface
386
- with gr.Blocks(title="Indian Cuisine Nutrition Planner") as app:
387
- gr.Markdown("# Indian Cuisine Nutrition Planner")
388
- gr.Markdown("Enter your information to get a personalized Indian meal plan")
 
 
 
 
 
389
 
390
  with gr.Row():
391
- with gr.Column():
392
- # User inputs
393
  weight = gr.Number(label="Weight (kg)", value=70)
394
  height = gr.Number(label="Height (cm)", value=170)
395
  age = gr.Number(label="Age", value=30)
396
  gender = gr.Radio(["Male", "Female"], label="Gender", value="Male")
397
- activity_level = gr.Dropdown(
398
- ["Sedentary", "Lightly Active", "Moderately Active", "Very Active", "Extra Active"],
399
- label="Activity Level",
400
- value="Moderately Active"
401
- )
402
- goal = gr.Radio(["Weight Loss", "Maintenance", "Muscle Gain"],
403
- label="Goal", value="Maintenance")
404
- dietary_restrictions = gr.Textbox(
405
- label="Dietary Restrictions (comma-separated, e.g., vegetarian)",
406
- value=""
407
- )
408
- meals_per_day = gr.Slider(2, 6, value=3, step=1, label="Meals per Day")
409
- regional_preference = gr.Dropdown(
410
- ["All", "North Indian", "South Indian", "East Indian", "West Indian"],
411
- label="Regional Preference",
412
- value="All"
413
- )
414
-
415
- submit_btn = gr.Button("Generate Indian Nutrition Plan")
416
 
417
- with gr.Column():
418
- # Output area
419
- output = gr.Markdown()
 
 
 
 
 
 
 
 
 
 
 
 
420
 
421
- # Connect the function to the button
422
- submit_btn.click(
423
- fn=create_nutrition_plan,
424
- inputs=[weight, height, age, gender, activity_level, goal, dietary_restrictions,
425
- meals_per_day, regional_preference],
426
- outputs=output
427
- )
 
 
 
428
 
429
- # Launch the app
430
  app.launch(debug=True)
 
4
  from sklearn.metrics.pairwise import cosine_similarity
5
  from datasets import load_dataset
6
  import warnings
7
+ import matplotlib.pyplot as plt
8
  warnings.filterwarnings('ignore')
9
 
10
+ # Load the Indian food dataset or use fallback data
 
 
11
  try:
12
  ds = load_dataset("Anupam007/nutarian-Indianfood")
 
13
  food_df = pd.DataFrame(ds['train'])
14
+ print(f"Successfully loaded dataset with {len(food_df)} items")
15
 
16
+ # Clean and prepare dataset
 
 
 
 
 
17
  required_columns = ['name', 'calories', 'protein', 'carbohydrates', 'fat']
18
+ column_mapping = {'Name': 'name', 'Calories': 'calories', 'Protein': 'protein',
19
+ 'Carbs': 'carbohydrates', 'Fats': 'fat', 'Category': 'food_group'}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  for old_col, new_col in column_mapping.items():
21
  if old_col in food_df.columns:
22
  food_df = food_df.rename(columns={old_col: new_col})
 
 
23
  if 'serving_size' not in food_df.columns:
24
+ food_df['serving_size'] = 100
 
 
25
  numeric_cols = ['calories', 'protein', 'carbohydrates', 'fat', 'serving_size']
26
  for col in numeric_cols:
27
  if col in food_df.columns:
28
  food_df[col] = pd.to_numeric(food_df[col], errors='coerce')
 
 
29
  food_df = food_df.dropna(subset=['name', 'calories'])
 
 
 
30
  except Exception as e:
31
+ print(f"Error loading dataset: {e}, using fallback data...")
 
 
 
32
  food_data = {
33
+ 'name': ['Aloo Gobi', 'Butter Chicken', 'Chana Masala', 'Dal Makhani', 'Palak Paneer',
34
+ 'Roti', 'Naan', 'Basmati Rice', 'Idli', 'Dosa', 'Sambar', 'Raita', 'Biryani',
35
+ 'Tandoori Chicken', 'Vada', 'Uttapam', 'Upma', 'Poha', 'Pav Bhaji', 'Chole Bhature'],
36
+ 'calories': [150, 325, 180, 230, 190, 120, 260, 150, 58, 133, 152, 75, 292, 165, 97,
37
+ 188, 185, 270, 210, 427],
38
+ 'protein': [3.5, 28, 7.5, 9, 11, 3, 9, 3.5, 2, 3.7, 3.8, 3.5, 9.5, 31, 2.2,
39
+ 5.3, 3.5, 5.2, 6, 13.2],
40
+ 'carbohydrates': [15, 10, 30, 31, 6, 18, 33, 32, 12, 25.2, 28, 3.5, 46, 0, 16.3,
41
+ 28.5, 31, 44, 22.7, 57.2],
42
+ 'fat': [8, 17, 6, 9, 12.5, 3.7, 11, 0.5, 0.2, 3.8, 5.6, 5, 9, 3.6, 3.9,
43
+ 7.2, 7, 12, 12, 20],
44
+ 'serving_size': [100, 100, 100, 100, 100, 30, 80, 100, 40, 100, 100, 100, 100, 100, 35,
45
+ 100, 100, 100, 100, 120],
46
+ 'food_group': ['Vegetable', 'Protein', 'Protein', 'Protein', 'Protein', 'Grain', 'Grain',
47
+ 'Grain', 'Grain', 'Grain', 'Vegetable', 'Dairy', 'Mixed', 'Protein', 'Snack',
48
+ 'Grain', 'Grain', 'Grain', 'Mixed', 'Mixed']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
 
 
50
  food_df = pd.DataFrame(food_data)
 
51
 
52
+ # Sample recipe database (could be expanded)
53
+ recipes = {
54
+ 'Aloo Gobi': "Ingredients: Potatoes, Cauliflower, Spices\nInstructions: Sauté spices, add veggies, cook until tender.",
55
+ 'Butter Chicken': "Ingredients: Chicken, Butter, Cream, Spices\nInstructions: Marinate chicken, cook with sauce.",
56
+ 'Idli': "Ingredients: Rice, Urad Dal\nInstructions: Ferment batter, steam in molds."
57
+ }
58
+
59
+ # Calculate caloric needs (Harris-Benedict Equation)
60
  def calculate_caloric_needs(weight, height, age, gender, activity_level):
61
+ if not all(isinstance(x, (int, float)) and x > 0 for x in [weight, height, age]):
62
+ raise gr.Error("Weight, height, and age must be positive numbers")
63
  if gender.lower() == 'male':
64
  bmr = 88.362 + (13.397 * weight) + (4.799 * height) - (5.677 * age)
65
  else:
66
  bmr = 447.593 + (9.247 * weight) + (3.098 * height) - (4.330 * age)
67
+ activity_multipliers = {'sedentary': 1.2, 'lightly active': 1.375, 'moderately active': 1.55,
68
+ 'very active': 1.725, 'extra active': 1.9}
 
 
 
 
 
 
 
69
  return round(bmr * activity_multipliers[activity_level.lower()])
70
 
71
+ # Calculate macronutrients
72
  def calculate_macros(caloric_needs, goal):
73
  macros = {}
 
74
  if goal.lower() == 'weight loss':
75
+ caloric_needs = caloric_needs * 0.85
76
+ macros['protein'] = (caloric_needs * 0.30) / 4
77
+ macros['fat'] = (caloric_needs * 0.30) / 9
78
+ macros['carbs'] = (caloric_needs * 0.40) / 4
 
79
  elif goal.lower() == 'maintenance':
80
+ macros['protein'] = (caloric_needs * 0.25) / 4
81
+ macros['fat'] = (caloric_needs * 0.30) / 9
82
+ macros['carbs'] = (caloric_needs * 0.45) / 4
 
83
  elif goal.lower() == 'muscle gain':
84
+ caloric_needs = caloric_needs * 1.10
85
+ macros['protein'] = (caloric_needs * 0.30) / 4
86
+ macros['fat'] = (caloric_needs * 0.25) / 9
87
+ macros['carbs'] = (caloric_needs * 0.45) / 4
88
+ return {'calories': round(caloric_needs), 'protein': round(macros['protein']),
89
+ 'carbs': round(macros['carbs']), 'fat': round(macros['fat'])}
 
 
 
 
 
90
 
91
+ # Recommend meals
92
  def recommend_meals(caloric_needs, macros, restrictions, meals_per_day, meal_preferences):
 
 
 
 
93
  filtered_foods = food_df.copy()
 
94
  if 'vegetarian' in restrictions:
95
+ filtered_foods = filtered_foods[~filtered_foods['food_group'].str.contains('Non-veg|Meat', case=False, na=False)]
 
 
 
96
  if 'vegan' in restrictions:
97
+ filtered_foods = filtered_foods[~filtered_foods['food_group'].str.contains('Non-veg|Meat|Dairy', case=False, na=False)]
 
 
 
 
 
 
 
 
 
 
 
 
98
  if len(filtered_foods) < 10:
99
  filtered_foods = food_df.copy()
 
 
 
 
 
 
 
 
 
100
 
101
+ meal_types = {"Breakfast": ["Idli", "Dosa", "Poha", "Upma"], "Lunch": ["Rice", "Dal", "Roti", "Biryani"],
102
+ "Dinner": ["Roti", "Sabzi", "Dal"], "Snack": ["Vada", "Samosa"]}
103
  per_meal_calories = caloric_needs / meals_per_day
 
 
 
 
 
104
  meal_plan = []
105
+ daily_meal_names = ["Breakfast", "Lunch", "Evening Snack", "Dinner"][:meals_per_day]
 
 
106
  if meals_per_day > len(daily_meal_names):
107
+ daily_meal_names.extend([f"Meal {i+1}" for i in range(len(daily_meal_names), meals_per_day)])
 
 
 
 
108
 
109
+ for meal_name in daily_meal_names:
110
+ meal_category = next((k for k, v in meal_types.items() if meal_name in k), "Lunch")
111
+ potential_items = filtered_foods[filtered_foods['name'].str.contains('|'.join(meal_types.get(meal_category, [])),
112
+ case=False, na=False)] if meal_types.get(meal_category) else filtered_foods
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  if len(potential_items) < 5:
114
  potential_items = filtered_foods
 
 
115
  num_items = np.random.randint(2, 5)
116
+ selected_food_items = potential_items.sample(min(num_items, len(potential_items)))
 
 
 
117
 
118
+ selected_items = []
119
+ current_nutrition = {'calories': 0, 'protein': 0, 'carbs': 0, 'fat': 0}
120
  for _, food in selected_food_items.iterrows():
 
 
 
 
 
 
121
  serving_multiplier = 1.0
122
+ food_name = food.get('name', "Unknown")
 
 
123
  serving_size = food.get('serving_size', 100) * serving_multiplier
 
 
124
  item_calories = food.get('calories', 0) * serving_multiplier
125
  item_protein = food.get('protein', 0) * serving_multiplier
126
  item_carbs = food.get('carbohydrates', 0) * serving_multiplier
127
  item_fat = food.get('fat', 0) * serving_multiplier
 
128
  current_nutrition['calories'] += item_calories
129
  current_nutrition['protein'] += item_protein
130
  current_nutrition['carbs'] += item_carbs
131
  current_nutrition['fat'] += item_fat
132
+ selected_items.append({'name': food_name, 'serving': round(serving_size), 'calories': item_calories,
133
+ 'protein': item_protein, 'carbs': item_carbs, 'fat': item_fat})
 
 
 
 
 
 
 
134
 
 
135
  if current_nutrition['calories'] > 0:
136
  scaling_factor = per_meal_calories / current_nutrition['calories']
 
 
137
  for item in selected_items:
138
  item['serving'] = round(item['serving'] * scaling_factor)
139
  item['calories'] = item['calories'] * scaling_factor
140
  item['protein'] = item['protein'] * scaling_factor
141
  item['carbs'] = item['carbs'] * scaling_factor
142
  item['fat'] = item['fat'] * scaling_factor
143
+ current_nutrition = {k: sum(item[k] for item in selected_items) for k in ['calories', 'protein', 'carbs', 'fat']}
 
 
 
 
 
 
144
 
145
+ meal_plan.append({'name': meal_name, 'items': selected_items,
146
+ 'nutrition': {k: round(v) for k, v in current_nutrition.items()}})
 
 
 
 
 
 
 
 
 
 
147
  return meal_plan
148
 
149
+ # Format meal plan with recipes
150
  def format_meal_plan(meal_plan, daily_targets):
151
+ output = "# Your Personalized Indian Meal Plan\n\n"
152
+ output += f"## Daily Targets: {daily_targets['calories']} kcal, {daily_targets['protein']}g protein, {daily_targets['carbs']}g carbs, {daily_targets['fat']}g fat\n\n"
 
 
 
 
 
 
 
 
153
  total_nutrition = {'calories': 0, 'protein': 0, 'carbs': 0, 'fat': 0}
154
 
155
  for meal in meal_plan:
156
  output += f"### {meal['name']}\n"
157
  for item in meal['items']:
158
  output += f"- {item['name']} ({item['serving']}g) - {round(item['calories'])} kcal\n"
159
+ if item['name'] in recipes:
160
+ output += f" *Recipe*: {recipes[item['name']]}\n"
161
  nutrition = meal['nutrition']
162
+ total_nutrition = {k: total_nutrition[k] + v for k, v in nutrition.items()}
163
+ output += f"\n**Nutrition:** {nutrition['calories']} kcal, {nutrition['protein']}g protein, {nutrition['carbs']}g carbs, {nutrition['fat']}g fat\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ output += f"## Summary: {total_nutrition['calories']} kcal, {total_nutrition['protein']}g protein, {total_nutrition['carbs']}g carbs, {total_nutrition['fat']}g fat\n"
166
  return output
167
 
168
+ # Main function
169
+ def create_nutrition_plan(weight, height, age, gender, activity_level, goal, dietary_restrictions, meals_per_day, regional_preference):
 
 
170
  caloric_needs = calculate_caloric_needs(weight, height, age, gender, activity_level)
 
 
171
  macros = calculate_macros(caloric_needs, goal)
 
 
172
  restrictions = dietary_restrictions.lower().split(', ') if dietary_restrictions else []
 
 
173
  meal_plan = recommend_meals(macros['calories'], macros, restrictions, meals_per_day, regional_preference)
174
+ return format_meal_plan(meal_plan, macros)
175
+
176
+ # Progress tracking (simple example)
177
+ progress_data = {'dates': [], 'calories': []}
178
+ def track_progress(calories_consumed):
179
+ progress_data['dates'].append(pd.Timestamp.now().strftime('%Y-%m-%d'))
180
+ progress_data['calories'].append(float(calories_consumed))
181
+ fig, ax = plt.subplots()
182
+ ax.plot(progress_data['dates'], progress_data['calories'], marker='o')
183
+ ax.set_xlabel("Date")
184
+ ax.set_ylabel("Calories Consumed")
185
+ plt.xticks(rotation=45)
186
+ return fig
187
 
188
+ # Social sharing
189
+ def share_plan(plan):
190
+ return f"Check out my Indian Meal Plan!\n\n{plan}"
191
+
192
+ # Gradio Interface
193
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="green"),
194
+ css=".gr-button {border-radius: 10px;} .header {color: #FF5733; font-size: 2em;}") as app:
195
+ gr.Markdown("# Indian Cuisine Nutrition Planner", elem_classes="header")
196
+ gr.Markdown("Plan your meals with authentic Indian flavors!")
197
 
198
  with gr.Row():
199
+ with gr.Column(scale=1, min_width=300):
 
200
  weight = gr.Number(label="Weight (kg)", value=70)
201
  height = gr.Number(label="Height (cm)", value=170)
202
  age = gr.Number(label="Age", value=30)
203
  gender = gr.Radio(["Male", "Female"], label="Gender", value="Male")
204
+ activity_level = gr.Dropdown(["Sedentary", "Lightly Active", "Moderately Active",
205
+ "Very Active", "Extra Active"], label="Activity Level",
206
+ value="Moderately Active")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
+ with gr.Column(scale=1, min_width=300):
209
+ goal = gr.Radio(["Weight Loss", "Maintenance", "Muscle Gain"], label="Goal", value="Maintenance")
210
+ dietary_restrictions = gr.Textbox(label="Dietary Restrictions (e.g., vegetarian)", value="")
211
+ meals_per_day = gr.Slider(2, 6, value=3, step=1, label="Meals per Day")
212
+ regional_preference = gr.Dropdown(["All", "North Indian", "South Indian", "East Indian",
213
+ "West Indian"], label="Regional Preference", value="All")
214
+ submit_btn = gr.Button("Generate Plan", variant="primary")
215
+
216
+ with gr.Row():
217
+ output = gr.Markdown(label="Your Meal Plan")
218
+
219
+ with gr.Tab("Track Progress"):
220
+ calories_input = gr.Number(label="Log Today's Calories")
221
+ track_btn = gr.Button("Add to Progress")
222
+ progress_plot = gr.Plot(label="Calorie Progress")
223
 
224
+ with gr.Tab("Share"):
225
+ share_btn = gr.Button("Generate Shareable Plan")
226
+ share_output = gr.Textbox(label="Share this with friends!")
227
+
228
+ submit_btn.click(fn=create_nutrition_plan,
229
+ inputs=[weight, height, age, gender, activity_level, goal, dietary_restrictions,
230
+ meals_per_day, regional_preference],
231
+ outputs=output)
232
+ track_btn.click(fn=track_progress, inputs=calories_input, outputs=progress_plot)
233
+ share_btn.click(fn=share_plan, inputs=output, outputs=share_output)
234
 
 
235
  app.launch(debug=True)