Spaces:
Sleeping
Sleeping
import pandas as pd | |
import plotly.express as px | |
import streamlit as st | |
from transformers import pipeline | |
import datetime | |
import matplotlib.pyplot as plt | |
# Function to add background image to the app | |
def add_bg_from_url(image_url): | |
st.markdown( | |
f""" | |
<style> | |
.stApp {{ | |
background-image: url({image_url}); | |
background-size: cover; | |
background-position: center center; | |
background-repeat: no-repeat; | |
}} | |
</style> | |
""", | |
unsafe_allow_html=True | |
) | |
# Set background image (it will remain even after file upload) | |
add_bg_from_url('https://huggingface.co./spaces/engralimalik/Smart-Expense-Tracker/resolve/main/top-view-finance-business-elements.jpg') | |
# File upload | |
uploaded_file = st.file_uploader("Upload your expense CSV file", type=["csv"]) | |
if uploaded_file: | |
df = pd.read_csv(uploaded_file) | |
# Display first few rows to the user for format verification | |
st.write("Here are the first few entries in your file for format verification:") | |
st.write(df.head()) | |
# Ensure 'Amount' is numeric and 'Date' is in datetime format | |
df['Amount'] = pd.to_numeric(df['Amount'], errors='coerce') | |
df['Date'] = pd.to_datetime(df['Date']) | |
# Initialize Hugging Face model for zero-shot classification | |
classifier = pipeline('zero-shot-classification', model='roberta-large-mnli') | |
categories = ["Groceries", "Rent", "Utilities", "Entertainment", "Dining", "Transportation"] | |
# Function to categorize | |
def categorize_expense(description): | |
result = classifier(description, candidate_labels=categories) | |
return result['labels'][0] # Most probable category | |
# Apply categorization | |
df['Category'] = df['Description'].apply(categorize_expense) | |
# Sidebar for setting the monthly budget using sliders | |
st.sidebar.header("Set Your Monthly Budget") | |
groceries_budget = st.sidebar.slider("Groceries Budget", 0, 1000, 300) | |
rent_budget = st.sidebar.slider("Rent Budget", 0, 5000, 1000) | |
utilities_budget = st.sidebar.slider("Utilities Budget", 0, 500, 150) | |
entertainment_budget = st.sidebar.slider("Entertainment Budget", 0, 1000, 100) | |
dining_budget = st.sidebar.slider("Dining Budget", 0, 1000, 150) | |
transportation_budget = st.sidebar.slider("Transportation Budget", 0, 500, 120) | |
# Store the updated budget values | |
budgets = { | |
"Groceries": groceries_budget, | |
"Rent": rent_budget, | |
"Utilities": utilities_budget, | |
"Entertainment": entertainment_budget, | |
"Dining": dining_budget, | |
"Transportation": transportation_budget | |
} | |
# Get the minimum and maximum dates from the uploaded file | |
min_date = df['Date'].min() | |
max_date = df['Date'].max() | |
# Add a date slider for start and end date based on data from the uploaded file | |
start_date = st.sidebar.date_input("Start Date", min_date) | |
end_date = st.sidebar.date_input("End Date", max_date) | |
# Filter data by date range | |
df_filtered = df[(df['Date'] >= pd.to_datetime(start_date)) & (df['Date'] <= pd.to_datetime(end_date))] | |
# Track if any category exceeds its budget | |
df_filtered['Budget_Exceeded'] = df_filtered.apply(lambda row: row['Amount'] > budgets.get(row['Category'], 0), axis=1) | |
# Show categories that exceeded their budget | |
exceeded_budget = df_filtered[df_filtered['Budget_Exceeded'] == True] | |
st.write("Categories that exceeded the budget:", exceeded_budget[['Date', 'Category', 'Amount']]) | |
# Visualizations | |
# 1. Pie Chart for expense distribution by category | |
category_expenses = df_filtered.groupby('Category')['Amount'].sum() | |
fig1 = px.pie(category_expenses, values=category_expenses.values, names=category_expenses.index, title="Expense Distribution by Category") | |
st.plotly_chart(fig1) | |
# 2. Monthly Spending Trends (Line Chart) | |
df_filtered['Month'] = df_filtered['Date'].dt.to_period('M').astype(str) # Convert Period to string for Plotly compatibility | |
monthly_expenses = df_filtered.groupby('Month')['Amount'].sum() | |
# Convert monthly_expenses into DataFrame for correct plotting | |
monthly_expenses_df = monthly_expenses.reset_index() | |
if not monthly_expenses_df.empty: | |
fig2 = px.line(monthly_expenses_df, x='Month', y='Amount', title="Monthly Expenses", labels={"Month": "Month", "Amount": "Amount ($)"}) | |
st.plotly_chart(fig2) | |
else: | |
st.write("No data to display for the selected date range.") | |
# 3. Monthly Spending vs Budget (Bar Chart) | |
if not monthly_expenses_df.empty: | |
monthly_expenses_df = pd.DataFrame({ | |
'Actual': monthly_expenses, | |
'Budget': [sum(budgets.values())] * len(monthly_expenses) # Same budget for simplicity | |
}) | |
# Create a Matplotlib figure for the bar chart | |
fig3, ax = plt.subplots(figsize=(10, 6)) | |
monthly_expenses_df.plot(kind='bar', ax=ax) | |
ax.set_title('Monthly Spending vs Budget') | |
ax.set_ylabel('Amount ($)') | |
ax.set_xlabel('Month') | |
# Use st.pyplot to display the figure | |
st.pyplot(fig3) | |
else: | |
st.write("No data to display for the selected date range.") | |