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"""

{row['dish_name']}

{pct} MATCH

📍 {row['restaurant_name']} | {row.get('cuisine_type', 'Gourmet')}

"{row['taste_review']}"

💰 {row.get('price_range', '$$')} 👥 BEST FOR: {row.get('best_for', 'Friends')}

Twin: {u_name} from {row['user_origin']}

""" 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("

BiteWise

") # מסך 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=["."])