Spaces:
Sleeping
Sleeping
File size: 7,034 Bytes
fef3901 b8bb1b3 fef3901 723ac7f 8dbe1d6 8be8159 fef3901 b34e44f 8be8159 0fd2d60 8be8159 d8399cc 1459687 fef3901 1459687 8be8159 1459687 0e1fbe4 1459687 491c2dd e8220c4 1459687 8be8159 e8220c4 8be8159 1459687 bcd2fbe e8220c4 1459687 8be8159 1459687 491c2dd 1459687 e8220c4 d310c93 1459687 723ac7f 1459687 7abb4fe 1459687 7abb4fe 8be8159 7abb4fe dbf6e24 e8220c4 1459687 b7dac73 1459687 b7dac73 8be8159 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | import gradio as gr
import pandas as pd
import numpy as np
import pickle
import os
import zipfile
import glob
import random
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
# --- 1. הכנת תמונות ---
IMAGE_DIR = "extracted_images"
if os.path.exists('images.zip'):
with zipfile.ZipFile('images.zip', 'r') as zip_ref:
zip_ref.extractall(IMAGE_DIR)
def find_dish_image(idx):
pattern = os.path.join(IMAGE_DIR, "Dishes_Images", f"dish_{idx}_*.jpg")
files = glob.glob(pattern)
if not files:
files = glob.glob(os.path.join(IMAGE_DIR, "**", f"dish_{idx}_*.jpg"), recursive=True)
return f"file/{files[0]}" if files else "https://via.placeholder.com/400x400?text=BiteWise+Dish"
# --- 2. טעינה וסנכרון ברזל ---
model = SentenceTransformer('all-MiniLM-L6-v2')
def load_data():
df = pd.read_csv('bitewise_clean_dataset.csv').fillna("N/A")
dish_emb = np.load('BiteWise_Dish_Embeddings.npy')
with open('BiteWise_User_Embeddings.pkl', 'rb') as f:
u_emb = pickle.load(f)
if isinstance(u_emb, list): u_emb = np.array(u_emb)
min_l = min(len(df), len(dish_emb), len(u_emb))
return df.iloc[:min_l].reset_index(drop=True), dish_emb[:min_l], u_emb[:min_l]
main_df, dish_embeddings, user_embeddings = load_data()
NAMES = ["James Miller", "Sarah Johnson", "Michael Brown", "Emily Davis", "Robert Wilson"]
# --- 3. מנוע החיפוש ---
def run_discovery(query, origin, hobbies, style):
q_vec = model.encode([str(query)])
u_dna = f"Origin: {origin}, Hobbies: {hobbies}, Style: {style}"
u_vec = model.encode([u_dna])
scores = (cosine_similarity(q_vec, dish_embeddings).flatten() * 0.7) + (cosine_similarity(u_vec, user_embeddings).flatten() * 0.3)
res = main_df.copy()
res['similarity_score'] = scores
top = res.sort_values('similarity_score', ascending=False).head(10)
html = ""
seen = set()
for idx, row in top.iterrows():
u_name = row['user_name'] if row['user_name'] != "N/A" else random.choice(NAMES)
if u_name not in seen:
pct = f"{min(99.0, 85 + (row['similarity_score'] * 15)):.1f}%"
img = find_dish_image(idx)
html += f"""
<div style="border: 1px solid #C4A484; padding: 25px; margin-bottom: 25px; background: #FFF9F5; border-left: 10px solid #3E2723; display: flex; gap: 20px; color: #3E2723;">
<img src="{img}" style="width: 200px; height: 200px; object-fit: cover; border: 1px solid #D2B48C; background: white;">
<div style="flex: 1;">
<div style="display: flex; justify-content: space-between;">
<h2 style="margin: 0; font-family: Serif;">{row['dish_name']}</h2>
<span style="background: #3E2723; color: white; padding: 2px 10px; border-radius: 20px; font-size: 0.8em;">{pct} MATCH</span>
</div>
<p style="margin: 5px 0; font-weight: bold;">📍 {row['restaurant_name']} | {row.get('cuisine_type', 'Gourmet')}</p>
<p style="font-style: italic;">"{row['taste_review']}"</p>
<div style="margin: 10px 0;">
<span style="background: #EEDDCC; padding: 4px 8px; border: 1px solid #D2B48C; font-size: 0.8em;">💰 {row.get('price_range', '$$')}</span>
<span style="background: #EEDDCC; padding: 4px 8px; border: 1px solid #D2B48C; font-size: 0.8em;">👥 BEST FOR: {row.get('best_for', 'Friends')}</span>
</div>
<p style="font-size: 0.85em;"><b>Twin:</b> {u_name} from {row['user_origin']}</p>
</div>
</div>
"""
seen.add(u_name)
if len(seen) == 3: break
return html
# --- 4. הממשק (זרימת מסכים אמיתית) ---
custom_css = """
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;1,400&display=swap');
.gradio-container { background-color: #FDFCF8 !important; }
button.primary { background: #3E2723 !important; color: white !important; border-radius: 0px !important; text-transform: uppercase; letter-spacing: 2px; }
"""
with gr.Blocks(css=custom_css) as demo:
gr.HTML("<h1 style='text-align: center; color: #3E2723; font-family: \"Playfair Display\", serif; font-size: 4em; font-style: italic; border-bottom: 2px double #D2B48C; margin-bottom: 40px;'>BiteWise</h1>")
# מסך 1: DNA
with gr.Column(visible=True) as screen_dna:
with gr.Row():
u_n = gr.Textbox(label="IDENTIFICATION")
u_o = gr.Dropdown(list(main_df['user_origin'].unique()), label="ORIGIN", value="Tel Aviv")
with gr.Row():
u_h = gr.Dropdown(list(main_df['user_hobbies'].unique()), label="INTERESTS")
u_s = gr.Dropdown(list(main_df['user_fashion_style'].unique()) + ["Vintage/Retro"], label="STYLE", value="Vintage/Retro")
btn_sync = gr.Button("SYNC PERSONALITY", variant="primary")
# מסך 2: Discovery
with gr.Column(visible=False) as screen_discovery:
q_in = gr.Textbox(label="CRAVING", placeholder="What are you in the mood for?")
btn_search = gr.Button("COMMENCE SEARCH", variant="primary")
out_html = gr.HTML()
with gr.Row():
btn_back_to_dna = gr.Button("⬅ BACK TO DNA")
btn_to_archive = gr.Button("✚ ADD DISCOVERY")
# מסך 3: Archive
with gr.Column(visible=False) as screen_archive:
gr.Markdown("### ARCHIVE A NEW CULINARY DISCOVERY")
with gr.Row():
gr.Textbox(label="DISH")
gr.Textbox(label="ESTABLISHMENT")
gr.Textbox(label="REVIEW", lines=3)
btn_submit = gr.Button("SUBMIT & SHARE", variant="primary")
status_msg = gr.Markdown()
btn_back_to_disc = gr.Button("⬅ BACK TO DISCOVERY")
# פונקציות מעבר בין מסכים
def show_discovery(): return {screen_dna: gr.update(visible=False), screen_discovery: gr.update(visible=True), screen_archive: gr.update(visible=False)}
def show_dna(): return {screen_dna: gr.update(visible=True), screen_discovery: gr.update(visible=False), screen_archive: gr.update(visible=False)}
def show_archive(): return {screen_dna: gr.update(visible=False), screen_discovery: gr.update(visible=False), screen_archive: gr.update(visible=True)}
btn_sync.click(show_discovery, None, [screen_dna, screen_discovery, screen_archive])
btn_back_to_dna.click(show_dna, None, [screen_dna, screen_discovery, screen_archive])
btn_to_archive.click(show_archive, None, [screen_dna, screen_discovery, screen_archive])
btn_back_to_disc.click(show_discovery, None, [screen_dna, screen_discovery, screen_archive])
btn_search.click(run_discovery, [q_in, u_o, u_h, u_s], out_html)
btn_submit.click(lambda: "### Thank you! \nYour discovery has been successfully shared.", None, status_msg)
demo.launch(allowed_paths=["."]) |