Smart_Spender / app.py
Rida-Zehra's picture
Update app.py
5a4fded verified
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import easyocr
import cv2
import datetime
import os
import speech_recognition as sr
from PIL import Image
from groq import Groq
from dotenv import load_dotenv
import json
import os
RECEIPT_FOLDER = "receipts"
os.makedirs(RECEIPT_FOLDER, exist_ok=True)
DATA_FILE = "data.json"
def load_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r") as f:
return json.load(f)
else:
return {"receipts": [], "budgets": {}}
def save_data():
with open(DATA_FILE, "w") as f:
json.dump(data, f, indent=4)
# βœ… This loads your existing data or creates a new one
data = load_data()
# Load environment variables
load_dotenv()
# Initialize Groq client
client = Groq(api_key=os.getenv("smartspender"))
# App Configuration
st.set_page_config(page_title="SmartSpender πŸ’Έ", layout="wide")
# Display App Logo (Centered)
st.markdown("<div style='text-align: center;'>", unsafe_allow_html=True)
st.image("logo.png.png", width=150)
st.markdown("</div>", unsafe_allow_html=True)
st.markdown("""
<style>
body {
background-color: #f7f1ff;
color: #3f3f44;
}
.stApp {
font-family: 'Comic Sans MS', cursive, sans-serif;
}
.sidebar .sidebar-content {
background-color: #f3e5f5;
}
.stButton>button {
background-color: #d1c4e9;
color: black;
border-radius: 10px;
}
.stTextInput>div>div>input, .stNumberInput>div>div>input {
background-color: #f5f5f5;
border-radius: 8px;
}
</style>
""", unsafe_allow_html=True)
# Session State Defaults
if "expenses" not in st.session_state:
st.session_state.expenses = []
if "budget" not in st.session_state:
st.session_state.budget = 50000
if "total_spent" not in st.session_state:
st.session_state.total_spent = 0
if "reminders" not in st.session_state:
st.session_state.reminders = []
# Navigation Panel
menu = st.sidebar.radio("🌸 Navigation", [
"🏠 Dashboard",
"πŸ“₯ Expense Entry",
"🎯 Budget",
"πŸ’° Savings",
"🚨 Budget Alerts",
"πŸ“Š Goals",
"πŸ’± Currency Converter",
"πŸ“„ Upload Receipt",
"πŸ”” Reminders",
"πŸ₯‘ Guac AI Chatbot"
], key="navigation_menu")
# Dashboard
if menu == "🏠 Dashboard":
st.title("πŸ“Š SmartSpender Dashboard")
st.metric("πŸ’Έ Total Spent", f"Rs. {st.session_state.total_spent:,.2f}")
st.metric("🎯 Budget", f"Rs. {st.session_state.budget:,.2f}")
auto_savings = st.session_state.budget - st.session_state.total_spent
st.metric("πŸ’° Savings", f"Rs. {auto_savings:,.2f}")
# Pie chart
labels = ['Spent', 'Remaining']
values = [st.session_state.total_spent, auto_savings]
fig, ax = plt.subplots()
ax.pie(values, labels=labels, autopct='%1.1f%%', startangle=90)
ax.axis('equal')
st.pyplot(fig)
# Expense Entry (Voice + Manual)
if menu == "πŸ“₯ Expense Entry":
st.title("πŸ“₯ Expense Entry")
method = st.radio("Choose input method:", ["Manual", "Voice"])
if method == "Manual":
category = st.text_input("Category")
amount = st.number_input("Amount (Rs.)", min_value=0.0, step=100.0)
if st.button("Add Expense"):
st.session_state.expenses.append((category, amount))
st.session_state.total_spent += amount
st.success(f"Added Rs. {amount} to {category}!")
else:
st.info("Click below and speak your expense like 'Grocery 500'")
if st.button("πŸŽ™οΈ Record Expense"):
r = sr.Recognizer()
with sr.Microphone() as source:
audio = r.listen(source)
try:
text = r.recognize_google(audio)
st.write(f"You said: {text}")
parts = text.split()
category = parts[0]
amount = float(parts[1])
st.session_state.expenses.append((category, amount))
st.session_state.total_spent += amount
st.success(f"Added Rs. {amount} to {category}!")
except Exception as e:
st.error(f"Error: {str(e)}")
# Budget Setting
if menu == "🎯 Budget":
st.title("🎯 Set Your Monthly Budget")
st.session_state.budget = st.number_input(
"Monthly Budget (Rs.)",
min_value=0.0,
step=100.0,
value=float(st.session_state.budget)
)
st.success(f"Your monthly budget is set to Rs. {st.session_state.budget:,.2f}")
# Savings Section
if menu == "πŸ’° Savings":
st.title("πŸ’° Your Savings")
auto_savings = st.session_state.budget - st.session_state.total_spent
manual_savings = st.number_input("Enter additional manual savings (optional)", min_value=0.0, step=100.0)
total_savings = auto_savings + manual_savings
st.success(f"πŸ’Έ Total Savings: Rs. {total_savings:,.2f}")
# Budget Alerts
if menu == "🚨 Budget Alerts":
st.title("🚨 Budget Alerts")
spent_ratio = st.session_state.total_spent / st.session_state.budget
if spent_ratio >= 0.8:
st.error("You’ve spent over 80% of your budget! Slow down 🐒")
else:
st.success("You’re within your budget πŸ‘Œ")
# Goals with Medals
if menu == "πŸ“Š Goals":
st.title("πŸ† Savings Goals")
goal = st.number_input("Set a savings goal:", min_value=0.0, step=100.0)
current_savings = st.session_state.budget - st.session_state.total_spent
if current_savings >= goal:
if current_savings >= goal * 3:
st.balloons()
st.success("πŸŽ–οΈ GOLD Medal Earned!")
elif current_savings >= goal * 2:
st.success("πŸ₯ˆ SILVER Medal Earned!")
else:
st.success("πŸ₯‰ BRONZE Medal Earned!")
else:
st.info("Keep going! You're on your way to a medal ✨")
# Currency Converter
if menu == "πŸ’± Currency Converter":
st.title("πŸ’± Currency Converter")
amount = st.number_input("Amount (Rs.)", min_value=0.0)
currency = st.selectbox("Convert to:", ["USD", "EUR", "SAR", "AED"])
rates = {"USD": 0.0036, "EUR": 0.0033, "SAR": 0.0135, "AED": 0.0132}
converted = amount * rates[currency]
st.success(f"{amount} PKR = {converted:.2f} {currency}")
# Upload Receipt
if menu == "πŸ“„ Upload Receipt":
st.header("🧾 Upload & View Receipts")
uploaded_receipt = st.file_uploader("Upload your receipt", type=["png", "jpg", "jpeg"])
if uploaded_receipt is not None:
if not os.path.exists(RECEIPT_FOLDER):
os.makedirs(RECEIPT_FOLDER)
filename = f"{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}_{uploaded_receipt.name}"
filepath = os.path.join(RECEIPT_FOLDER, filename)
img = Image.open(uploaded_receipt)
img.save(filepath)
data["receipts"].append({"image": filepath, "date": str(datetime.date.today())})
def save_data(data):
with open("data.json", "w") as f:
json.dump(data, f, indent=4)
save_data(data)
st.success("Receipt uploaded and saved!")
st.subheader("Saved Receipts")
if data["receipts"]:
cols = st.columns(3)
for idx, r in enumerate(data["receipts"]):
if os.path.exists(r["image"]):
with cols[idx % 3]:
st.image(r["image"], width=200)
st.caption(f"{r['date']}")
else:
st.info("No receipts uploaded yet.")
# Reminders
if menu == "πŸ”” Reminders":
st.title("πŸ”” Bill/Subscription Reminders")
reminder = st.text_input("Add Reminder")
if st.button("Add Reminder"):
st.session_state.reminders.append(reminder)
if st.session_state.reminders:
st.markdown("### πŸ“‹ Your Reminders:")
for r in st.session_state.reminders:
st.write(f"πŸ”” {r}")
# Guac AI Chatbot
if menu == "πŸ₯‘ Guac AI Chatbot":
st.title("πŸ₯‘ Guac AI Chatbot")
user_prompt = st.chat_input("Ask me anything about budgeting πŸ’¬")
if user_prompt:
try:
response = client.chat.completions.create(
model="llama3-70b-8192",
messages=[
{"role": "system", "content": "You are Guac AIπŸ₯‘, a smart, cute, fun financial assistant."},
{"role": "user", "content": user_prompt}
]
)
st.chat_message("Guac AIπŸ₯‘").write(response.choices[0].message.content)
except Exception as e:
st.error(f"Chatbot error: {str(e)}")
# Footer
st.markdown("""
---
πŸ’‘ One-stop app for budgeting, saving & tracking
πŸ”” Reminders for bills & subscriptions
πŸ“Š Auto detects overspending & trends
πŸ† Savings goals with reward badges
πŸ“· Upload & store receipts in one place
🌍 Built-in currency converter
πŸ₯‘ Guac AI for smart finance tips
""")