Spaces:
Sleeping
Sleeping
| # app.py (Final Version: SAHAR AUTO, Custom Design, and Manufacturer Dropdown) | |
| import streamlit as st | |
| import pickle | |
| import pandas as pd | |
| import numpy as np | |
| import os | |
| import sys | |
| # --- CONFIGURATION --- | |
| PKL_FILE_PATH = "model.pkl" | |
| LOGO_PATH = r"F:\Car_price\sahar_logo.png" | |
| COMPANY_NAME = "SAHAR AUTO" | |
| # --- CUSTOM CSS FOR STYLING --- | |
| st.markdown( | |
| """ | |
| <style> | |
| /* 1. General App Background and Text Color */ | |
| .stApp { | |
| background-color: #1a1a1a; | |
| color: white; | |
| } | |
| /* 2. Headers and General Text (White) */ | |
| h1, h2, h3, h4, h5, h6, p, label, .stMarkdown, .streamlit-expanderHeader { | |
| color: white !important; | |
| } | |
| /* 3. Button Styling (Red) */ | |
| .stButton > button { | |
| background-color: #ff4b4b; | |
| color: white; | |
| border-radius: 5px; | |
| padding: 10px 20px; | |
| font-size: 1.1em; | |
| font-weight: bold; | |
| border: none; | |
| transition: background-color 0.3s ease; | |
| } | |
| .stButton > button:hover { | |
| background-color: #e03a3a; | |
| } | |
| /* 4. Custom Banner Text */ | |
| .banner-text-large { | |
| font-size: 3.5em; | |
| font-weight: bold; | |
| color: white; | |
| margin-bottom: 0px; | |
| line-height: 1.2; | |
| } | |
| .banner-text-red { | |
| font-size: 3.5em; | |
| font-weight: bold; | |
| color: #ff4b4b; | |
| margin-top: 0px; | |
| line-height: 1.2; | |
| } | |
| /* 5. Input Fields Styling */ | |
| .stSelectbox > div > div, | |
| .stNumberInput > div > div { | |
| background-color: #333333; | |
| color: white; | |
| } | |
| /* 💡 تغيير لون النص داخل حقول إدخال الأرقام إلى الأحمر */ | |
| div[data-testid*="stNumberInput"] input { | |
| color: #ff4b4b !important; | |
| font-weight: bold; | |
| background-color: #333333; | |
| } | |
| /* Other input text remains white */ | |
| div[data-testid*="stTextInput"] input, | |
| div[data-testid*="stSelectbox"] div[data-testid*="stInput"], | |
| div[data-testid*="stRadio"] label, | |
| .stSlider label { | |
| color: white !important; | |
| } | |
| /* 6. Slider Coloring */ | |
| .stSlider > div > div > div > div { | |
| background-color: #ff4b4b; | |
| } | |
| .stSlider > div > div > div > div > div { | |
| background-color: #ff4b4b; | |
| } | |
| .st-emotion-cache-eq8hrv { | |
| max-width: 1000px; | |
| padding-top: 2rem; | |
| padding-bottom: 2rem; | |
| } | |
| </style> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| # --- Load Model and Columns --- | |
| def load_model_data(): | |
| """Loads model, all columns, and extracts manufacturer names from columns.""" | |
| if not os.path.exists(PKL_FILE_PATH): | |
| st.error(f"Error: Model file not found at: {PKL_FILE_PATH}") | |
| sys.exit(1) | |
| try: | |
| with open(PKL_FILE_PATH, "rb") as f: | |
| saved = pickle.load(f) | |
| all_columns = saved["columns"] | |
| # 💡 يتم استخراج جميع الشركات المصنعة، لا حاجة لإضافة toyota يدوياً الآن | |
| manufacturer_cols = [col.replace('Maker_', '') for col in all_columns if col.startswith('Maker_')] | |
| return saved["model"], all_columns, manufacturer_cols | |
| except Exception as e: | |
| st.error(f"Error loading model: {e}") | |
| sys.exit(1) | |
| model, training_columns, manufacturer_options = load_model_data() | |
| # --- Prediction Function --- | |
| def predict_price(input_data): | |
| """Processes input and predicts the price.""" | |
| full_data = {col: 0 for col in training_columns} | |
| for key, value in input_data.items(): | |
| if key in full_data: | |
| full_data[key] = value | |
| df = pd.DataFrame([full_data]) | |
| df = df.reindex(columns=training_columns, fill_value=0) | |
| prediction = model.predict(df)[0] | |
| return np.round(prediction, 2) | |
| # --- Streamlit APP LAYOUT --- | |
| st.set_page_config(page_title=f"{COMPANY_NAME} Predictor", layout="wide") | |
| # Logo and Headline | |
| col_logo, col_title = st.columns([1, 4]) | |
| with col_logo: | |
| if os.path.exists(LOGO_PATH): | |
| st.image(LOGO_PATH, width=150) | |
| else: | |
| st.markdown(f"<h3 style='color:white;'>{COMPANY_NAME}</h3>", unsafe_allow_html=True) | |
| st.markdown(f"<p style='color:white; font-size:0.8em; margin-top:-10px;'>AUTO</p>", unsafe_allow_html=True) | |
| with col_title: | |
| st.markdown("<p class='banner-text-large'>LET'S GET YOU</p>", unsafe_allow_html=True) | |
| st.markdown("<p class='banner-text-red'>ON THE ROAD</p>", unsafe_allow_html=True) | |
| st.markdown("---") | |
| st.header("Enter Car Specifications") | |
| # Input Fields (main numeric) | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| horsepower = st.slider("1. Horsepower", 50, 200, 100) | |
| enginesize = st.slider("2. Engine Size", 70, 300, 120) | |
| with col2: | |
| curbweight = st.number_input("3. Curbweight", 1500, 4500, 2500) | |
| carwidth = st.number_input("4. Car Width", 60.0, 75.0, 68.0) | |
| st.markdown("---") | |
| st.subheader("Categorical Details") | |
| # Input Fields (categorical) | |
| carbody_options = ['sedan', 'hatchback', 'wagon', 'hardtop', 'convertible'] | |
| fueltype_options = ['gas', 'diesel'] | |
| drivewheel_options = ['fwd', 'rwd', '4wd'] | |
| # Create 4 columns for categorical inputs including Maker | |
| col_cat0, col_cat1, col_cat2, col_cat3 = st.columns(4) | |
| with col_cat0: | |
| selected_maker = st.selectbox("5. Manufacturer", sorted(manufacturer_options)) | |
| with col_cat1: | |
| selected_carbody = st.selectbox("6. Car Body Type", carbody_options) | |
| with col_cat2: | |
| selected_fueltype = st.radio("7. Fuel Type", fueltype_options) | |
| with col_cat3: | |
| selected_drivewheel = st.radio("8. Drive Wheel", drivewheel_options) | |
| # --- Prepare Input Data for Prediction --- | |
| input_data_for_prediction = { | |
| 'horsepower': horsepower, | |
| 'enginesize': enginesize, | |
| 'curbweight': curbweight, | |
| 'carwidth': carwidth, | |
| # --- One-Hot Encoded Features --- | |
| **{col: 0 for col in training_columns if '_' in col} | |
| } | |
| # Set selected One-Hot features to 1 | |
| # 💡 Manufacturer: Set the selected maker column to 1 | |
| maker_column_name = f'Maker_{selected_maker}' | |
| if maker_column_name in training_columns: | |
| input_data_for_prediction[maker_column_name] = 1 | |
| # Other One-Hot features | |
| if f'carbody_{selected_carbody}' in training_columns: | |
| input_data_for_prediction[f'carbody_{selected_carbody}'] = 1 | |
| if f'fueltype_{selected_fueltype}' in training_columns: | |
| input_data_for_prediction[f'fueltype_{selected_fueltype}'] = 1 | |
| if f'drivewheel_{selected_drivewheel}' in training_columns: | |
| input_data_for_prediction[f'drivewheel_{selected_drivewheel}'] = 1 | |
| # --- Prediction Button --- | |
| st.markdown("---") | |
| if st.button("REQUEST A QUOTE"): | |
| try: | |
| input_data_for_prediction = {k: v for k, v in input_data_for_prediction.items() if k is not None} | |
| predicted_price = predict_price(input_data_for_prediction) | |
| st.success(f"## Your Estimated Car Price: **${predicted_price:,.2f}**") | |
| except Exception as e: | |
| st.error("Please ensure all fields are filled correctly.") | |
| st.error(f"Detailed Error: {e}") |