Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/api/budget_suggestion_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from flask import Blueprint, jsonify, request
from src.features.budget_suggestion import BudgetSuggestion
import pandas as pd

budget_api = Blueprint('budget_api', __name__)

@budget_api.route('/suggestions', methods=['POST'])
def get_budget_suggestions():
try:
data = request.get_json()
spending_data = pd.DataFrame(data['spending_data'])
months = data.get('months', 6)
budget_suggestion = BudgetSuggestion(spending_data, months)
suggestions = budget_suggestion.get_suggestions()
return jsonify({'suggestions': [{'category': s[0], 'lower_bound': s[1], 'upper_bound': s[2]} for s in suggestions]}), 200
except Exception as e:
return jsonify({'error': str(e)}), 400

# In your app initialization code
# from src.api.budget_suggestion_api import budget_api
# app.register_blueprint(budget_api, url_prefix='/api')
37 changes: 37 additions & 0 deletions src/app/src/components/BudgetSuggestions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { useState } from 'react';
import axios from 'axios';

const BudgetSuggestions: React.FC = () => {
const [suggestions, setSuggestions] = useState<any[]>([]);
const [error, setError] = useState<string>('');

const fetchBudgetSuggestions = async () => {
try {
const response = await axios.post('/api/suggestions', {
spending_data: {
Food: [200, 220, 250, 230, 240, 210],
Transport: [100, 120, 110, 130, 140, 125],
Entertainment: [50, 60, 55, 65, 70, 60]
},
months: 6
});
setSuggestions(response.data.suggestions);
} catch (err) {
setError('Failed to fetch suggestions');
}
};

return (
<div>
<button onClick={fetchBudgetSuggestions}>Get Budget Suggestions</button>
{error && <div>{error}</div>}
<ul>
{suggestions.map((suggestion, index) => (
<li key={index}>{suggestion.category}: ${suggestion.lower_bound.toFixed(2)} - ${suggestion.upper_bound.toFixed(2)}</li>
))}
</ul>
</div>
);
};

export default BudgetSuggestions;
43 changes: 43 additions & 0 deletions src/features/budget_suggestion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pandas as pd
import numpy as np
from typing import List, Tuple

class BudgetSuggestion:
def __init__(self, spending_data: pd.DataFrame, months: int = 6):
self.spending_data = spending_data
self.months = months
self.suggestions = []

def analyze_spending(self) -> pd.DataFrame:
# Calculate average spending and confidence interval
recent_data = self.spending_data.tail(self.months)
avg_spending = recent_data.mean(axis=0)
std_dev = recent_data.std(axis=0)
confidence_interval = 1.96 * std_dev / np.sqrt(self.months)
return avg_spending, confidence_interval

def generate_suggestion(self) -> List[Tuple[str, float, float]]:
avg_spending, confidence_interval = self.analyze_spending()
for category in avg_spending.index:
lower_bound = avg_spending[category] - confidence_interval[category]
upper_bound = avg_spending[category] + confidence_interval[category]
self.suggestions.append((category, lower_bound, upper_bound))
return self.suggestions

def get_suggestions(self) -> List[Tuple[str, float, float]]:
if not self.suggestions:
self.generate_suggestion()
return self.suggestions

# Example Usage
if __name__ == '__main__':
# Example spending data for the last 6 months
data = {'Food': [200, 220, 250, 230, 240, 210],
'Transport': [100, 120, 110, 130, 140, 125],
'Entertainment': [50, 60, 55, 65, 70, 60]}
df = pd.DataFrame(data)

budget = BudgetSuggestion(df)
suggestions = budget.get_suggestions()
for suggestion in suggestions:
print(f'Category: {suggestion[0]}, Suggested Budget: ${suggestion[1]:.2f} - ${suggestion[2]:.2f}')