import streamlit as st import joblib import pandas as pd import numpy as np MODEL_PATH = 'src/r_tips.joblib' SCALER_PATH = 'src/scaler_tips.joblib' FEATURES = [ 'total_bill', 'size', 'bill_per_person', 'sex_Male', 'smoker_Yes', 'day_Sat', 'day_Sun', 'day_Thur', 'time_Lunch' ] NUMERICAL_COLS = ['total_bill', 'size', 'bill_per_person'] @st.cache_resource def load_assets(): try: model = joblib.load(MODEL_PATH) scaler = joblib.load(SCALER_PATH) return model, scaler except Exception as e: st.error(f"Error loading assets. Ensure '{MODEL_PATH}' and '{SCALER_PATH}' are uploaded. Error: {e}") return None, None def preprocess_and_predict(model, scaler, input_data): df_input = pd.DataFrame([input_data]) df_processed = pd.get_dummies(df_input, columns=["sex", "smoker", "day", "time"], drop_first=True) for col in FEATURES: if col not in df_processed.columns: df_processed[col] = 0 final_features = df_processed[FEATURES] numerical_part = final_features[NUMERICAL_COLS] scaled_numerical = scaler.transform(numerical_part) final_input_array = final_features.values.copy() final_input_array[:, 0:len(NUMERICAL_COLS)] = scaled_numerical prediction = model.predict(final_input_array) return float(prediction[0]) # --- Streamlit Interface --- st.set_page_config(page_title="Waiter Tip Predictor", layout="centered") st.title("💰 Waiter Tip Prediction") st.markdown("Enter bill details and dining context to predict the tip amount ($).") model, scaler = load_assets() if model is not None and scaler is not None: st.sidebar.header("Dining Details") total_bill = st.sidebar.number_input("Total Bill ($):", min_value=1.0, value=25.0, step=0.5) size = st.sidebar.number_input("Party Size:", min_value=1, max_value=10, value=3) bill_per_person = total_bill / size if size > 0 else 0 sex = st.sidebar.selectbox("Server/Diner Sex:", options=["Female", "Male"]) smoker = st.sidebar.selectbox("Smoker at Table?", options=["No", "Yes"]) day = st.sidebar.selectbox("Day of the Week:", options=["Thur", "Fri", "Sat", "Sun"]) time = st.sidebar.selectbox("Time of Day:", options=["Lunch", "Dinner"]) input_data = { 'total_bill': total_bill, 'size': size, 'bill_per_person': bill_per_person, 'sex': sex, 'smoker': smoker, 'day': day, 'time': time } st.subheader("Input Summary:") st.dataframe(pd.DataFrame([input_data]), hide_index=True) if st.button("Predict Tip Amount"): with st.spinner('Calculating prediction...'): predicted_tip = preprocess_and_predict(model, scaler, input_data) st.success("Prediction Successful!") st.markdown("### Predicted Tip:") st.markdown(f"**${predicted_tip:,.2f}**") st.info(f"The predicted tip is approximately {predicted_tip/total_bill:.1%} of the total bill.")