danielhjerresen's picture
Update app.py
4fe458f verified
import streamlit as st
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# Apply theme
sns.set_theme()
sns.set(color_codes=True)
# Title and Problem Statement
st.title("How Do Day of the Week and Customer Sex Influence Tipping?")
st.subheader("What day of the week is it???")
# Import dataset
df_tips = sns.load_dataset("tips")
df_tips["tip_percentage"] = df_tips["tip"] / df_tips["total_bill"] * 100
# Sidebar filters
st.sidebar.header("Filters")
days_list = df_tips["day"].unique().tolist() # convert to Python list
selected_days = st.sidebar.multiselect(
"Select Day(s):",
options=days_list,
default=days_list # use the same Python list
)
selected_sex = st.sidebar.radio(
"Select Sex:", options=["All", "Male", "Female"], index=0
)
# Filter Data
filtered = df_tips[df_tips["day"].isin(selected_days)]
if selected_sex != "All":
filtered = filtered[filtered["sex"] == selected_sex]
# KPI
avg_tip_pct = filtered["tip_percentage"].mean()
st.metric("Average Tip Percentage", f"{avg_tip_pct:.2f}%")
# Visualization
st.subheader("Tip Percentage by Day")
fig, ax = plt.subplots()
order = ["Thur", "Fri", "Sat", "Sun"]
sns.barplot(
data=filtered,
x="day",
y="tip_percentage",
hue="sex",
ci=None,
ax=ax,
dodge=True, # Force side-by-side bars
order=order # Consistent weekday order
)
ax.set_ylabel("Average Tip %")
ax.set_xlabel("Day")
ax.legend(title="Sex")
fig.tight_layout()
st.pyplot(fig)
# Dynamic Insight
st.subheader("Insight")
if len(filtered) > 0:
if selected_sex == "All":
grouped = filtered.groupby("day")["tip_percentage"].mean()
max_day = grouped.idxmax()
max_value = grouped.max()
st.write(f"On **{max_day}**, customers gave the highest average tip percentage: {max_value:.2f}%.")
else:
grouped = filtered.groupby(["day","sex"])["tip_percentage"].mean()
max_day = grouped.idxmax()
max_value = grouped.max()
st.write(f"On **{max_day[0]}**, **{max_day[1]}** customers gave the highest average tip percentage: {max_value:.2f}%.")
else:
st.write("No data available for the selected filters.")