Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1 |
-
|
2 |
-
|
3 |
# budget_tracker_with_voice_ocr.py
|
4 |
import streamlit as st
|
5 |
import pandas as pd
|
@@ -266,7 +264,7 @@ def process_voice_text(text):
|
|
266 |
break
|
267 |
|
268 |
# Extract numbers for amount using regex
|
269 |
-
amount_pattern = r'(
|
270 |
matches = re.findall(amount_pattern, text_lower)
|
271 |
if matches:
|
272 |
for match in matches:
|
@@ -292,7 +290,7 @@ def process_voice_text(text):
|
|
292 |
'receipt_image': ['']
|
293 |
})
|
294 |
st.session_state.expenses = pd.concat([st.session_state.expenses, new_expense], ignore_index=True)
|
295 |
-
st.success(f"β
Expense logged:
|
296 |
|
297 |
# Check budget alerts
|
298 |
check_budget_alerts(amount, category)
|
@@ -442,8 +440,8 @@ def ocr_receipt_processing():
|
|
442 |
if amount == 0:
|
443 |
# Extract amount with multiple patterns
|
444 |
amount_patterns = [
|
445 |
-
r'[
|
446 |
-
r'(\d+(?:\.\d+)?)\s*[
|
447 |
r'(?:total|amount|paid|grand total).*?(\d+(?:\.\d+)?)',
|
448 |
r'(?:bill|invoice).*?(\d+(?:\.\d+)?)'
|
449 |
]
|
@@ -489,7 +487,7 @@ def ocr_receipt_processing():
|
|
489 |
'receipt_image': [image_data]
|
490 |
})
|
491 |
st.session_state.expenses = pd.concat([st.session_state.expenses, new_expense], ignore_index=True)
|
492 |
-
st.success(f"β
Receipt processed successfully:
|
493 |
|
494 |
# Check budget alerts
|
495 |
check_budget_alerts(amount, category)
|
@@ -525,7 +523,7 @@ def create_budget():
|
|
525 |
else:
|
526 |
category = st.text_input("Enter custom category")
|
527 |
with col2:
|
528 |
-
budget_amount = st.number_input("Budget Amount (
|
529 |
period = st.selectbox("Period", ["Monthly", "Weekly", "Custom"])
|
530 |
|
531 |
# AI-powered budget recommendations
|
@@ -535,7 +533,7 @@ def create_budget():
|
|
535 |
try:
|
536 |
# Prepare spending history for LLM
|
537 |
spending_summary = st.session_state.expenses.groupby('category')['amount'].sum().to_dict()
|
538 |
-
spending_text = "\n".join([f"{cat}:
|
539 |
|
540 |
prompt = f"""
|
541 |
Based on this user's spending history:
|
@@ -556,7 +554,7 @@ def create_budget():
|
|
556 |
recommendation = re.findall(r'\d+(?:\.\d+)?', response.content)
|
557 |
if recommendation:
|
558 |
recommended_amount = float(recommendation[0])
|
559 |
-
st.info(f"π€ AI Recommendation:
|
560 |
except:
|
561 |
st.info("π€ AI Recommendation: " + response.content)
|
562 |
|
@@ -578,7 +576,7 @@ def create_budget():
|
|
578 |
st.session_state.budgets.loc[
|
579 |
st.session_state.budgets['category'] == category, 'period'
|
580 |
] = period
|
581 |
-
st.success(f"π Budget updated:
|
582 |
else:
|
583 |
# Add new budget
|
584 |
new_budget = pd.DataFrame({
|
@@ -587,7 +585,7 @@ def create_budget():
|
|
587 |
'period': [period]
|
588 |
})
|
589 |
st.session_state.budgets = pd.concat([st.session_state.budgets, new_budget], ignore_index=True)
|
590 |
-
st.success(f"β
Budget set:
|
591 |
except Exception as e:
|
592 |
st.error(f"β Error setting budget: {str(e)}")
|
593 |
else:
|
@@ -623,7 +621,7 @@ def set_savings_goals():
|
|
623 |
with col1:
|
624 |
goal_name = st.text_input("Goal Name", placeholder="e.g., Vacation, Emergency Fund")
|
625 |
with col2:
|
626 |
-
target_amount = st.number_input("Target Amount (
|
627 |
with col3:
|
628 |
target_date = st.date_input("Target Date",
|
629 |
value=datetime.now() + timedelta(days=30))
|
@@ -640,9 +638,9 @@ def set_savings_goals():
|
|
640 |
|
641 |
prompt = f"""
|
642 |
Based on this financial situation:
|
643 |
-
- Monthly income (budgeted):
|
644 |
-
- Monthly spending:
|
645 |
-
- Current savings:
|
646 |
|
647 |
For a savings goal named '{goal_name}', suggest:
|
648 |
1. A realistic target amount
|
@@ -688,7 +686,7 @@ def set_savings_goals():
|
|
688 |
days_left = (goal['target_date'] - datetime.now().date()).days
|
689 |
st.write(f"**{goal['goal_name']}**")
|
690 |
st.progress(min(progress/100, 1.0))
|
691 |
-
st.write(f"π°
|
692 |
st.write(f"π
Target Date: {goal['target_date']} ({days_left} days left)")
|
693 |
|
694 |
# Add to current savings
|
@@ -697,7 +695,7 @@ def set_savings_goals():
|
|
697 |
if st.button(f"β Add to {goal['goal_name']}", key=f"btn_{idx}"):
|
698 |
if add_amount > 0:
|
699 |
st.session_state.savings_goals.at[idx, 'current_amount'] += add_amount
|
700 |
-
st.success(f"β
Added
|
701 |
st.rerun()
|
702 |
st.write("---")
|
703 |
except Exception as e:
|
@@ -721,7 +719,7 @@ def spending_categorization():
|
|
721 |
st.write("π Uncategorized Expenses:")
|
722 |
for idx, expense in uncategorized.iterrows():
|
723 |
try:
|
724 |
-
st.write(f"π
{expense['date']} |
|
725 |
predefined_categories = ["Food", "Transport", "Shopping", "Entertainment", "Bills", "Health", "Education", "Other"]
|
726 |
new_category = st.selectbox(f"Re-categorize", predefined_categories,
|
727 |
key=f"cat_{idx}")
|
@@ -777,8 +775,8 @@ def spending_categorization():
|
|
777 |
st.subheader("π Summary")
|
778 |
total_spent = filtered_expenses['amount'].sum()
|
779 |
avg_spent = filtered_expenses['amount'].mean()
|
780 |
-
st.metric("Total Spent", f"
|
781 |
-
st.metric("Average Expense", f"
|
782 |
|
783 |
# AI-powered spending analysis
|
784 |
if st.button("π€ Analyze Spending Patterns"):
|
@@ -787,7 +785,7 @@ def spending_categorization():
|
|
787 |
try:
|
788 |
# Prepare spending data for analysis
|
789 |
category_spending = filtered_expenses.groupby('category')['amount'].sum().to_dict()
|
790 |
-
spending_text = "\n".join([f"{cat}:
|
791 |
|
792 |
prompt = f"""
|
793 |
Analyze this spending pattern and provide insights:
|
@@ -833,11 +831,11 @@ def check_budget_alerts(amount, category):
|
|
833 |
]['amount'].sum()
|
834 |
|
835 |
if current_spending > budget_amount:
|
836 |
-
alert_msg = f"π¨ OVERSPENT: {category} -
|
837 |
if alert_msg not in st.session_state.notifications:
|
838 |
st.session_state.notifications.append(alert_msg)
|
839 |
elif current_spending > budget_amount * 0.8: # 80% threshold
|
840 |
-
alert_msg = f"β οΈ WARNING: {category} -
|
841 |
if alert_msg not in st.session_state.notifications:
|
842 |
st.session_state.notifications.append(alert_msg)
|
843 |
except Exception as e:
|
@@ -850,7 +848,7 @@ def generate_financial_insight_for_expense(expense):
|
|
850 |
if llm:
|
851 |
prompt = f"""
|
852 |
For this expense:
|
853 |
-
- Amount:
|
854 |
- Category: {expense['category']}
|
855 |
- Description: {expense['description']}
|
856 |
|
@@ -895,9 +893,9 @@ def alerts_and_notifications():
|
|
895 |
spent = category_spending.iloc[0]['amount']
|
896 |
budget_amount = budget['budget_amount']
|
897 |
if spent > budget_amount:
|
898 |
-
alerts.append(f"π¨ OVERSPENT: {budget['category']} -
|
899 |
elif spent > budget_amount * 0.8: # 80% threshold
|
900 |
-
alerts.append(f"β οΈ WARNING: {budget['category']} -
|
901 |
|
902 |
# Display alerts
|
903 |
if alerts:
|
@@ -967,7 +965,7 @@ def visualizations_and_summaries():
|
|
967 |
]
|
968 |
if not monthly_expenses.empty:
|
969 |
total_spent = monthly_expenses['amount'].sum()
|
970 |
-
st.metric("Total Monthly Spending", f"
|
971 |
category_summary = monthly_expenses.groupby('category')['amount'].sum().reset_index()
|
972 |
fig3 = px.bar(category_summary, x='category', y='amount',
|
973 |
title='Monthly Spending by Category')
|
@@ -1008,17 +1006,17 @@ def visualizations_and_summaries():
|
|
1008 |
# Prepare data for summary
|
1009 |
total_expenses = st.session_state.expenses['amount'].sum()
|
1010 |
category_spending = st.session_state.expenses.groupby('category')['amount'].sum().to_dict()
|
1011 |
-
spending_text = "\n".join([f"{cat}:
|
1012 |
|
1013 |
# Get budget data
|
1014 |
total_budget = st.session_state.budgets['budget_amount'].sum()
|
1015 |
-
budget_text = "\n".join([f"{row['category']}:
|
1016 |
for _, row in st.session_state.budgets.iterrows()])
|
1017 |
|
1018 |
prompt = f"""
|
1019 |
Based on this financial data:
|
1020 |
|
1021 |
-
Total Expenses:
|
1022 |
|
1023 |
Spending by Category:
|
1024 |
{spending_text}
|
@@ -1093,7 +1091,7 @@ def receipt_management():
|
|
1093 |
try:
|
1094 |
with cols[idx % 3]:
|
1095 |
st.write(f"**π
{receipt['date']}**")
|
1096 |
-
st.write(f"π°
|
1097 |
st.write(f"π·οΈ {receipt['category']}")
|
1098 |
if receipt['receipt_image'].startswith('data:image'):
|
1099 |
# Display base64 image
|
@@ -1107,7 +1105,7 @@ def receipt_management():
|
|
1107 |
try:
|
1108 |
prompt = f"""
|
1109 |
Analyze this receipt expense:
|
1110 |
-
- Amount:
|
1111 |
- Category: {receipt['category']}
|
1112 |
- Date: {receipt['date']}
|
1113 |
|
@@ -1266,11 +1264,11 @@ def main_dashboard():
|
|
1266 |
expense_count = len(st.session_state.expenses)
|
1267 |
|
1268 |
with col1:
|
1269 |
-
st.metric("π° Total Expenses", f"
|
1270 |
with col2:
|
1271 |
-
st.metric("π Total Budget", f"
|
1272 |
with col3:
|
1273 |
-
st.metric("π Total Savings", f"
|
1274 |
with col4:
|
1275 |
st.metric("π§Ύ Expense Count", f"{expense_count}")
|
1276 |
|
@@ -1308,7 +1306,7 @@ def main_dashboard():
|
|
1308 |
progress = (category_spending / budget['budget_amount']) * 100 if budget['budget_amount'] > 0 else 0
|
1309 |
st.write(f"**{budget['category']}**")
|
1310 |
st.progress(min(progress/100, 1.0))
|
1311 |
-
st.write(f"
|
1312 |
|
1313 |
# Savings goals progress
|
1314 |
if not st.session_state.savings_goals.empty:
|
@@ -1317,7 +1315,7 @@ def main_dashboard():
|
|
1317 |
progress = (goal['current_amount'] / goal['target_amount']) * 100 if goal['target_amount'] > 0 else 0
|
1318 |
st.write(f"**{goal['goal_name']}**")
|
1319 |
st.progress(min(progress/100, 1.0))
|
1320 |
-
st.write(f"
|
1321 |
|
1322 |
# AI-powered financial health score
|
1323 |
if st.button("π€ Calculate Financial Health Score"):
|
@@ -1334,9 +1332,9 @@ def main_dashboard():
|
|
1334 |
|
1335 |
prompt = f"""
|
1336 |
Calculate a financial health score (0-100) based on:
|
1337 |
-
- Total income/budget:
|
1338 |
-
- Total spending:
|
1339 |
-
- Savings amount:
|
1340 |
- Savings rate: {savings_rate:.1f}%
|
1341 |
- Spending category diversity: {category_count} categories
|
1342 |
|
|
|
|
|
|
|
1 |
# budget_tracker_with_voice_ocr.py
|
2 |
import streamlit as st
|
3 |
import pandas as pd
|
|
|
264 |
break
|
265 |
|
266 |
# Extract numbers for amount using regex
|
267 |
+
amount_pattern = r'(?:$|\$|rs|rupees?|dollars?)\s*(\d+(?:\.\d+)?)|(\d+(?:\.\d+)?)\s*(?:$|\$|rs|rupees?|dollars?)'
|
268 |
matches = re.findall(amount_pattern, text_lower)
|
269 |
if matches:
|
270 |
for match in matches:
|
|
|
290 |
'receipt_image': ['']
|
291 |
})
|
292 |
st.session_state.expenses = pd.concat([st.session_state.expenses, new_expense], ignore_index=True)
|
293 |
+
st.success(f"β
Expense logged: ${amount:.2f} for {category}")
|
294 |
|
295 |
# Check budget alerts
|
296 |
check_budget_alerts(amount, category)
|
|
|
440 |
if amount == 0:
|
441 |
# Extract amount with multiple patterns
|
442 |
amount_patterns = [
|
443 |
+
r'[$$β¬Β£]\s*(\d+(?:\.\d+)?)',
|
444 |
+
r'(\d+(?:\.\d+)?)\s*[$$β¬Β£]',
|
445 |
r'(?:total|amount|paid|grand total).*?(\d+(?:\.\d+)?)',
|
446 |
r'(?:bill|invoice).*?(\d+(?:\.\d+)?)'
|
447 |
]
|
|
|
487 |
'receipt_image': [image_data]
|
488 |
})
|
489 |
st.session_state.expenses = pd.concat([st.session_state.expenses, new_expense], ignore_index=True)
|
490 |
+
st.success(f"β
Receipt processed successfully: ${amount:.2f} for {category}")
|
491 |
|
492 |
# Check budget alerts
|
493 |
check_budget_alerts(amount, category)
|
|
|
523 |
else:
|
524 |
category = st.text_input("Enter custom category")
|
525 |
with col2:
|
526 |
+
budget_amount = st.number_input("Budget Amount ($)", min_value=0.0, step=100.0, value=1000.0)
|
527 |
period = st.selectbox("Period", ["Monthly", "Weekly", "Custom"])
|
528 |
|
529 |
# AI-powered budget recommendations
|
|
|
533 |
try:
|
534 |
# Prepare spending history for LLM
|
535 |
spending_summary = st.session_state.expenses.groupby('category')['amount'].sum().to_dict()
|
536 |
+
spending_text = "\n".join([f"{cat}: ${amt:.2f}" for cat, amt in spending_summary.items()])
|
537 |
|
538 |
prompt = f"""
|
539 |
Based on this user's spending history:
|
|
|
554 |
recommendation = re.findall(r'\d+(?:\.\d+)?', response.content)
|
555 |
if recommendation:
|
556 |
recommended_amount = float(recommendation[0])
|
557 |
+
st.info(f"π€ AI Recommendation: ${recommended_amount:.2f} for {category}")
|
558 |
except:
|
559 |
st.info("π€ AI Recommendation: " + response.content)
|
560 |
|
|
|
576 |
st.session_state.budgets.loc[
|
577 |
st.session_state.budgets['category'] == category, 'period'
|
578 |
] = period
|
579 |
+
st.success(f"π Budget updated: ${budget_amount:.2f} for {category}")
|
580 |
else:
|
581 |
# Add new budget
|
582 |
new_budget = pd.DataFrame({
|
|
|
585 |
'period': [period]
|
586 |
})
|
587 |
st.session_state.budgets = pd.concat([st.session_state.budgets, new_budget], ignore_index=True)
|
588 |
+
st.success(f"β
Budget set: ${budget_amount:.2f} for {category}")
|
589 |
except Exception as e:
|
590 |
st.error(f"β Error setting budget: {str(e)}")
|
591 |
else:
|
|
|
621 |
with col1:
|
622 |
goal_name = st.text_input("Goal Name", placeholder="e.g., Vacation, Emergency Fund")
|
623 |
with col2:
|
624 |
+
target_amount = st.number_input("Target Amount ($)", min_value=0.0, step=1000.0, value=10000.0)
|
625 |
with col3:
|
626 |
target_date = st.date_input("Target Date",
|
627 |
value=datetime.now() + timedelta(days=30))
|
|
|
638 |
|
639 |
prompt = f"""
|
640 |
Based on this financial situation:
|
641 |
+
- Monthly income (budgeted): ${total_income:.2f}
|
642 |
+
- Monthly spending: ${total_spending:.2f}
|
643 |
+
- Current savings: ${current_savings:.2f}
|
644 |
|
645 |
For a savings goal named '{goal_name}', suggest:
|
646 |
1. A realistic target amount
|
|
|
686 |
days_left = (goal['target_date'] - datetime.now().date()).days
|
687 |
st.write(f"**{goal['goal_name']}**")
|
688 |
st.progress(min(progress/100, 1.0))
|
689 |
+
st.write(f"π° ${goal['current_amount']:.2f} / ${goal['target_amount']:.2f} ({progress:.1f}%)")
|
690 |
st.write(f"π
Target Date: {goal['target_date']} ({days_left} days left)")
|
691 |
|
692 |
# Add to current savings
|
|
|
695 |
if st.button(f"β Add to {goal['goal_name']}", key=f"btn_{idx}"):
|
696 |
if add_amount > 0:
|
697 |
st.session_state.savings_goals.at[idx, 'current_amount'] += add_amount
|
698 |
+
st.success(f"β
Added ${add_amount:.2f} to {goal['goal_name']}")
|
699 |
st.rerun()
|
700 |
st.write("---")
|
701 |
except Exception as e:
|
|
|
719 |
st.write("π Uncategorized Expenses:")
|
720 |
for idx, expense in uncategorized.iterrows():
|
721 |
try:
|
722 |
+
st.write(f"π
{expense['date']} | ${expense['amount']:.2f} | {expense['description']}")
|
723 |
predefined_categories = ["Food", "Transport", "Shopping", "Entertainment", "Bills", "Health", "Education", "Other"]
|
724 |
new_category = st.selectbox(f"Re-categorize", predefined_categories,
|
725 |
key=f"cat_{idx}")
|
|
|
775 |
st.subheader("π Summary")
|
776 |
total_spent = filtered_expenses['amount'].sum()
|
777 |
avg_spent = filtered_expenses['amount'].mean()
|
778 |
+
st.metric("Total Spent", f"${total_spent:.2f}")
|
779 |
+
st.metric("Average Expense", f"${avg_spent:.2f}")
|
780 |
|
781 |
# AI-powered spending analysis
|
782 |
if st.button("π€ Analyze Spending Patterns"):
|
|
|
785 |
try:
|
786 |
# Prepare spending data for analysis
|
787 |
category_spending = filtered_expenses.groupby('category')['amount'].sum().to_dict()
|
788 |
+
spending_text = "\n".join([f"{cat}: ${amt:.2f}" for cat, amt in category_spending.items()])
|
789 |
|
790 |
prompt = f"""
|
791 |
Analyze this spending pattern and provide insights:
|
|
|
831 |
]['amount'].sum()
|
832 |
|
833 |
if current_spending > budget_amount:
|
834 |
+
alert_msg = f"π¨ OVERSPENT: {category} - ${current_spending:.2f}/${budget_amount:.2f}"
|
835 |
if alert_msg not in st.session_state.notifications:
|
836 |
st.session_state.notifications.append(alert_msg)
|
837 |
elif current_spending > budget_amount * 0.8: # 80% threshold
|
838 |
+
alert_msg = f"β οΈ WARNING: {category} - ${current_spending:.2f}/${budget_amount:.2f} ({((current_spending/budget_amount)*100):.1f}%)"
|
839 |
if alert_msg not in st.session_state.notifications:
|
840 |
st.session_state.notifications.append(alert_msg)
|
841 |
except Exception as e:
|
|
|
848 |
if llm:
|
849 |
prompt = f"""
|
850 |
For this expense:
|
851 |
+
- Amount: ${expense['amount']:.2f}
|
852 |
- Category: {expense['category']}
|
853 |
- Description: {expense['description']}
|
854 |
|
|
|
893 |
spent = category_spending.iloc[0]['amount']
|
894 |
budget_amount = budget['budget_amount']
|
895 |
if spent > budget_amount:
|
896 |
+
alerts.append(f"π¨ OVERSPENT: {budget['category']} - ${spent:.2f}/${budget_amount:.2f} ({((spent/budget_amount)*100):.1f}%)")
|
897 |
elif spent > budget_amount * 0.8: # 80% threshold
|
898 |
+
alerts.append(f"β οΈ WARNING: {budget['category']} - ${spent:.2f}/${budget_amount:.2f} ({((spent/budget_amount)*100):.1f}%)")
|
899 |
|
900 |
# Display alerts
|
901 |
if alerts:
|
|
|
965 |
]
|
966 |
if not monthly_expenses.empty:
|
967 |
total_spent = monthly_expenses['amount'].sum()
|
968 |
+
st.metric("Total Monthly Spending", f"${total_spent:.2f}")
|
969 |
category_summary = monthly_expenses.groupby('category')['amount'].sum().reset_index()
|
970 |
fig3 = px.bar(category_summary, x='category', y='amount',
|
971 |
title='Monthly Spending by Category')
|
|
|
1006 |
# Prepare data for summary
|
1007 |
total_expenses = st.session_state.expenses['amount'].sum()
|
1008 |
category_spending = st.session_state.expenses.groupby('category')['amount'].sum().to_dict()
|
1009 |
+
spending_text = "\n".join([f"{cat}: ${amt:.2f}" for cat, amt in category_spending.items()])
|
1010 |
|
1011 |
# Get budget data
|
1012 |
total_budget = st.session_state.budgets['budget_amount'].sum()
|
1013 |
+
budget_text = "\n".join([f"{row['category']}: ${row['budget_amount']:.2f}"
|
1014 |
for _, row in st.session_state.budgets.iterrows()])
|
1015 |
|
1016 |
prompt = f"""
|
1017 |
Based on this financial data:
|
1018 |
|
1019 |
+
Total Expenses: ${total_expenses:.2f}
|
1020 |
|
1021 |
Spending by Category:
|
1022 |
{spending_text}
|
|
|
1091 |
try:
|
1092 |
with cols[idx % 3]:
|
1093 |
st.write(f"**π
{receipt['date']}**")
|
1094 |
+
st.write(f"π° ${receipt['amount']:.2f}")
|
1095 |
st.write(f"π·οΈ {receipt['category']}")
|
1096 |
if receipt['receipt_image'].startswith('data:image'):
|
1097 |
# Display base64 image
|
|
|
1105 |
try:
|
1106 |
prompt = f"""
|
1107 |
Analyze this receipt expense:
|
1108 |
+
- Amount: ${receipt['amount']:.2f}
|
1109 |
- Category: {receipt['category']}
|
1110 |
- Date: {receipt['date']}
|
1111 |
|
|
|
1264 |
expense_count = len(st.session_state.expenses)
|
1265 |
|
1266 |
with col1:
|
1267 |
+
st.metric("π° Total Expenses", f"${total_expenses:.2f}")
|
1268 |
with col2:
|
1269 |
+
st.metric("π Total Budget", f"${total_budget:.2f}")
|
1270 |
with col3:
|
1271 |
+
st.metric("π Total Savings", f"${total_savings:.2f}")
|
1272 |
with col4:
|
1273 |
st.metric("π§Ύ Expense Count", f"{expense_count}")
|
1274 |
|
|
|
1306 |
progress = (category_spending / budget['budget_amount']) * 100 if budget['budget_amount'] > 0 else 0
|
1307 |
st.write(f"**{budget['category']}**")
|
1308 |
st.progress(min(progress/100, 1.0))
|
1309 |
+
st.write(f"${category_spending:.2f} / ${budget['budget_amount']:.2f} ({progress:.1f}%)")
|
1310 |
|
1311 |
# Savings goals progress
|
1312 |
if not st.session_state.savings_goals.empty:
|
|
|
1315 |
progress = (goal['current_amount'] / goal['target_amount']) * 100 if goal['target_amount'] > 0 else 0
|
1316 |
st.write(f"**{goal['goal_name']}**")
|
1317 |
st.progress(min(progress/100, 1.0))
|
1318 |
+
st.write(f"${goal['current_amount']:.2f} / ${goal['target_amount']:.2f} ({progress:.1f}%)")
|
1319 |
|
1320 |
# AI-powered financial health score
|
1321 |
if st.button("π€ Calculate Financial Health Score"):
|
|
|
1332 |
|
1333 |
prompt = f"""
|
1334 |
Calculate a financial health score (0-100) based on:
|
1335 |
+
- Total income/budget: ${total_income:.2f}
|
1336 |
+
- Total spending: ${total_spent:.2f}
|
1337 |
+
- Savings amount: ${total_savings:.2f}
|
1338 |
- Savings rate: {savings_rate:.1f}%
|
1339 |
- Spending category diversity: {category_count} categories
|
1340 |
|