SmartMenu / app.py
SanaAdeel's picture
Update app.py
3458fe4 verified
import os
import random
import pandas as pd
import streamlit as st
from groq import Groq
import gdown
# Function to download the file from Google Drive
def download_file_from_gdrive(url, output):
import gdown
gdown.download(url, output, quiet=False)
# Load the menu data from the downloaded file
def load_data(file_path):
return pd.read_excel(file_path)
# Get user inputs for menu generation
def get_user_inputs():
# Get user input via Streamlit widgets
user_type = st.selectbox("Is this menu for Adult or Infant?", ["Adult", "Infant"])
if user_type == "Adult":
season = st.selectbox("Select the season", ["Summer", "Winter"])
outings = st.slider("Enter the number of outings for the week:", 0, 7, 0)
budget = st.number_input("Enter your weekly budget (in Rs):", min_value=0, step=100)
sub_category_prefs = {}
categories = ["Sabzi", "Rice", "Daal", "Meat", "Chicken", "Fish"]
for category in categories:
count = st.number_input(f"Enter the number of {category} dishes:", min_value=0)
sub_category_prefs[category] = count
return user_type, season, outings, budget, sub_category_prefs
elif user_type == "Infant":
return user_type, None, None, None, None
# Fetch recipe from Groq API for a given dish name
def get_recipe(dish_name):
client = Groq(api_key="your-api-key-here") # Replace with your actual API key
try:
chat_completion = client.chat.completions.create(
messages=[{
"role": "user",
"content": f"Provide a detailed recipe for {dish_name}.",
}],
model="llama-3.3-70b-versatile",
)
return chat_completion.choices[0].message.content
except Exception as e:
return f"Error fetching recipe: {e}"
# Generate menu based on user inputs
def generate_menu(data, user_type, season=None, outings=None, budget=None, sub_category_prefs=None):
if user_type == "Adult":
# Filter data by season
filtered_data = data[data['Season'].isin([season, 'All Seasons'])]
main_courses = filtered_data[filtered_data['Course'] == 'Main Course']
side_dishes = filtered_data[filtered_data['Course'] == 'Side Dish']
# Initialize menu
homemade_dishes_count = 14 - outings
weekly_menu = []
# Add dishes from each sub-category based on user preferences
for category, count in sub_category_prefs.items():
category_dishes = main_courses[main_courses['Sub-Category'] == category]
available_count = len(category_dishes)
while count > available_count:
st.warning(f"You requested {count} {category} dishes, but only {available_count} are available.")
count = st.number_input(f"Please revise your selection for {category} dishes (Maximum: {available_count}):", min_value=0, max_value=available_count)
sub_category_prefs[category] = count
selected_dishes = category_dishes.sample(n=count).to_dict('records')
weekly_menu.extend(selected_dishes)
# Fill remaining dishes if fewer than 14 are selected
remaining_count = homemade_dishes_count - len(weekly_menu)
if remaining_count > 0:
additional_dishes = main_courses.sample(n=min(remaining_count, len(main_courses))).to_dict('records')
weekly_menu.extend(additional_dishes)
# Randomly select outings
available_outings = len(main_courses)
if outings > available_outings:
st.warning(f"You requested {outings} outings, but only {available_outings} are available.")
outings = st.number_input(f"Please revise your selection for outings (Maximum: {available_outings}):", min_value=0, max_value=available_outings)
outing_dishes = main_courses.sample(n=min(outings, len(main_courses))).to_dict('records')
# Combine homemade and outing dishes
weekly_menu = random.sample(weekly_menu, k=homemade_dishes_count) + outing_dishes
# Add 2 side dishes
selected_side_dishes = side_dishes.sample(n=min(len(side_dishes), 2)).to_dict('records')
# Ensure budget constraint
total_expenditure = sum(dish['Cost per 4 persons'] for dish in weekly_menu + selected_side_dishes)
if total_expenditure > budget:
st.warning(f"Your budget of Rs. {budget} is too low for the selected preferences.")
return None, None, None, None
# Split menu into lunch and dinner
lunch_menu = weekly_menu[:7]
dinner_menu = weekly_menu[7:14]
# Assign days of the week
days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
lunch_menu = {days_of_week[i]: dish['Name'] for i, dish in enumerate(lunch_menu)}
dinner_menu = {days_of_week[i]: dish['Name'] for i, dish in enumerate(dinner_menu)}
return lunch_menu, dinner_menu, selected_side_dishes, total_expenditure
elif user_type == "Infant":
baby_dishes_data = data[data['Course'] == 'Baby Dish']
baby_dishes = baby_dishes_data['Name'].tolist()
if len(baby_dishes) >= 14:
infant_menu = random.sample(baby_dishes, k=14)
else:
infant_menu = random.choices(baby_dishes, k=14)
# Calculate total expenditure for the infant menu
baby_dishes_cost = {row['Name']: row['Cost per 4 persons'] for _, row in baby_dishes_data.iterrows()}
total_expenditure = sum(baby_dishes_cost[dish] for dish in infant_menu)
return {"Weekly Menu": infant_menu}, total_expenditure
# Save the generated menu to an Excel file
def save_menu_to_excel(lunch_menu=None, dinner_menu=None, side_dishes=None, infant_menu=None):
with pd.ExcelWriter("Weekly_Menu.xlsx") as writer:
if infant_menu:
infant_df = pd.DataFrame(infant_menu["Weekly Menu"], columns=['Dish'])
infant_df.to_excel(writer, sheet_name='Infant Menu', index=False)
else:
lunch_df = pd.DataFrame(list(lunch_menu.items()), columns=['Day', 'Lunch'])
lunch_df.to_excel(writer, sheet_name='Lunch Menu', index=False)
dinner_df = pd.DataFrame(list(dinner_menu.items()), columns=['Day', 'Dinner'])
dinner_df.to_excel(writer, sheet_name='Dinner Menu', index=False)
side_dishes_df = pd.DataFrame(side_dishes)
side_dishes_df = side_dishes_df[['Name']]
side_dishes_df.to_excel(writer, sheet_name='Side Dishes', index=False)
# Main function to run the app
def main():
# File URL and output path
file_url = "https://drive.google.com/uc?id=1BJFao3C6p8k3_KjLfmDo5KbNMrTs7MRo"
output_file = "menu_data.xlsx"
# Download the file
download_file_from_gdrive(file_url, output_file)
# Load data
data = load_data(output_file)
st.title("Weekly Menu Generator")
# Option selection
choice = st.selectbox("What would you like to do?", ["Generate a Weekly Menu", "Get a Recipe for a Dish", "Exit"])
if choice == "Generate a Weekly Menu":
# Get user inputs
user_type, season, outings, budget, sub_category_prefs = get_user_inputs()
# Generate menu
if user_type == "Adult":
lunch_menu, dinner_menu, side_dishes, total_expenditure = generate_menu(
data, user_type, season, outings, budget, sub_category_prefs
)
if lunch_menu is None:
st.warning("Unable to generate a menu within the given budget and preferences. Please try again.")
return
# Display results
st.subheader("Lunch Menu")
for day, dish in lunch_menu.items():
st.write(f"{day}: {dish}")
st.subheader("Dinner Menu")
for day, dish in dinner_menu.items():
st.write(f"{day}: {dish}")
st.subheader("Side Dishes")
for dish in side_dishes:
st.write(f"- {dish['Name']}")
st.write(f"Total Weekly Expenditure: Rs. {total_expenditure}")
# Save menu to Excel
save_menu_to_excel(lunch_menu, dinner_menu, side_dishes)
elif user_type == "Infant":
infant_menu, total_expenditure = generate_menu(data, user_type)
# Display results
st.subheader("Infant Weekly Menu")
for dish in infant_menu["Weekly Menu"]:
st.write(f"- {dish}")
st.write(f"Total Weekly Expenditure: Rs. {total_expenditure}")
# Save menu to Excel
save_menu_to_excel(infant_menu=infant_menu)
elif choice == "Get a Recipe for a Dish":
dish_name = st.text_input("Enter the name of a dish you want the recipe for:")
if dish_name:
recipe = get_recipe(dish_name)
st.subheader(f"Recipe for {dish_name}")
st.write(recipe)
elif choice == "Exit":
st.write("Thank you for using the Weekly Menu Generator!")
if __name__ == "__main__":
main()