Spaces:
Sleeping
Sleeping
| 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 | |
| """) | |