Initial commit with app and dependencies
Browse files- app.py +135 -0
- requirements.txt +4 -0
app.py
ADDED
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import streamlit as st
|
3 |
+
from transformers import T5ForConditionalGeneration, T5Tokenizer
|
4 |
+
from sentence_transformers import SentenceTransformer, util
|
5 |
+
import torch
|
6 |
+
|
7 |
+
# Prevent parallelism warnings
|
8 |
+
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
9 |
+
|
10 |
+
# Load the models and tokenizer using Streamlit's updated caching method
|
11 |
+
@st.cache_resource
|
12 |
+
def load_models():
|
13 |
+
generation_model = T5ForConditionalGeneration.from_pretrained('t5-small')
|
14 |
+
generation_tokenizer = T5Tokenizer.from_pretrained('t5-small')
|
15 |
+
sentence_model = SentenceTransformer('all-MiniLM-L6-v2')
|
16 |
+
return generation_model, generation_tokenizer, sentence_model
|
17 |
+
|
18 |
+
generation_model, generation_tokenizer, sentence_model = load_models()
|
19 |
+
|
20 |
+
# Predefined meals with calorie information
|
21 |
+
# Updated predefined meals with higher calorie options
|
22 |
+
meals = {
|
23 |
+
"Breakfast": [
|
24 |
+
{"meal": "Oatmeal with fruits", "calories": 250},
|
25 |
+
{"meal": "Scrambled eggs with toast", "calories": 350},
|
26 |
+
{"meal": "Protein Smoothie", "calories": 300},
|
27 |
+
{"meal": "Avocado toast with poached egg", "calories": 320},
|
28 |
+
{"meal": "Greek yogurt with granola and berries", "calories": 280},
|
29 |
+
{"meal": "Pancakes with honey", "calories": 400},
|
30 |
+
{"meal": "Veggie omelette", "calories": 300},
|
31 |
+
{"meal": "Cereal with milk", "calories": 400}
|
32 |
+
],
|
33 |
+
"Lunch": [
|
34 |
+
{"meal": "Grilled chicken salad", "calories": 400},
|
35 |
+
{"meal": "Vegetable stir-fry with tofu", "calories": 350},
|
36 |
+
{"meal": "Chicken wrap", "calories": 500},
|
37 |
+
{"meal": "Turkey sandwich on whole grain bread", "calories": 450},
|
38 |
+
{"meal": "Quinoa salad with mixed greens", "calories": 375},
|
39 |
+
{"meal": "Fish tacos", "calories": 480},
|
40 |
+
{"meal": "Lentil soup with a side salad", "calories": 420},
|
41 |
+
{"meal": "Pasta Alfredo with garlic bread", "calories": 1100}, # High-calorie option
|
42 |
+
{"meal": "Buffalo wings with ranch dressing", "calories": 950} # High-calorie option
|
43 |
+
],
|
44 |
+
"Dinner": [
|
45 |
+
{"meal": "Salmon with steamed vegetables", "calories": 600},
|
46 |
+
{"meal": "Pasta with tomato sauce", "calories": 500},
|
47 |
+
{"meal": "Vegetarian chili", "calories": 450},
|
48 |
+
{"meal": "Beef stir-fry with bell peppers", "calories": 550},
|
49 |
+
{"meal": "Chicken curry with brown rice", "calories": 650},
|
50 |
+
{"meal": "Grilled shrimp with quinoa", "calories": 580},
|
51 |
+
{"meal": "Stuffed bell peppers with ground turkey", "calories": 525},
|
52 |
+
{"meal": "Ribeye steak with mashed potatoes", "calories": 1300}, # High-calorie option
|
53 |
+
{"meal": "BBQ pork ribs with cornbread", "calories": 1400}, # High-calorie option
|
54 |
+
{"meal": "Seafood platter with garlic butter", "calories": 1250} # High-calorie option
|
55 |
+
],
|
56 |
+
"Snacks": [
|
57 |
+
{"meal": "Apple with peanut butter", "calories": 200},
|
58 |
+
{"meal": "Greek yogurt with honey", "calories": 150},
|
59 |
+
{"meal": "Granola bar", "calories": 250},
|
60 |
+
{"meal": "Handful of almonds", "calories": 180},
|
61 |
+
{"meal": "Hummus with carrot sticks", "calories": 100},
|
62 |
+
{"meal": "Cheese and crackers", "calories": 200},
|
63 |
+
{"meal": "Protein shake", "calories": 220}
|
64 |
+
]
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
# Function to suggest meals based on the target calorie goal
|
69 |
+
def suggest_meals(target_calories):
|
70 |
+
suggestions = {}
|
71 |
+
total_calories = 0
|
72 |
+
remaining_calories = target_calories
|
73 |
+
|
74 |
+
# Prioritize essential meals
|
75 |
+
essential_meal_categories = ["Breakfast", "Lunch", "Dinner"]
|
76 |
+
snack_category = "Snacks"
|
77 |
+
|
78 |
+
for category in essential_meal_categories:
|
79 |
+
# Sort meals by calories in descending order to prioritize higher calorie meals
|
80 |
+
available_meals = sorted(meals[category], key=lambda x: -x["calories"])
|
81 |
+
selected_meal = None
|
82 |
+
|
83 |
+
for meal in available_meals:
|
84 |
+
if meal["calories"] <= remaining_calories:
|
85 |
+
selected_meal = meal
|
86 |
+
break
|
87 |
+
|
88 |
+
if selected_meal:
|
89 |
+
suggestions[category] = f"{selected_meal['meal']} containing {selected_meal['calories']} calories"
|
90 |
+
total_calories += selected_meal["calories"]
|
91 |
+
remaining_calories -= selected_meal["calories"]
|
92 |
+
|
93 |
+
# Add multiple snacks to use up the remaining calories efficiently
|
94 |
+
available_snacks = sorted(meals[snack_category], key=lambda x: -x["calories"])
|
95 |
+
snack_descriptions = []
|
96 |
+
|
97 |
+
for snack in available_snacks:
|
98 |
+
if snack["calories"] <= remaining_calories:
|
99 |
+
snack_descriptions.append(f"{snack['meal']} containing {snack['calories']} calories")
|
100 |
+
total_calories += snack["calories"]
|
101 |
+
remaining_calories -= snack["calories"]
|
102 |
+
|
103 |
+
if remaining_calories < 100: # Stop adding snacks if the remaining calories are too low
|
104 |
+
break
|
105 |
+
|
106 |
+
return suggestions, snack_descriptions, total_calories
|
107 |
+
|
108 |
+
# Streamlit interface
|
109 |
+
st.title("Calorie-Based Meal Plan Bot")
|
110 |
+
st.write("Enter your daily calorie goal, and I will suggest a balanced meal plan for the day. Minimum calorie goal is 800 kcal for a sustainable diet.")
|
111 |
+
|
112 |
+
# Ensure the user inputs a calorie target without a default value
|
113 |
+
target_calories = st.number_input("Enter your daily calorie target (in kcal):", min_value=800, max_value=4500, value=None)
|
114 |
+
|
115 |
+
if target_calories:
|
116 |
+
suggested_meals, snack_descriptions, total_calories = suggest_meals(target_calories)
|
117 |
+
|
118 |
+
st.subheader("Suggested Meals:")
|
119 |
+
for category, meal_description in suggested_meals.items():
|
120 |
+
st.write(f"{category}: {meal_description}")
|
121 |
+
|
122 |
+
|
123 |
+
if(len(snack_descriptions) == 0):
|
124 |
+
st.write("Snacks: Sorry. No snacks for you π")
|
125 |
+
else:
|
126 |
+
st.write("Snacks:")
|
127 |
+
for snack in snack_descriptions:
|
128 |
+
st.write(f"- {snack}")
|
129 |
+
|
130 |
+
st.write(f"Total Calories: {total_calories} calories")
|
131 |
+
|
132 |
+
if total_calories < target_calories:
|
133 |
+
st.write("You can add more snacks or meals to meet your target!")
|
134 |
+
elif total_calories > target_calories:
|
135 |
+
st.write("Consider reducing meal portions to stay within your target!")
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
transformers
|
3 |
+
torch
|
4 |
+
sentence-transformers
|