BilalCode's picture
Create app.py
beb1f86 verified
Raw
History Blame Contribute Delete
3.42 kB
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
st.set_page_config(page_title="Smart Group Expense Tracker", layout="centered")
st.title("πŸ’Έ Smart Group Expense Tracker")
st.caption("Roommates & Trips Edition - Track expenses, split fairly, and settle up easily!")
# --- Session State Init ---
if "participants" not in st.session_state:
st.session_state.participants = []
if "expenses" not in st.session_state:
st.session_state.expenses = []
# --- Add Participants ---
with st.expander("βž• Add Participants"):
new_name = st.text_input("Participant Name", placeholder="e.g. Bilal")
if st.button("Add Participant") and new_name:
if new_name not in st.session_state.participants:
st.session_state.participants.append(new_name)
else:
st.warning("Participant already exists!")
# --- Show Participants ---
if st.session_state.participants:
st.markdown("### πŸ‘₯ Participants")
st.write(", ".join(st.session_state.participants))
else:
st.info("Add at least one participant to start tracking.")
# --- Log New Expense ---
st.divider()
st.markdown("### 🧾 Log New Expense")
if st.session_state.participants:
col1, col2 = st.columns(2)
with col1:
payer = st.selectbox("Paid By", st.session_state.participants)
with col2:
amount = st.number_input("Amount (Rs)", min_value=0.0, step=0.5)
reason = st.text_input("For What?", placeholder="e.g. Dinner, Transport")
if st.button("Add Expense"):
if amount > 0 and payer:
st.session_state.expenses.append({
"payer": payer,
"amount": amount,
"reason": reason
})
else:
st.warning("Please enter a valid amount and payer.")
# --- Display Expense Log ---
if st.session_state.expenses:
df = pd.DataFrame(st.session_state.expenses)
st.subheader("πŸ“‹ Expense Log")
st.dataframe(df)
# --- Optional Tip Calculation ---
st.subheader("πŸ’‘ Add Tip")
tip_percent = st.slider("Tip %", 0, 25, 0)
tip_amount = df["amount"].sum() * (tip_percent / 100)
total = df["amount"].sum() + tip_amount
st.markdown(f"**πŸ’° Total Spent (with Tip): Rs. {total:.2f}**")
# --- Final Balances ---
per_person = total / len(st.session_state.participants)
paid = df.groupby("payer")["amount"].sum()
balance = paid - per_person
summary = pd.DataFrame({
"Paid": paid,
"Balance": balance
}).fillna(0)
st.subheader("πŸ’³ Final Balances")
st.dataframe(summary.style.format({"Paid": "Rs. {:.2f}", "Balance": "Rs. {:.2f}"}))
st.caption("πŸ”Ή Positive balance = Gets money back | Negative = Owes money")
# --- Pie Chart ---
st.subheader("πŸ“Š Who Paid What?")
fig, ax = plt.subplots()
ax.pie(paid, labels=paid.index, autopct='%1.1f%%', startangle=90)
ax.axis('equal')
st.pyplot(fig)
# --- Download CSV ---
st.subheader("⬇️ Download Expense Log")
csv = df.to_csv(index=False).encode("utf-8")
st.download_button(
label="Download CSV",
data=csv,
file_name="group_expenses.csv",
mime="text/csv"
)
else:
st.info("No expenses logged yet.")
# --- Footer ---
st.markdown("---")
st.markdown(
"<p style='text-align: center; font-size: 14px;'>Made with ❀️ by <b>Bilal Hussain</b></p>",
unsafe_allow_html=True
)