From 32ed1e8c27d206a1135822add36c8a68e3caba59 Mon Sep 17 00:00:00 2001 From: Kritika Singh Date: Thu, 31 Oct 2024 04:56:25 +0530 Subject: [PATCH] Added the enhancements --- Personal Finance Tracker/finance_tracker.py | 312 ++++++++++++-------- Python Snippets/language_translator.py | 8 +- pomodoro_history.json | 1 + user_data.json | 1 + 4 files changed, 200 insertions(+), 122 deletions(-) create mode 100644 pomodoro_history.json create mode 100644 user_data.json diff --git a/Personal Finance Tracker/finance_tracker.py b/Personal Finance Tracker/finance_tracker.py index 4326348..fda9d95 100644 --- a/Personal Finance Tracker/finance_tracker.py +++ b/Personal Finance Tracker/finance_tracker.py @@ -3,126 +3,206 @@ import speech_recognition as sr import json import os +import csv +import matplotlib.pyplot as plt +from datetime import datetime -# Initialize TTS engine -engine = pyttsx3.init() -engine.setProperty('rate', 150) - -# File to store expenses and budgets -DATA_FILE = "finance_data.json" - -# Global variables to store expenses and budgets -expenses = {} -budgets = {} - -# Load data from file -def load_data(): - global expenses, budgets - if os.path.exists(DATA_FILE): - try: - with open(DATA_FILE, 'r') as f: - data = json.load(f) - expenses = data.get("expenses", {}) - budgets = data.get("budgets", {}) - except json.JSONDecodeError: - expenses = {} - budgets = {} - print("Warning: Data file is corrupted. Starting fresh.") - -# Save data to file -def save_data(): - with open(DATA_FILE, 'w') as f: - json.dump({"expenses": expenses, "budgets": budgets}, f) - -# Function to convert text to speech asynchronously -async def speak_async(text): - engine.say(text) - engine.runAndWait() - await asyncio.sleep(0.5) - -# Function to get user input through speech recognition -async def voice_to_text_async(): - recognizer = sr.Recognizer() - await asyncio.sleep(0.5) - with sr.Microphone() as source: - print("Listening for your command...") +# Class to encapsulate finance data and operations +class FinanceAssistant: + DATA_FILE = "finance_data.json" + + def __init__(self): + self.expenses = {} + self.budgets = {} + self.recurring_expenses = {} + self.engine = pyttsx3.init() + self.engine.setProperty('rate', 150) + self.load_data() + + def load_data(self): + """Loads data from the JSON file if it exists.""" + if os.path.exists(self.DATA_FILE): + try: + with open(self.DATA_FILE, 'r') as f: + data = json.load(f) + self.expenses = data.get("expenses", {}) + self.budgets = data.get("budgets", {}) + self.recurring_expenses = data.get("recurring_expenses", {}) + except (json.JSONDecodeError, IOError): + print("Warning: Data file is corrupted or unreadable. Starting with fresh data.") + + def save_data(self): + """Saves the current state of expenses, budgets, and recurring expenses to the JSON file.""" try: - audio = recognizer.listen(source, timeout=10) - command = recognizer.recognize_google(audio) - return command.lower() - except sr.UnknownValueError: - await speak_async("I didn't catch that. Could you please repeat?") - return None - except sr.RequestError: - await speak_async("The speech recognition service is unavailable at the moment.") + with open(self.DATA_FILE, 'w') as f: + json.dump({"expenses": self.expenses, "budgets": self.budgets, "recurring_expenses": self.recurring_expenses}, f) + except IOError: + print("Warning: Could not save data to file.") + + def speak(self, text): + """Synchronously convert text to speech.""" + self.engine.say(text) + self.engine.runAndWait() + + async def speak_async(self, text): + """Async wrapper for speak to maintain code consistency.""" + await asyncio.to_thread(self.speak, text) + + async def recognize_speech(self): + """Converts voice input to text asynchronously.""" + recognizer = sr.Recognizer() + with sr.Microphone() as source: + print("Listening for your command...") + try: + audio = recognizer.listen(source, timeout=10) + command = recognizer.recognize_google(audio) + return command.lower() + except sr.UnknownValueError: + await self.speak_async("I didn't catch that. Could you please repeat?") + except sr.RequestError: + await self.speak_async("The speech recognition service is unavailable.") + except Exception as e: + print(f"Error in speech recognition: {e}") return None -# Function to log expenses -async def log_expense(category, amount): - if category not in expenses: - expenses[category] = [] - expenses[category].append(amount) - save_data() # Save data after logging - await speak_async(f"Logged {amount} dollars for {category}.") - -# Function to set budget -async def set_budget(category, amount): - budgets[category] = amount - save_data() # Save data after setting budget - await speak_async(f"Set {category} budget to {amount} dollars.") - -# Function to check budgets -async def check_budget(): - for category, budget in budgets.items(): - total_expense = sum(expenses.get(category, [])) - remaining = budget - total_expense - if remaining < 0: - await speak_async(f"You have exceeded your budget for {category} by {-remaining} dollars.") - else: - await speak_async(f"You have {remaining} dollars left in your budget for {category}.") - -# Function to provide help -async def provide_help(): - await speak_async("You can log expenses by saying 'Log expense [category] [amount]', set budgets by saying 'Set budget [category] [amount]', and check budgets by saying 'Check budget'. To exit, say 'exit'.") - -# Main function for the assistant -async def main(): - load_data() # Load existing data at startup - await speak_async("Welcome to your personal finance assistant! How can I assist you today?") - - while True: - command = await voice_to_text_async() + async def log_expense(self, category, amount, date=None): + """Logs an expense under a specific category.""" + date = date or datetime.now().strftime("%Y-%m-%d") + self.expenses.setdefault(category, []).append({"amount": amount, "date": date}) + self.save_data() + await self.speak_async(f"Logged {amount} dollars for {category}.") + + async def set_budget(self, category, amount): + """Sets a budget for a specific category.""" + self.budgets[category] = amount + self.save_data() + await self.speak_async(f"Set {category} budget to {amount} dollars.") + + async def check_budget(self): + """Checks remaining budgets against expenses and provides alerts if limits are exceeded.""" + for category, budget in self.budgets.items(): + total_expense = sum(expense["amount"] for expense in self.expenses.get(category, [])) + remaining = budget - total_expense + if remaining < 0: + await self.speak_async(f"You have exceeded your budget for {category} by {-remaining} dollars.") + elif remaining < budget * 0.1: + await self.speak_async(f"Warning: You are approaching your budget limit for {category}.") + else: + await self.speak_async(f"You have {remaining} dollars left in your budget for {category}.") + + async def manage_recurring_expenses(self, category, amount): + """Logs and manages recurring expenses for subscriptions.""" + self.recurring_expenses[category] = amount + self.save_data() + await self.speak_async(f"Recurring expense of {amount} dollars added for {category}.") + + def generate_expense_summary(self): + """Generates a report summarizing expenses by category.""" + summary = {category: sum(expense["amount"] for expense in expenses) for category, expenses in self.expenses.items()} + for category, total in summary.items(): + print(f"{category}: ${total:.2f}") + return summary + + async def generate_monthly_report(self): + """Generates a monthly report comparing expenses and budgets.""" + monthly_summary = self.generate_expense_summary() + for category, total_expense in monthly_summary.items(): + budget = self.budgets.get(category, 0) + await self.speak_async(f"For {category}, you spent {total_expense} out of {budget} dollars.") + + def export_data_to_csv(self): + """Exports the expense summary to a CSV file.""" + with open("expense_summary.csv", "w", newline='') as file: + writer = csv.writer(file) + writer.writerow(["Category", "Date", "Amount"]) + for category, expenses in self.expenses.items(): + for expense in expenses: + writer.writerow([category, expense["date"], expense["amount"]]) + + def generate_charts(self): + """Generates charts to visualize spending by category.""" + summary = self.generate_expense_summary() + categories = list(summary.keys()) + expenses = list(summary.values()) + + plt.figure(figsize=(8, 6)) + plt.pie(expenses, labels=categories, autopct='%1.1f%%', startangle=140) + plt.title("Spending by Category") + plt.show() + + def currency_conversion(self, amount, from_currency, to_currency, rate): + """Converts amount from one currency to another given an exchange rate.""" + converted_amount = amount * rate + print(f"{amount} {from_currency} is approximately {converted_amount:.2f} {to_currency}.") + return converted_amount + + async def detailed_expense_history(self): + """Provides detailed history of expenses for each category.""" + for category, expenses in self.expenses.items(): + await self.speak_async(f"Expenses for {category}:") + for expense in expenses: + await self.speak_async(f"On {expense['date']}, spent {expense['amount']} dollars.") + + async def provide_help(self): + """Provides help instructions to the user.""" + await self.speak_async("You can log expenses, set budgets, manage recurring expenses, check budgets, view expense history, and generate reports. To exit, say 'exit'.") + + async def parse_command(self, command): + """Parses the user's command and calls appropriate methods.""" + if "log expense" in command: + try: + _, _, category, amount_str = command.split(maxsplit=3) + amount = float(amount_str) + await self.log_expense(category, amount) + except (ValueError, IndexError): + await self.speak_async("Please specify a valid category and amount.") + + elif "set budget" in command: + try: + _, _, category, amount_str = command.split(maxsplit=3) + amount = float(amount_str) + await self.set_budget(category, amount) + except (ValueError, IndexError): + await self.speak_async("Please specify a valid category and budget amount.") + + elif "check budget" in command: + await self.check_budget() + + elif "recurring expense" in command: + _, _, category, amount_str = command.split(maxsplit=3) + amount = float(amount_str) + await self.manage_recurring_expenses(category, amount) + + elif "generate report" in command: + await self.generate_monthly_report() + + elif "export data" in command: + self.export_data_to_csv() + await self.speak_async("Data exported to CSV.") + + elif "expense history" in command: + await self.detailed_expense_history() + + elif "help" in command: + await self.provide_help() + + elif "exit" in command: + await self.speak_async("Goodbye!") + return False + + return True + + async def run(self): + """Main loop for voice command processing.""" + await self.speak_async("Welcome to your personal finance assistant! How can I assist you today?") - if command: - if "log expense" in command: - parts = command.split() - if len(parts) == 4 and parts[1] == "expense": - category = parts[2] - try: - amount = float(parts[3]) - await log_expense(category, amount) - except ValueError: - await speak_async("Please provide a valid amount.") - - elif "set budget" in command: - parts = command.split() - if len(parts) == 4 and parts[1] == "budget": - category = parts[2] - try: - amount = float(parts[3]) - await set_budget(category, amount) - except ValueError: - await speak_async("Please provide a valid budget amount.") - - elif "check budget" in command: - await check_budget() - - elif "help" in command: - await provide_help() - - elif "exit" in command: - await speak_async("Goodbye!") - break + while True: + command = await self.recognize_speech() + if command: + keep_running = await self.parse_command(command) + if not keep_running: + break if __name__ == "__main__": - asyncio.run(main()) + assistant = FinanceAssistant() + asyncio.run(assistant.run()) diff --git a/Python Snippets/language_translator.py b/Python Snippets/language_translator.py index 61c8e5a..be59075 100644 --- a/Python Snippets/language_translator.py +++ b/Python Snippets/language_translator.py @@ -1,5 +1,5 @@ -ion , translate and pyttsx3 libraries +# ion , translate and pyttsx3 libraries #make sure there are no microphone or hardware issues import speech_recognition as sr @@ -22,11 +22,7 @@ def translate_text(text, target_language): def speak(text): engine.say(text) engine.runAndWait() - - - - - + # Function to capture voice commands and convert speech to text def voice_to_text(): diff --git a/pomodoro_history.json b/pomodoro_history.json new file mode 100644 index 0000000..d0d0534 --- /dev/null +++ b/pomodoro_history.json @@ -0,0 +1 @@ +[{"task": "ee", "type": "work", "cycle": 1}] \ No newline at end of file diff --git a/user_data.json b/user_data.json new file mode 100644 index 0000000..b366f41 --- /dev/null +++ b/user_data.json @@ -0,0 +1 @@ +{"Krits": "testingfile"} \ No newline at end of file