Код: Выделить всё
from json import JSONDecodeError
import json
#Function to add an expense to the list of expenses
def add_expense(expenses, category, description, amount):
expenses.append({"category": category, "description": description, "amount": amount})
print(f"Added expense: {description}. Amount {amount}$")
# Fucntion to allocate savings from the budget
def allocate_savings(budget, percentage, total_savings):
if percentage < 0 or percentage > 100:
raise ValueError("Please enter a value between 0 and 100.")
else:
new_savings = (percentage / 100) * budget
total_savings += new_savings
budget -= new_savings
print(f"{percentage}% allocated for savings: {new_savings}$. Total Savings: {total_savings}$ ")
return budget, total_savings
# Function to get the total expenses
def get_total_expenses(expenses):
return sum(expense["amount"] for expense in expenses)
# Function to get the balance after expenses
def get_balance(budget, expenses):
return budget - get_total_expenses(expenses)
# Function to show budget details
def show_budget_details(initial_budget, budget, expenses, filepath, total_savings):
total_spent = get_total_expenses(expenses)
remaining_budget = get_balance(budget, expenses)
print(f"Initial Budget: {initial_budget}$")
print(f"Budget after savings: {budget}$")
print("Expenses: ")
for expense in expenses:
category = expense.get('category')
description = expense.get('description')
amount = expense.get('amount')
print(f"{category}: {amount}$ in {description}")
print(f"Total Spent: {total_spent}$")
print(f"Remaining Budget: {remaining_budget}$")
save_budget_details(filepath, initial_budget, budget, expenses, total_savings, remaining_budget, total_spent)
#Function to load budget data from a file
def load_budget_data(filepath):
try:
with open(filepath, 'r') as file:
data = json.load(file)
# Filter only dictionary sections?
sections = [section for section in data if isinstance(section, dict)]
if sections:
last_section = sections[-1]
else:
last_section = {}
initial_budget = last_section.get("Initial Budget", 0) # Ensure consistent key naming
formatted_expenses = last_section.get("Expenses", []) # Load expenses as a list of dictionatries
expenses = [{"category": expense["category"], "description": expense["description"],
"amount": expense["amount"]} for expense in formatted_expenses]
total_expenses = get_total_expenses(expenses)
remaining_budget = last_section.get("Remaining Budget", initial_budget - total_expenses)
total_savings = last_section.get("Total Savings", 0) # Initializing totoal_savings
return initial_budget, remaining_budget, expenses, total_savings, total_expenses
except (FileNotFoundError, JSONDecodeError):
return 0, 0, [], 0, 0 # Return default value if the file doesnt exist or is empty/curroptede
# Function to save budget details to a file
def save_budget_details(filepath, initial_budget, budget, expenses, total_savings, remaining_budget, total_spent):
# convert expenses to a list of dictionaries
formatted_expenses = [{"category": expense["category"], "description": expense["description"],
"amount": expense["amount"]} for expense in expenses]
data = {
'Initial Budget': initial_budget,
'Budget After Savings': budget,
'Expenses': formatted_expenses,
'Total Savings': total_savings,
'Total Spent': total_spent,
'Remaining Budget': remaining_budget
}
try:
with open(filepath, 'r+') as file:
existing_data = json.load(file)
if isinstance(existing_data, list):
if existing_data and isinstance(existing_data[-1], dict):
existing_data[-1] = data
else:
existing_data.append(data)
else:
existing_data = [data]
file.seek(0)
json.dump(existing_data, file, indent=4)
file.truncate() # Ensure the file is truncated to remov
except (FileNotFoundError, JSONDecodeError):
with open(filepath, 'w') as file:
json.dump([data], file, indent=4)
print("Budget details saved to file.")
# Function to append an expense
def append_expense(expenses, filepath, expense, initial_budget):
expenses.append(expense)
total_spent = get_total_expenses(expenses)
remaining_budget = get_balance(initial_budget, expenses)
try:
with open(filepath, 'r+') as file:
data = json.load(file)
if isinstance(data, list) and data and isinstance(data[-1], dict):
last_section = data[-1]
if "Expenses" in last_section:
last_section["Expenses"].append(expense)
last_section["Total Spent"] = total_spent
last_section["Remaining Budget"] = remaining_budget
else:
print("No 'Expenses' key in the last section") # debug print
file.seek(0)
json.dump(data, file, indent=4)
file.truncate() # Ensure the file is truncated to remove any remaining data
else:
print("Invalid data struucture in file") # Debug print
except (FileNotFoundError, JSONDecodeError) as e:
print(f"Error reading file: {e}") # Debug print
pass
def add_bill(expenses, filepath, initial_budget):
while True:
description = input("\nEnter bill description: ")
try:
amount = float(input("Enter bill amount: "))
expense = {"category": "Bills", "description": description, "amount": amount}
append_expense(expense, filepath, expenses, initial_budget)
print("Expense added successfully!")
break
except:
print("Please enter a valid numeric amount.")
def add_necessary_expense(expenses, filepath, initial_budget):
while True:
description = input("Enter necessary expense description: ")
try:
amount = float(input("Enter amount: "))
expense = {"category": "Necessities", "description": description, "amount": amount}
append_expense(expenses, filepath, expense, initial_budget)
print("Expense added successfully!")
break
except ValueError:
print("Please enter a valid numeric amount.")
def add_luxury_expense(expenses, filepath, initial_budget):
while True:
description = input("\nEnter luxury expense description: ")
try:
amount = float(input("Enter amount: "))
expenses = {"category": "Luxuries", "description": description, "amount": amount}
append_expense(expenses, filepath, expense, initial_budget)
print("Expense added succesfully!")
break
except ValueError:
print("Please enter a valid numeric amount.")
def add_new_budget(filepath, remaining_budget, total_savings):
# get the new budget from the user
budget = float(input("Enter your budget: "))
# Calculate new initital budget
new_initial_budget = remaining_budget + budget
data = {
'Initial Budget': new_initial_budget,
'Budget After Savings': new_initial_budget,
'Expenses': [],
'Total Savings': total_savings,
'Total Spent': 0,
'Remaining Budget': new_initial_budget
}
try:
with open(filepath, 'r+') as file:
# Load existing data from file
try:
file_data = json.load(file)
except JSONDecodeError:
file_data = []
# Calculate total savings from all previous sections
previous_total_savings = sum(section.get("Total Savings", 0) for section in file_data if isinstance(section, dict))
# Define the Divider
divider = {"divider": "=" * 50 + "\nNew Section\n" + "=" * 50}
# Add divider if file_data is not empty
if file_data:
file_data.append(divider)
# update data with previous total savings
data['Total Savings'] += previous_total_savings
# Save the updated budget details to the file
file_data.append(data)
file.seek(0)
json.dump(file_data, file, indent=4)
file.truncate() # Ensure the file is truncated to remove any remaining data
print("New budget added successfully")
except (FileNotFoundError, JSONDecodeError):
with open(filepath, 'w') as file:
json.dump([data], file, indent=4)
return new_initial_budget, new_initial_budget, [], total_savings + data['Total Savings'], 0
# Function to handle the main application logic
def main():
print("\nWelcome to the Budget App")
filepath = 'budget_data_v75.json' #Define the path of your JASON file
initial_budget, budget, expenses, total_savings, total_expenses = load_budget_data(filepath)
menu_shown = False
while True:
if not menu_shown:
print("\nWhat would you like to do?")
print("1. Add a new Budget")
print("2. Allocate Savings %")
print("3. Add expenses")
print("4. Show budget details")
print("5. Exit")
menu_shown = True
choice = input("\nEnter your choice (1/2/3/4/5): ")
if choice == "1":
initial_budget, budget, expenses, total_savings, total_expenses = add_new_budget(filepath, budget, total_savings)
elif choice == "2":
if budget
Подробнее здесь: [url]https://stackoverflow.com/questions/78707814/my-budgeting-app-is-giving-me-an-infinite-loop-in-python-is-there-a-way-to-reso[/url]