Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -2,40 +2,18 @@ import gradio as gr
|
|
| 2 |
import time
|
| 3 |
import csv
|
| 4 |
from datetime import datetime
|
|
|
|
|
|
|
| 5 |
|
| 6 |
# ====== 菜单数据结构(英文 + 编号) ======
|
| 7 |
MENU_DATA = {
|
| 8 |
-
"Appetizers": [
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
{"id": "A4", "name": "Tofu Skewers", "desc": "Grilled tofu with sauce", "price": 4.0, "img": "https://via.placeholder.com/100"},
|
| 13 |
-
{"id": "A5", "name": "Edamame", "desc": "Boiled soybeans with salt", "price": 3.0, "img": "https://via.placeholder.com/100"},
|
| 14 |
-
],
|
| 15 |
-
"Main Dishes": [
|
| 16 |
-
{"id": "B1", "name": "Beef Pho", "desc": "Traditional Vietnamese noodle soup", "price": 9.5, "img": "https://via.placeholder.com/100"},
|
| 17 |
-
{"id": "B2", "name": "Chicken Curry", "desc": "Spicy chicken curry with rice", "price": 10.0, "img": "https://via.placeholder.com/100"},
|
| 18 |
-
{"id": "B3", "name": "Fried Rice", "desc": "Fried rice with egg and vegetables", "price": 8.0, "img": "https://via.placeholder.com/100"},
|
| 19 |
-
{"id": "B4", "name": "Grilled Fish", "desc": "Grilled fish with herbs", "price": 11.0, "img": "https://via.placeholder.com/100"},
|
| 20 |
-
{"id": "B5", "name": "Veggie Stir Fry", "desc": "Mixed vegetables stir-fried with sauce", "price": 8.5, "img": "https://via.placeholder.com/100"},
|
| 21 |
-
],
|
| 22 |
-
"Desserts": [
|
| 23 |
-
{"id": "C1", "name": "Mango Sticky Rice", "desc": "Sweet coconut rice with mango", "price": 5.0, "img": "https://via.placeholder.com/100"},
|
| 24 |
-
{"id": "C2", "name": "Taro Cake", "desc": "Steamed taro cake", "price": 4.5, "img": "https://via.placeholder.com/100"},
|
| 25 |
-
{"id": "C3", "name": "Coconut Jelly", "desc": "Chilled coconut milk jelly", "price": 4.0, "img": "https://via.placeholder.com/100"},
|
| 26 |
-
{"id": "C4", "name": "Sweet Bean Soup", "desc": "Warm red bean dessert soup", "price": 3.5, "img": "https://via.placeholder.com/100"},
|
| 27 |
-
{"id": "C5", "name": "Sesame Balls", "desc": "Fried sesame rice balls", "price": 3.5, "img": "https://via.placeholder.com/100"},
|
| 28 |
-
],
|
| 29 |
-
"Drinks": [
|
| 30 |
-
{"id": "D1", "name": "Lime Soda", "desc": "Refreshing soda with lime", "price": 2.5, "img": "https://via.placeholder.com/100"},
|
| 31 |
-
{"id": "D2", "name": "Iced Tea", "desc": "Chilled black tea with lemon", "price": 2.0, "img": "https://via.placeholder.com/100"},
|
| 32 |
-
{"id": "D3", "name": "Coconut Water", "desc": "Natural coconut juice", "price": 3.0, "img": "https://via.placeholder.com/100"},
|
| 33 |
-
{"id": "D4", "name": "Soy Milk", "desc": "Sweetened soy milk", "price": 2.0, "img": "https://via.placeholder.com/100"},
|
| 34 |
-
{"id": "D5", "name": "Bottled Water", "desc": "Still mineral water", "price": 1.5, "img": "https://via.placeholder.com/100"},
|
| 35 |
-
],
|
| 36 |
}
|
| 37 |
|
| 38 |
-
# ==========
|
| 39 |
def record_time(start_time):
|
| 40 |
duration = round(time.time() - start_time, 2)
|
| 41 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
@@ -44,6 +22,18 @@ def record_time(start_time):
|
|
| 44 |
writer.writerow([timestamp, duration])
|
| 45 |
return f"✅ Thank you! Your decision time was {duration} seconds.\nPlease proceed to the next page and enter your selected item IDs."
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
with gr.Blocks() as demo:
|
| 48 |
start_time = time.time()
|
| 49 |
gr.Markdown("# 📋 Digital Menu\nPlease browse the menu and decide what you'd like to order. When ready, click the button at the bottom.")
|
|
@@ -53,11 +43,20 @@ with gr.Blocks() as demo:
|
|
| 53 |
with gr.Tab(label=category):
|
| 54 |
for item in items:
|
| 55 |
with gr.Row():
|
| 56 |
-
gr.Image(value=item["img"],
|
| 57 |
gr.Markdown(f"**{item['id']} - {item['name']}**\n\n{item['desc']}\n\n💰 €{item['price']:.2f}")
|
| 58 |
|
| 59 |
submit_btn = gr.Button("✅ I have made my selection")
|
| 60 |
output_box = gr.Textbox(label="", lines=3, interactive=False)
|
| 61 |
submit_btn.click(fn=record_time, inputs=[gr.State(value=start_time)], outputs=output_box)
|
| 62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
demo.launch()
|
|
|
|
| 2 |
import time
|
| 3 |
import csv
|
| 4 |
from datetime import datetime
|
| 5 |
+
import os
|
| 6 |
+
import pandas as pd
|
| 7 |
|
| 8 |
# ====== 菜单数据结构(英文 + 编号) ======
|
| 9 |
MENU_DATA = {
|
| 10 |
+
"Appetizers": [...], # (略,保留原结构)
|
| 11 |
+
"Main Dishes": [...],
|
| 12 |
+
"Desserts": [...],
|
| 13 |
+
"Drinks": [...],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
|
| 16 |
+
# ========== 功能函数 ==========
|
| 17 |
def record_time(start_time):
|
| 18 |
duration = round(time.time() - start_time, 2)
|
| 19 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
| 22 |
writer.writerow([timestamp, duration])
|
| 23 |
return f"✅ Thank you! Your decision time was {duration} seconds.\nPlease proceed to the next page and enter your selected item IDs."
|
| 24 |
|
| 25 |
+
def show_csv():
|
| 26 |
+
if not os.path.exists("decision_times.csv"):
|
| 27 |
+
return "No data recorded yet."
|
| 28 |
+
df = pd.read_csv("decision_times.csv", header=None, names=["Timestamp", "Duration (s)"])
|
| 29 |
+
return df.to_markdown(index=False)
|
| 30 |
+
|
| 31 |
+
def clear_csv():
|
| 32 |
+
if os.path.exists("decision_times.csv"):
|
| 33 |
+
os.remove("decision_times.csv")
|
| 34 |
+
return "🧹 decision_times.csv has been cleared."
|
| 35 |
+
|
| 36 |
+
# ========== Gradio 主界面 ==========
|
| 37 |
with gr.Blocks() as demo:
|
| 38 |
start_time = time.time()
|
| 39 |
gr.Markdown("# 📋 Digital Menu\nPlease browse the menu and decide what you'd like to order. When ready, click the button at the bottom.")
|
|
|
|
| 43 |
with gr.Tab(label=category):
|
| 44 |
for item in items:
|
| 45 |
with gr.Row():
|
| 46 |
+
gr.Image(value=item["img"], width=100, height=100)
|
| 47 |
gr.Markdown(f"**{item['id']} - {item['name']}**\n\n{item['desc']}\n\n💰 €{item['price']:.2f}")
|
| 48 |
|
| 49 |
submit_btn = gr.Button("✅ I have made my selection")
|
| 50 |
output_box = gr.Textbox(label="", lines=3, interactive=False)
|
| 51 |
submit_btn.click(fn=record_time, inputs=[gr.State(value=start_time)], outputs=output_box)
|
| 52 |
|
| 53 |
+
with gr.Accordion("📊 Admin Tools (optional)", open=False):
|
| 54 |
+
gr.Markdown("### View or Clear Recorded CSV Data")
|
| 55 |
+
show_btn = gr.Button("📥 Show CSV Data")
|
| 56 |
+
show_output = gr.Textbox(label="decision_times.csv content", lines=10)
|
| 57 |
+
show_btn.click(fn=show_csv, outputs=show_output)
|
| 58 |
+
|
| 59 |
+
clear_btn = gr.Button("🧹 Clear CSV File")
|
| 60 |
+
clear_btn.click(fn=clear_csv, outputs=show_output)
|
| 61 |
+
|
| 62 |
demo.launch()
|