File size: 5,211 Bytes
f10ec56
2c359f1
c7d0bb8
 
53977a7
d88597f
118b9d7
11532fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9189033
 
 
a6ee9ca
6ca4f9e
11532fe
 
9189033
 
57f3e55
11532fe
57f3e55
11532fe
53977a7
11532fe
9189033
 
53977a7
9189033
 
 
 
 
 
e57fb31
9189033
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57f3e55
 
 
 
 
 
 
53977a7
 
 
 
9189033
53977a7
9189033
 
53977a7
9189033
 
 
 
 
53977a7
9189033
 
 
 
53977a7
 
9189033
53977a7
 
 
 
 
 
 
9189033
e6dd97e
53977a7
 
 
 
 
d88597f
 
 
e833f6e
d88597f
 
 
 
 
53977a7
 
 
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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.")