import gradio as gr import pandas as pd import numpy as np CSV_FILE = "all-vehicles-model@public.csv" # עמודות חשובות מתוך הדאטה COLS = { "make": "Make", "model": "Model", "fuel1": "Fuel Type1", "fuel_any": "Fuel Type", "drive": "Drive", "trans": "Transmission", "cyl": "Cylinders", "disp": "Engine displacement", "mpg_city_f1": "City Mpg For Fuel Type1", "mpg_hwy_f1": "Highway Mpg For Fuel Type1", "mpg_comb_f1": "Combined Mpg For Fuel Type1", "mpg_city_f2": "City Mpg For Fuel Type2", "mpg_hwy_f2": "Highway Mpg For Fuel Type2", "mpg_comb_f2": "Combined Mpg For Fuel Type2", "annual_fuel_cost_f1": "Annual Fuel Cost For Fuel Type1", "annual_fuel_cost_f2": "Annual Fuel Cost For Fuel Type2", "ev_range_f2": "Epa Range For Fuel Type2", "charge_240": "Time to charge at 240V", "co2_f1": "Co2 Fuel Type1", "co2_tailpipe_f1": "Co2 Tailpipe For Fuel Type1", "hatch_lug": "Hatchback luggage volume", "hatch_pass": "Hatchback passenger volume", "year": "Year" } def load_data(): df = pd.read_csv(CSV_FILE, sep=";", encoding="utf-8", engine="python") # המרות טיפוס בסיסיות for c in ["City Mpg For Fuel Type1", "Highway Mpg For Fuel Type1", "Combined Mpg For Fuel Type1", "City Mpg For Fuel Type2", "Highway Mpg For Fuel Type2", "Combined Mpg For Fuel Type2", "Annual Fuel Cost For Fuel Type1", "Annual Fuel Cost For Fuel Type2", "Epa Range For Fuel Type2", "Time to charge at 240V", "Cylinders", "Engine displacement", "Hatchback luggage volume", "Hatchback passenger volume"]: if c in df.columns: df[c] = pd.to_numeric(df[c], errors="coerce") # הורדת כפילויות בסיסית keep_cols = [v for v in COLS.values() if v in df.columns] subset = [c for c in keep_cols if c in ["Make","Model","Year"]] if subset: df = df.drop_duplicates(subset=subset) return df DF = load_data() def options_safe(col): if col in DF.columns: vals = DF[col].dropna().astype(str).str.strip().replace("", np.nan).dropna().unique().tolist() vals = [v for v in vals if v.lower() not in {"nan","none"}] vals.sort() return vals[:50] return [] FUEL_OPTS = sorted(set([*options_safe(COLS["fuel1"]), *options_safe(COLS["fuel_any"]), "No preference"])) DRIVE_OPTS = [*options_safe(COLS["drive"]), "No preference"] TRANS_OPTS = [*options_safe(COLS["trans"]), "No preference"] def recommend(budget_fuel_per_year, usage, daily_km, seats_min, fuel_pref, drive_pref, trans_pref, cargo_need, perf_pref): df = DF.copy() # סינונים לפי העדפות if fuel_pref and fuel_pref != "No preference": df = df[(df.get(COLS["fuel1"], "").astype(str).str.contains(fuel_pref, case=False, na=False)) | (df.get(COLS["fuel_any"], "").astype(str).str.contains(fuel_pref, case=False, na=False))] if drive_pref and drive_pref != "No preference" and COLS["drive"] in df.columns: df = df[df[COLS["drive"]].astype(str).str.contains(drive_pref, case=False, na=False)] if trans_pref and trans_pref != "No preference" and COLS["trans"] in df.columns: df = df[df[COLS["trans"]].astype(str).str.contains(trans_pref, case=False, na=False)] def norm(s): s = pd.to_numeric(s, errors="coerce") return (s - s.min()) / (s.max() - s.min() + 1e-9) # יעילות דלק לפי שימוש if usage == "עיר": eff = df.get(COLS["mpg_city_f1"], df.get(COLS["mpg_comb_f1"])) elif usage == "בינעירוני": eff = df.get(COLS["mpg_hwy_f1"], df.get(COLS["mpg_comb_f1"])) else: eff = df.get(COLS["mpg_comb_f1"]) eff_score = norm(eff) if eff is not None else pd.Series(0, index=df.index) # עלות דלק שנתית נמוכה עדיפה fuel_cost = df.get(COLS["annual_fuel_cost_f1"]) fuel_cost_score = 1 - norm(fuel_cost) if fuel_cost is not None else pd.Series(0.5, index=df.index) # התאמת EV לפי טווח ונסועה יומית ev_range = df.get(COLS["ev_range_f2"]) if ev_range is not None and daily_km: ev_ok = (ev_range >= (daily_km * 0.62 * 3)) # ק"מ למייל, פי 3 מרווח ביטחון ev_score = ev_ok.astype(float) else: ev_score = pd.Series(0.5, index=df.index) # נפח מטען cargo = df.get(COLS["hatch_lug"]) cargo_score = norm(cargo) if (cargo is not None and cargo_need) else pd.Series(0.5, index=df.index) # ביצועים מול חסכון לפי צילינדרים ונפח מנוע cyl = df.get(COLS["cyl"]); disp = df.get(COLS["disp"]) perf_raw = norm(cyl).fillna(0.5) * 0.5 + norm(disp).fillna(0.5) * 0.5 econ_raw = 1 - perf_raw perf_mix = perf_pref * perf_raw + (1 - perf_pref) * econ_raw # משקולות w_eff = 0.3 w_cost = 0.25 w_ev = 0.15 w_cargo = 0.1 w_perf = 0.2 score = w_eff*eff_score.fillna(0.5) + w_cost*fuel_cost_score.fillna(0.5) + w_ev*ev_score.fillna(0.5) + \ w_cargo*cargo_score.fillna(0.5) + w_perf*perf_mix.fillna(0.5) df_out = df.copy() df_out["Score"] = score.round(4) show_cols = [c for c in [ COLS["make"], COLS["model"], "Year" if "Year" in df.columns else None, COLS["fuel1"] if COLS["fuel1"] in df.columns else COLS["fuel_any"], COLS["drive"], COLS["trans"], COLS["mpg_city_f1"], COLS["mpg_hwy_f1"], COLS["mpg_comb_f1"], COLS["annual_fuel_cost_f1"], COLS["ev_range_f2"], COLS["cyl"], COLS["disp"], "Score" ] if (c and (c in df.columns)) or c=="Score"] return df_out.sort_values("Score", ascending=False).head(10)[show_cols] with gr.Blocks(title="ממליץ רכבים") as demo: gr.Markdown("# ממליץ רכבים חכם\nהאפליקציה מתאימה דגמים לצרכים שלך על בסיס דאטה של EPA.\n") with gr.Row(): usage = gr.Radio(["עיר", "בינעירוני", "מעורב"], value="מעורב", label="אופי שימוש") daily_km = gr.Slider(0, 200, value=30, step=5, label="נסועה יומית ממוצעת בקילומטרים") budget_fuel = gr.Slider(0, 6000, value=3000, step=100, label="תקציב דלק או חשמל שנתי") with gr.Row(): fuel_pref = gr.Dropdown(choices=FUEL_OPTS, value="No preference", label="עדיפות לסוג דלק") drive_pref = gr.Dropdown(choices=DRIVE_OPTS, value="No preference", label="הנעה") trans_pref = gr.Dropdown(choices=TRANS_OPTS, value="No preference", label="תיבת הילוכים") with gr.Row(): cargo_need = gr.Slider(0, 800, value=0, step=20, label="נפח מטען מינימלי רצוי") perf_pref = gr.Slider(0, 1, value=0.4, step=0.05, label="עדיפות 0 חסכון 1 ביצועים") seats_min = gr.Slider(2, 8, value=4, step=1, label="מושבים מינימום") btn = gr.Button("מצא רכבים") out = gr.Dataframe(interactive=False, wrap=True, label="התאמות מומלצות . טופ 10") btn.click(fn=recommend, inputs=[budget_fuel, usage, daily_km, seats_min, fuel_pref, drive_pref, trans_pref, cargo_need, perf_pref], outputs=out) demo.queue().launch()