Kallapapruk's picture
Upload 2 files
23da334 verified
import streamlit as st
import google.generativeai as genai
import textwrap # For wrapping long text
# --- API Key Setup (Replace with your actual keys) ---
API_KEYS = [
"AIzaSyCnvlaZII4rP6UUy9LHL2u5Ab7CpST7U9g",
"AIzaSyBXg8nVnRCrLcbBTby7j5yDoKaQvfo9rFk",
"AIzaSyCbPsdkZ8DGCAOSlfrXhh5JP2OLYEDHcJg"
]
# --- Helper Functions ---
def call_gemini_api(prompt):
for api_key in API_KEYS:
try:
genai.configure(api_key=api_key)
model = genai.GenerativeModel("gemini-pro")
response = model.generate_content(prompt)
return response.text.strip()
except Exception as e:
error_message = str(e)
if "insufficient_quota" in error_message or "Quota exceeded" in error_message:
continue
else:
return f"❌ เกิดข้อผิดพลาด: {error_message}"
return "⚠️ API ทั้งหมดหมดโควต้าแล้ว กรุณาตรวจสอบบัญชีของคุณ"
def process_menus(response_text):
menu_list = response_text.split("🍽️ เมนูที่")
menu_list = [menu.strip() for menu in menu_list if menu.strip()]
if not menu_list:
menu_list = response_text.split("\n- ")
menu_list = [menu.strip() for menu in menu_list if menu.strip()]
if not menu_list:
menu_list = response_text.split("\n• ")
menu_list = [menu.strip() for menu in menu_list if menu.strip()]
return menu_list
# --- Custom CSS ---
st.markdown("""
<style>
/* Global Styles */
body {
font-family: 'Kanit', sans-serif; /* Modern Thai font */
}
.stApp {
background-color: #f0f2f6; /* Light gray background */
background-image: url("https://www.transparenttextures.com/patterns/subtle-white-feathers.png"); /*Subtle Background Pattern*/
}
/* Header */
.title {
color: #2c3e50;
text-align: center;
padding: 1rem 0;
font-size: 2.5rem; /* Larger title */
font-weight: 600; /* Semi-bold */
}
/* Mode Selection */
.mode-selection {
margin-bottom: 2rem;
border-radius: 10px;
padding: 10px;
background-color: white;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
/* Input Sections */
.input-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
/* Input Fields */
.stTextInput, .stSelectbox, .stSlider, .stRadio, .stNumberInput {
margin-bottom: 10px;
}
.stTextArea>div>div>textarea{
border-color:#3498db;
}
/* Buttons */
.stButton>button {
background-color: #3498db; /* Blue */
color: white;
border: none;
border-radius: 20px; /* Rounded buttons */
padding: 10px 24px;
font-size: 1.1rem;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Subtle shadow */
width: 100%; /* Make buttons full width */
}
.stButton>button:hover {
background-color: #2980b9; /* Darker blue on hover */
transform: translateY(-2px); /* Slight lift on hover */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.stButton>button:active {
transform: translateY(0); /* Reset position on click */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
/* Menu Columns */
.menu-column {
background-color: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.2s ease; /* Smooth transition */
border: 2px solid transparent; /* Add a border */
}
.menu-column:hover {
transform: scale(1.03); /* Slightly enlarge on hover */
border-color: #3498db;
}
.menu-column h3 {
color: #3498db; /* Blue heading */
margin-bottom: 10px;
font-size: 1.4rem;
}
.menu-item {
font-size: 1rem;
line-height: 1.6;
color: #4a4a4a; /* Dark gray text */
}
/* Expander */
.st-expanderHeader {
font-size: 1.2rem;
font-weight: 500; /* Slightly bolder expander header */
}
/* About Section */
.about-section {
background-color: #e0e0e0;
border-radius: 10px;
padding: 20px;
margin-top: 20px;
}
.about-section ul {
list-style: none; /* Remove bullet points */
padding: 0;
}
.about-section li {
margin-bottom: .5rem;
}
/* Spinners */
.st-cf {
color: #3498db !important; /* Make spinners blue */
}
</style>
""", unsafe_allow_html=True)
# --- App UI ---
st.markdown("<h1 class='title'>🍽️ Smart Cooking App 😎</h1>", unsafe_allow_html=True)
with st.container(border=True):
option = st.radio("🔹 เลือกโหมด:", ["สร้างเมนูจากวัตถุดิบ", "ค้นหาเมนูสำหรับซื้อ"],
horizontal=True, key="mode_select")
if option == "สร้างเมนูจากวัตถุดิบ":
st.subheader("✨ สร้างเมนูแบบกำหนดเอง")
with st.expander("📝 กรอกวัตถุดิบของคุณ", expanded=True):
ingredients = st.text_area("วัตถุดิบ (คั่นด้วยจุลภาค):",
placeholder="เช่น ไข่, หมูสับ, ผักกาด...",
height=120)
with st.expander("⚙️ ปรับแต่งเมนูของคุณ", expanded=False):
col1, col2 = st.columns(2)
with col1:
num_ingredients = st.number_input("จำนวนวัตถุดิบหลัก", min_value=1, max_value=20, value=3, step=1)
category = st.selectbox("ประเภทอาหาร",
["อาหารทั่วไป", "มังสวิรัติ", "อาหารคลีน", "อาหารไทย", "อาหารญี่ปุ่น", "อาหารตะวันตก"])
calories = st.slider("แคลอรี่ที่ต้องการ (kcal)", 100, 1500, 500, step=50)
with col2:
difficulty = st.radio("ระดับความยาก", ["ง่าย", "ปานกลาง", "ยาก"], horizontal=True)
cook_time = st.slider("เวลาทำอาหาร (นาที)", 5, 180, 30, step=5)
if st.button("🍳 สร้างเมนู", use_container_width=True):
if ingredients:
prompt = (f"ฉันมี: {ingredients} ({num_ingredients} วัตถุดิบหลัก) "
f"แนะนำเมนู {category} เวลาทำไม่เกิน {cook_time} นาที "
f"ประมาณ {calories} kcal ระดับความยาก {difficulty} "
f"พร้อมวิธีทำอย่างละเอียด เสนอ 3 ตัวเลือก คั่นด้วย '🍽️ เมนูที่'")
with st.spinner("กำลังสร้างสรรค์ไอเดียอร่อยๆ..."):
menu_list = process_menus(call_gemini_api(prompt))
if menu_list:
st.subheader("🧑‍🍳 เมนูแนะนำ:")
cols = st.columns(3)
for i, menu in enumerate(menu_list[:3]):
with cols[i]:
st.markdown(f"<div class='menu-column'><h3>🍽️ เมนูที่ {i+1}</h3><p class='menu-item'>{menu}</p></div>", unsafe_allow_html=True)
else:
st.warning("⚠️ ไม่พบเมนูที่ตรงกับเกณฑ์ของคุณ โปรดลองปรับการตั้งค่า")
else:
st.warning("⚠️ กรุณากรอกวัตถุดิบของคุณ")
elif option == "ค้นหาเมนูสำหรับซื้อ":
st.subheader("✨ ค้นหาเมนูที่ใช่สำหรับคุณ")
with st.expander("⚙️ ตั้งค่าการค้นหา", expanded=True):
col1, col2 = st.columns(2)
with col1:
country = st.selectbox("ประเทศ", ["ไทย", "ญี่ปุ่น", "เกาหลีใต้", "สหรัฐอเมริกา", "อังกฤษ", "ฝรั่งเศส", "เยอรมนี"])
category = st.selectbox("ประเภทอาหาร", ["อาหารไทย", "อาหารญี่ปุ่น", "อาหารเกาหลี", "ฟาสต์ฟู้ด", "อาหารสุขภาพ"])
with col2:
taste = st.radio("รสชาติ", ["เผ็ด", "หวาน", "เค็ม", "เปรี้ยว"], horizontal=True)
budget = st.radio("งบประมาณ", ["ต่ำกว่า 100 บาท", "100 - 300 บาท", "มากกว่า 300 บาท"], horizontal=True)
if st.button("🔎 ค้นหาเมนู", use_container_width=True):
prompt = (f"ฉันต้องการซื้ออาหาร {category} รสชาติ {taste} งบประมาณ {budget} ใน {country} "
f"แนะนำ 3 ตัวเลือกเมนู {category} ที่มีขายใน {country} คั่นด้วย '🍽️ เมนูที่'")
with st.spinner("กำลังค้นหาตัวเลือกที่ดีที่สุด..."):
menu_list = process_menus(call_gemini_api(prompt))
if menu_list:
st.subheader("🧑‍🍳 เมนูแนะนำ:")
cols = st.columns(3)
for i, menu in enumerate(menu_list[:3]):
with cols[i]:
st.markdown(f"<div class='menu-column'><h3>🍽️ เมนูที่ {i+1}</h3><p class='menu-item'>{menu}</p></div>", unsafe_allow_html=True)
else:
st.warning("⚠️ ไม่พบเมนู โปรดลองอีกครั้ง")
# --- About Section ---
st.markdown("---")
if st.button("📜 เกี่ยวกับผู้พัฒนา", use_container_width=True):
with st.expander("🤝 พบกับทีมงาน"):
st.markdown("""
<div class='about-section'>
<ul>
<li><strong>1. นาย กัลปพฤกษ์ วิเชียรรัตน์</strong> - <em>ชั้น 6/13 เลขที่ 3(คนแบกครับอิๆ)</em></li>
<li><strong>2. นาย ธีราธร มุกดาเพชรรัตน์</strong> - <em>ชั้น 6/13 เลขที่ 13</em></li>
<li><strong>3. นาย อภิวิชญ์ อดุลธรรมวิทย์</strong> - <em>ชั้น 6/13 เลขที่ 28</em></li>
<li><strong>4. นาย ปัณณวิชญ์ หลีกภัย</strong> - <em>ชั้น 6/13 เลขที่ 29</em></li>
</ul>
</div>
""", unsafe_allow_html=True)