DynamicMenu / app.py
dschandra's picture
Update app.py
b81ebfc verified
raw
history blame
5.14 kB
import gradio as gr
import pandas as pd
# Load menu data from Excel file
def load_menu(file_path="menu.xlsx"):
"""
Load menu data from an Excel file and dynamically map its columns to required fields.
"""
menu_df = pd.read_excel(file_path)
# Normalize column names (strip spaces and make lowercase)
menu_df.columns = menu_df.columns.str.strip().str.lower()
# Map dynamic column names to required fields
column_mapping = {
"name": next((col for col in menu_df.columns if "name" in col), None),
"price": next((col for col in menu_df.columns if "price" in col), None),
"description": next((col for col in menu_df.columns if "description" in col), None),
"image": next((col for col in menu_df.columns if "image" in col), None),
}
# Ensure all required columns are present
missing_columns = [key for key, col in column_mapping.items() if col is None]
if missing_columns:
raise ValueError(f"Excel file is missing one or more required columns: {missing_columns}")
# Map data to required structure
menu = []
for _, row in menu_df.iterrows():
menu.append({
"name": row[column_mapping["name"]],
"price": row[column_mapping["price"]],
"description": row[column_mapping["description"]],
"image": row[column_mapping["image"]],
})
return menu
# Initialize menu and cart
menu_data = load_menu("menu.xlsx")
cart = []
def display_menu():
"""
Render the menu dynamically as HTML.
"""
menu_html = ""
for item in menu_data:
menu_html += f"""
<div style="display: flex; margin-bottom: 15px; align-items: center; border: 1px solid #ddd; padding: 10px; border-radius: 5px;">
<img src="{item['image']}" alt="{item['name']}" style="width: 100px; height: 100px; margin-right: 15px; border-radius: 5px;">
<div style="flex-grow: 1;">
<h4 style="margin: 0;">{item['name']} - ${item['price']}</h4>
<p style="margin: 5px 0; font-size: 12px;">{item['description']}</p>
<label for="quantity-{item['name']}" style="margin-right: 10px;">Quantity:</label>
<input type="number" id="quantity-{item['name']}" value="1" min="1" style="width: 50px;">
</div>
<button onclick="add_to_cart('{item['name']}', document.getElementById('quantity-{item['name']}').value)" style="background-color: #28a745; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer;">Add</button>
</div>
"""
return menu_html
def add_to_cart(item_name, quantity):
"""
Add an item to the cart and return success message with cart count.
"""
quantity = int(quantity)
# Check if the item already exists in the cart
for item in cart:
if item["name"] == item_name:
item["quantity"] += quantity
break
else:
# Add new item to cart
for item in menu_data:
if item["name"] == item_name:
cart.append({"name": item_name, "price": item["price"], "quantity": quantity})
break
return f"{item_name} added to cart! Total items: {len(cart)}"
def view_cart():
"""
Render the cart contents and calculate the total price.
"""
if not cart:
return "Your cart is empty."
cart_html = "<h3>Cart Summary:</h3><ul>"
total_price = 0
for item in cart:
cart_html += f"<li>{item['name']} (x{item['quantity']}) - ${item['price'] * item['quantity']}</li>"
total_price += item["price"] * item["quantity"]
cart_html += f"</ul><h4>Total Price: ${total_price}</h4>"
return cart_html
# Gradio Interface
def menu_page():
return gr.update(value=display_menu(), visible=True), gr.update(visible=False)
def cart_page():
return gr.update(value=view_cart(), visible=True), gr.update(visible=False)
with gr.Blocks() as demo:
gr.Markdown("# Dynamic Food Menu")
# Menu and Cart Views
menu_display = gr.HTML(value=display_menu(), visible=True)
cart_display = gr.HTML(visible=False)
notification = gr.Textbox(label="Notification", value="", interactive=False)
# Navigation Buttons
with gr.Row():
menu_button = gr.Button("Menu")
cart_button = gr.Button("View Cart")
# Add item interaction
food_item_input = gr.Textbox(visible=False) # Hidden input to capture item name
quantity_input = gr.Number(visible=False) # Hidden input to capture quantity
add_button = gr.Button("Add to Cart", visible=False) # Simulated button for functionality
# Notification when item is added
add_button.click(add_to_cart, inputs=[food_item_input, quantity_input], outputs=notification)
# Navigation between Menu and Cart pages
menu_button.click(menu_page, outputs=[menu_display, cart_display])
cart_button.click(cart_page, outputs=[cart_display, menu_display])
# Render menu and cart
demo.append(menu_display)
demo.append(cart_display)
demo.append(notification)
demo.launch()