-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexpense_tracker.py
More file actions
106 lines (91 loc) · 4.18 KB
/
expense_tracker.py
File metadata and controls
106 lines (91 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import os
from datetime import date
st.set_page_config(page_title="Expense Tracker", page_icon="💰", layout="wide")
st.title("💰 Expense Tracker with Visuals")
DATA_FILE = "expenses.csv"
# Load or create data
if os.path.exists(DATA_FILE):
df = pd.read_csv(DATA_FILE)
else:
df = pd.DataFrame(columns=["Date", "Category", "Description", "Amount"])
# ── Sidebar: Add Expense ──────────────────────────────────────────────────────
st.sidebar.header("➕ Add New Expense")
with st.sidebar:
exp_date = st.date_input("Date", value=date.today())
category = st.selectbox("Category", ["Food", "Transport", "Shopping",
"Entertainment", "Health", "Bills", "Other"])
description = st.text_input("Description")
amount = st.number_input("Amount (₹)", min_value=0.0, step=10.0)
budget = st.number_input("Monthly Budget (₹)", min_value=0.0, step=100.0, value=10000.0)
if st.button("Add Expense", use_container_width=True):
if amount > 0 and description:
new_row = pd.DataFrame([[str(exp_date), category, description, amount]],
columns=["Date", "Category", "Description", "Amount"])
df = pd.concat([df, new_row], ignore_index=True)
df.to_csv(DATA_FILE, index=False)
st.success("Expense added!")
st.rerun()
else:
st.error("Please fill all fields.")
# CSV Upload
st.markdown("---")
st.subheader("📂 Upload CSV")
uploaded = st.file_uploader("Upload expenses CSV", type=["csv"])
if uploaded:
uploaded_df = pd.read_csv(uploaded)
df = pd.concat([df, uploaded_df], ignore_index=True)
df.to_csv(DATA_FILE, index=False)
st.success("CSV uploaded!")
st.rerun()
# ── Main Dashboard ────────────────────────────────────────────────────────────
if df.empty:
st.info("No expenses yet. Add one from the sidebar!")
else:
df["Amount"] = pd.to_numeric(df["Amount"], errors="coerce")
df["Date"] = pd.to_datetime(df["Date"])
total = df["Amount"].sum()
col1, col2, col3 = st.columns(3)
col1.metric("Total Spent", f"₹{total:,.2f}")
col2.metric("Monthly Budget", f"₹{budget:,.2f}")
remaining = budget - total
col3.metric("Remaining", f"₹{remaining:,.2f}", delta=f"{'Over budget!' if remaining < 0 else 'OK'}")
if remaining < 0:
st.error("⚠️ You have exceeded your budget!")
elif remaining < budget * 0.2:
st.warning("⚠️ Only 20% of budget remaining!")
st.markdown("---")
col_a, col_b = st.columns(2)
# Pie Chart
with col_a:
st.subheader("📊 Spending by Category")
cat_data = df.groupby("Category")["Amount"].sum()
fig1, ax1 = plt.subplots()
ax1.pie(cat_data, labels=cat_data.index, autopct="%1.1f%%", startangle=90)
ax1.axis("equal")
st.pyplot(fig1)
# Bar Chart by Date
with col_b:
st.subheader("📅 Daily Spending")
daily = df.groupby(df["Date"].dt.date)["Amount"].sum()
fig2, ax2 = plt.subplots()
ax2.bar(daily.index.astype(str), daily.values, color="steelblue")
ax2.set_xlabel("Date")
ax2.set_ylabel("Amount (₹)")
plt.xticks(rotation=45, ha="right")
st.pyplot(fig2)
# Expense Table
st.markdown("---")
st.subheader("📋 All Expenses")
st.dataframe(df.sort_values("Date", ascending=False), use_container_width=True)
# Export
st.download_button("⬇️ Export to CSV", df.to_csv(index=False),
file_name="expense_report.csv", mime="text/csv")
# Excel Export
excel_path = "expense_report.xlsx"
df.to_excel(excel_path, index=False)
with open(excel_path, "rb") as f:
st.download_button("⬇️ Export to Excel", f, file_name="expense_report.xlsx",
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")