I am trying to build a small project to track personal expenses using python programming.
This will be a non-GUI program, since I am very new to programming. The main menu would have options : user registration, user login, Add Income or Expense, Check Balance, View Reports. When the balance is close to a preset budget threshold or when exceeded users should be alerted like a message or something. Reports could be something like monthly, yearly income/expense reports and view expenses by category.
| from collections import namedtuple, OrderedDict | |
| from .data import (split_income_expenses, extract_transactions_by_label, filter_transactions_period, | |
| sort_transactions, period_to_months) | |
| import datetime | |
| from monthdelta import monthdelta | |
| class Budget(namedtuple('Budget', ['month', 'transactions', 'income_transactions', 'planned_expenses_transactions', | |
| 'expenses_transactions', 'real_balance', 'balance', 'income', 'planned_expenses', 'expenses', | |
| 'savings', 'savings_goal', 'expected_real_balance', 'expected_balance', 'expected_income', | |
| 'expected_planned_expenses', 'expected_savings', 'expected_remaining'])): | |
| @property | |
| def undetected_planned_expenses(self): | |
| return self.expected_planned_expenses - self.planned_expenses | |
| @property | |
| def all_expenses(self): | |
| current = datetime.date.today().replace(day=1) | |
| if self.month >= current: | |
| return self.expenses + self.expected_planned_expenses | |
| return self.expenses + self.planned_expenses | |
| @property | |
| def all_expected_expenses(self): | |
| return self.expenses + self.expected_planned_expenses | |
| def to_dict(self, with_transactions=True): | |
| dct = { | |
| "month": self.month, | |
| "real_balance": self.real_balance, | |
| "balance": self.balance, | |
| "income": self.income, | |
| "planned_expenses": self.planned_expenses, | |
| "expenses": self.expenses, | |
| "savings": self.savings, | |
| "savings_goal": self.savings_goal, | |
| "expected_real_balance": self.expected_real_balance, | |
| "expected_balance": self.expected_balance, | |
| "expected_income": self.expected_income, | |
| "expected_planned_expenses": self.expected_planned_expenses, | |
| "expected_savings": self.expected_savings, | |
| "expected_remaining": self.expected_remaining | |
| } | |
| if with_transactions: | |
| dct.update({ | |
| "transactions": self.transactions, | |
| "income_transactions": self.income_transactions, | |
| "planned_expenses_transactions": self.planned_expenses_transactions, | |
| "expenses_transactions": self.expenses_transactions | |
| }) | |
| return dct | |
| class BudgetList(list): | |
| def _aggregate_transactions(self, key): | |
| tx = [] | |
| for budget in self: | |
| tx.extend(getattr(budget, key)) | |
| return tx | |
| def _sum(self, key, real=False): | |
| total = 0 | |
| current = datetime.date.today().replace(day=1) | |
| for budget in self: | |
| if not real and budget.month == current and not key.startswith('expected_') and hasattr(budget, 'expected_%s' % key): | |
| total += getattr(budget, 'expected_%s' % key) | |
| elif real or budget.month < current or key.startswith('expected_'): | |
| total += getattr(budget, key) | |
| return total | |
| @property | |
| def transactions(self): | |
| return self._aggregate_transactions('transactions') | |
| @property | |
| def income_transactions(self): | |
| return self._aggregate_transactions('income_transactions') | |
| @property | |
| def planned_expenses_transactions(self): | |
| return self._aggregate_transactions('planned_expenses_transactions') | |
| @property | |
| def expenses_transactions(self): | |
| return self._aggregate_transactions('expenses_transactions') | |
| @property | |
| def real_balance(self): | |
| return self._sum('real_balance') | |
| @property | |
| def real_real_balance(self): | |
| return self._sum('real_balance', real=True) | |
| @property | |
| def balance(self): | |
| return self._sum('balance') | |
| @property | |
| def expected_income(self): | |
| return self._sum('expected_income') | |
| @property | |
| def income(self): | |
| return self._sum('income') | |
| @property | |
| def real_income(self): | |
| return self._sum('income', real=True) | |
| @property | |
| def expected_planned_expenses(self): | |
| return self._sum('expected_planned_expenses') | |
| @property | |
| def planned_expenses(self): | |
| return self._sum('planned_expenses') | |
| @property | |
| def real_planned_expenses(self): | |
| return self._sum('planned_expenses', real=True) | |
| @property | |
| def undetected_planned_expenses(self): | |
| return self._sum('undetected_planned_expenses') | |
| @property | |
| def expenses(self): | |
| return self._sum('expenses') | |
| @property | |
| def all_expenses(self): | |
| return self.expenses + self.planned_expenses | |
| @property | |
| def all_real_expenses(self): | |
| return self.expenses + self.real_planned_expenses | |
| @property | |
| def all_expected_expenses(self): | |
| return self.expenses + self.expected_planned_expenses | |
| @property | |
| def savings(self): | |
| return self._sum('savings') | |
| @property | |
| def savings_goal(self): | |
| return self._sum('savings_goal') | |
| @property | |
| def savings_balance(self): | |
| if datetime.date.today().month == 1: | |
| return 0 | |
| return self.savings - self.savings_goal | |
| @property | |
| def adjusted_savings_goal(self): | |
| if not self.current: | |
| return 0 | |
| balance = self.savings_balance | |
| if balance < 0: | |
| remaining_months = 12 - datetime.date.today().month + 1 | |
| return self.current.savings_goal + abs(balance) / remaining_months | |
| return self.current.savings_goal | |
| def get_from_date(self, date): | |
| date = date.replace(day=1) | |
| for budget in self: | |
| if budget.month == date: | |
| return budget | |
| @property | |
| def current(self): | |
| return self.get_from_date(datetime.date.today()) | |
| class IncomeSource(namedtuple('IncomeSource', ['label', 'amount', 'match', 'from_date', 'to_date'])): | |
| @classmethod | |
| def from_dict(cls, dct): | |
| from_date = datetime.datetime.strptime(dct['from_date'], '%Y-%m-%d').date() if dct.get('from_date') else None | |
| to_date = datetime.datetime.strptime(dct['to_date'], '%Y-%m-%d').date() if dct.get('to_date') else None | |
| return cls(label=dct['label'], amount=dct['amount'], match=dct.get('match'), | |
| from_date=from_date, to_date=to_date) | |
| def to_dict(self): | |
| return { | |
| "label": self.label, | |
| "amount": self.amount, | |
| "match": self.match, | |
| "from_date": self.from_date.isoformat() if self.from_date else None, | |
| "to_date": self.to_date.isoformat() if self.to_date else None | |
| } | |
| class PlannedExpense(namedtuple('PlannedExpense', ['label', 'amount', 'recurrence', 'match', 'from_date', 'to_date'])): | |
| WEEKLY = 0.25 | |
| MONTHLY = 1 | |
| YEARLY = 12 | |
| @classmethod | |
| def from_dict(cls, dct): | |
| recurrence = dct.get('recurrence', cls.MONTHLY) | |
| if isinstance(recurrence, (str, unicode)): | |
| recurrence = getattr(cls, recurrence.upper(), 1) | |
| from_date = datetime.datetime.strptime(dct['from_date'], '%Y-%m-%d').date() if dct.get('from_date') else None | |
| to_date = datetime.datetime.strptime(dct['to_date'], '%Y-%m-%d').date() if dct.get('to_date') else None | |
| return cls(label=dct['label'], amount=dct['amount'], recurrence=recurrence, | |
| match=dct.get('match'), from_date=from_date, to_date=to_date) | |
| @property | |
| def amount_per_month(self): | |
| return self.amount / self.recurrence | |
| @property | |
| def recurrence_label(self): | |
| return dict([ | |
| (0.25, "WEEKLY"), | |
| (1, "MONTHLY"), | |
| (12, "YEARLY") | |
| ]).get(self.recurrence, self.recurrence) | |
| def to_dict(self): | |
| return { | |
| "label": self.label, | |
| "amount": self.amount, | |
| "recurrence": self.recurrence_label, | |
| "match": self.match, | |
| "from_date": self.from_date.isoformat() if self.from_date else None, | |
| "to_date": self.to_date.isoformat() if self.to_date else None | |
| } | |
| class BudgetGoal(namedtuple('BudgetGoal', ['label', 'amount'])): | |
| @classmethod | |
| def from_dict(cls, dct): | |
| return cls(label=dct['label'], amount=dct.get('amount')) | |
| @property | |
| def savings_per_month(self): | |
| if not self.amount: | |
| return 0 | |
| return self.amount / 12 | |
| def to_dict(self): | |
| return { | |
| "label": self.label, | |
| "amount": self.amount | |
| } | |
| class ComputedBudgetGoal(namedtuple('ComputedBudgetGoal', ['label', 'target', 'saved', 'used'])): | |
| @classmethod | |
| def from_savings_goal(cls, goal, **kwargs): | |
| return cls(label=goal.label, target=goal.amount or 0, **kwargs) | |
| @property | |
| def completed_amount(self): | |
| return min(self.saved + self.used, self.target or 0) | |
| @property | |
| def completed_pct(self): | |
| if not self.target: | |
| return 0 | |
| return round(self.completed_amount * 100 / self.target, 0) | |
| @property | |
| def remaining(self): | |
| if not self.target: | |
| return 0 | |
| return max(self.target - self.completed_amount, 0) | |
| @property | |
| def remaining_pct(self): | |
| if not self.target: | |
| return 0 | |
| return round(self.remaining * 100 / self.target, 0) | |
| @property | |
| def used_pct(self): | |
| if not self.target: | |
| return 0 | |
| return round(self.used * 100 / self.target, 0) | |
| @property | |
| def saved_pct(self): | |
| if not self.target: | |
| return 0 | |
| return round(self.saved * 100 / self.target, 0) | |
| @property | |
| def savings_per_month(self): | |
| if not self.target: | |
| return 0 | |
| return min(self.target / 12, self.remaining) | |
| def to_str(self, famount): | |
| return "%s: %s / %s (%s%%) [used=%s saved=%s remaining=%s]" % ( | |
| self.label, famount(self.completed_amount), famount(self.target), | |
| self.completed_pct, famount(self.used), famount(self.saved), | |
| famount(self.remaining)) | |
| def compute_budget_goals(budgets, budget_goals, debug=False): | |
| # TODO: reopen completed budget if we need to take from savings | |
| def _debug(message): | |
| if debug: | |
| print message | |
| _debug('STARTING COMPUTING OF GOALS') | |
| if not budget_goals: | |
| _debug('No budget goals!') | |
| return [], 0 | |
| used = {g.label: 0 for g in budget_goals} | |
| saved = dict(used) | |
| remaining_goals = [g.label for g in budget_goals if g.amount] | |
| budget_goals = {g.label: g for g in budget_goals} | |
| current_month = datetime.datetime.now().replace(day=1).date() | |
| total_savings = 0 | |
| savings = 0 | |
| # for each months | |
| for budget in budgets: | |
| if budget.month > current_month: | |
| # only past months | |
| break | |
| savings = budget.savings if budget.month < current_month else budget.expected_savings | |
| _debug('%s = %s (before=%s)' % (budget.month.isoformat(), savings, total_savings)) | |
| # computing the amount used from each goals based on the marked transactions | |
| for tx in budget.transactions: | |
| if tx.goal and tx.goal in used and tx.amount < 0: | |
| used[tx.goal] += abs(tx.amount) | |
| if budget_goals[tx.goal].amount: | |
| _debug(' > Using %s from %s' % (abs(tx.amount), tx.goal)) | |
| if tx.goal not in remaining_goals: | |
| savings += abs(tx.amount) | |
| _debug(' + Goal already completed, giving %s to savings' % abs(tx.amount)) | |
| if savings < 0 and total_savings <= 0: | |
| # we used money from our savings this month and there is no savings left already (...) | |
| total_savings += savings | |
| continue | |
| if total_savings < 0: | |
| # we have some savings this month, but we had a negative balance until now | |
| _debug(' - Using %s from new savings to pay off balance (remaining=%s)' % (abs(total_savings), total_savings + savings)) | |
| total_savings += savings | |
| if total_savings < 0: | |
| continue | |
| savings = total_savings | |
| else: | |
| total_savings += savings | |
| # we use a while loop because if some goal completes during the loop | |
| # it may have some letfover savings that we will dispatch amongst other goals | |
| while savings != 0 and remaining_goals: | |
| savings_per_goal = savings / len(remaining_goals) | |
| savings = 0 | |
| for goal in filter(lambda g: g.amount and g.label in remaining_goals, budget_goals.values()): | |
| target = goal.amount | |
| new_save = max(saved[goal.label] + savings_per_goal, 0) | |
| completed = used[goal.label] + saved[goal.label] | |
| new_completed = max(completed + savings_per_goal, 0) | |
| if new_completed >= target: | |
| give_back = new_completed - target | |
| savings += give_back | |
| new_save = min(new_save - give_back, target) | |
| _debug(' + Giving %s to %s (saved=%s, used=%s remaining=COMPLETED!, leftover=%s)' % ( | |
| new_save - saved[goal.label], goal.label, new_save, used[goal.label], give_back)) | |
| saved[goal.label] = new_save | |
| remaining_goals.remove(goal.label) | |
| elif new_completed < completed: | |
| take_back = saved[goal.label] - new_save | |
| saved[goal.label] = new_save | |
| _debug(' - Taking %s from %s (saved=%s, used=%s, remaining=%s)' % ( | |
| take_back, goal.label, new_save, used[goal.label], target - new_completed)) | |
| else: | |
| saved[goal.label] = new_save | |
| _debug(' + Giving %s to %s (saved=%s, used=%s, remaining=%s)' % ( | |
| new_completed - completed, goal.label, new_save, used[goal.label], target - new_completed)) | |
| if total_savings < 0: | |
| _debug(' ! Not enough savings to cover this month (remaining=%s)' % total_savings) | |
| if not remaining_goals: | |
| break | |
| savings_after_goals = max(total_savings - sum(saved.values()), 0) | |
| _debug('END COMPUTING OF GOALS (savings=%s, after goals=%s)' % (total_savings, savings_after_goals)) | |
| computed = [] | |
| for goal in budget_goals.values(): | |
| computed.append(ComputedBudgetGoal.from_savings_goal(goal, | |
| saved=saved[goal.label], used=used[goal.label])) | |
| return computed, savings_after_goals | |
| def budgetize(transactions, start_date, end_date, *args, **kwargs): | |
| budgets = BudgetList() | |
| for date in period_to_months(start_date, end_date): | |
| budgets.append(budgetize_month(transactions, date, *args, **kwargs)) | |
| return budgets | |
| def budgetize_month(transactions, date, income_sources=None, planned_expenses=None, budget_goals=None, income_delay=0): | |
| start_date = date.replace(day=1) | |
| end_date = start_date + monthdelta(1) | |
| if income_delay: | |
| income_transactions, _ = split_income_expenses(filter_transactions_period( | |
| transactions, start_date + datetime.timedelta(days=income_delay), end_date + datetime.timedelta(days=income_delay))) | |
| _, expenses_transactions = split_income_expenses(filter_transactions_period(transactions, start_date, end_date)) | |
| transactions = sort_transactions(income_transactions + expenses_transactions) | |
| else: | |
| transactions = sort_transactions(filter_transactions_period(transactions, start_date, end_date)) | |
| income_transactions, expenses_transactions = split_income_expenses(transactions) | |
| expected_income = 0 | |
| if income_sources: | |
| income_sources = filter_period(income_sources, start_date, end_date) | |
| expected_income = sum([src.amount for src in income_sources]) | |
| planned_expenses_transactions = [] | |
| expected_planned_expenses = 0 | |
| if planned_expenses: | |
| planned_expenses = filter_period(planned_expenses, start_date, end_date) | |
| planned_expenses_labels = [exp.match for exp in planned_expenses if exp.match] | |
| expected_planned_expenses = sum([exp.amount_per_month for exp in planned_expenses]) | |
| planned_expenses_transactions, expenses_transactions = extract_transactions_by_label( | |
| expenses_transactions, planned_expenses_labels) | |
| savings_goal = 0 | |
| if budget_goals: | |
| savings_goal = sum([s.savings_per_month for s in budget_goals]) | |
| income = sum([tx.amount for tx in income_transactions]) | |
| expenses = abs(sum([tx.amount for tx in expenses_transactions])) | |
| planned_expenses = abs(sum([tx.amount for tx in planned_expenses_transactions])) | |
| real_balance = income - planned_expenses - expenses | |
| savings = income - expected_planned_expenses - expenses | |
| balance = savings - savings_goal | |
| expected_real_balance = max(income, expected_income) - planned_expenses - expenses | |
| expected_savings = max(income, expected_income) - expected_planned_expenses - expenses | |
| expected_balance = expected_savings - savings_goal | |
| expected_remaining = max(expected_balance, 0) | |
| return Budget(month=start_date, | |
| transactions=transactions, | |
| income_transactions=income_transactions, | |
| planned_expenses_transactions=planned_expenses_transactions, | |
| expenses_transactions=expenses_transactions, | |
| real_balance=real_balance, | |
| balance=balance, | |
| income=income, | |
| planned_expenses=planned_expenses, | |
| expenses=expenses, | |
| savings=savings, | |
| savings_goal=savings_goal, | |
| expected_real_balance=expected_real_balance, | |
| expected_balance=expected_balance, | |
| expected_income=expected_income, | |
| expected_planned_expenses=expected_planned_expenses, | |
| expected_savings=expected_savings, | |
| expected_remaining=expected_remaining) | |
| def filter_period(objs, from_date, to_date): | |
| return filter(lambda obj: (not obj.from_date or obj.from_date <= from_date)\ | |
| and (not obj.to_date or obj.to_date > from_date or obj.to_date > to_date), objs) |
I am trying to build a small project to track personal expenses using python programming. This...
The programming language is C# we are using wpf
forms.
Hello, I would like to get my clear button to work. So when
clear is click everything is clear not only the total, tax or
subtotal but also the combox and the data grid. For the Delete
button if the user selects a specific item it will be deleted and
for the receipt button, it should create a pdf that contains the
Name, Price, quantity, tax, total and subtotal. it...
Website help I am also trying to build a recipe website using an
API. here's a link to the API's https://www.themealdb.com/api.php I
just want to know how to get data from it specifically getting
recipes By searching on:
Search meal by name API:
https://www.themealdb.com/api/json/v1/1/search.php?s=Arrabiata
List all meals by first letter: API
https://www.themealdb.com/api/json/v1/1/search.php?f=a
Lookup full meal details by id: API
https://www.themealdb.com/api/json/v1/1/lookup.php?i=52772
Lookup a random meal: API:
https://www.themealdb.com/api/json/v1/1/random.php
List all meal categories: API:
https://www.themealdb.com/api/json/v1/1/categories.php
List all Categories, Area, Ingredients API:
https://www.themealdb.com/api/json/v1/1/list.php?c=list
https://www.themealdb.com/api/json/v1/1/list.php?a=list...
Hi, please help me to check and see if I am on the right track.
(Specifically for "requirement 3", I don't know if I choose the
correct one, each blank for requirement 3 contains 2 options, one
is the one that I chose, the other one is completely opposite than
the one that I selected. please let me know the answer for
requirement 3 and help me to check if I am doing correct for
requirement 1 and 2) Thank...
JAVA Hello I am trying to add a menu to my Java code if someone can help me I would really appreacite it thank you. I found a java menu code but I dont know how to incorporate it to my code this is the java menu code that i found. import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JRadioButtonMenuItem; public class MenuExp extends JFrame { public MenuExp() { setTitle("Menu Example");...
Need some help I am not understanding this programming class at
all. We are using Microsoft visual studio with python in console
mode to complete these labs.
Double-click to hide white space CIS115 Week 4 Lab Overview Title of Lab: Multiplication Table in Python Summary This week's lab is to create a simple multiplication table using nested loops and if statements. Prompt the user for the size of the multiplication table (from 2x2 to 10x10). Use a validation loop to...
I am having trouble completing this statement of cash flow.
Thank you so much for your help!
i Chrome File Edit View History Bookmarks People Window Help 苷공 *令100% 다과 Sun 3:05 PM Luxur × Shept x ← → С 을 https://courses.shepherd.edu/portal/site/201840-FINC-300:02/tool/cc3bf398-a434-4902-af36-9b7cd5f9b9df/jst/delivery/deliverAssessment !! Apps a \ User Login 血 @ Login Amazon.com: Onli." O YouTub Shepherd Universi Shepherd CLE: G-, inbox (264)-gian.. ヤBAGS ! Jessica Bu. 'A Used 2016 Ford F Part 1 of1 Tutor.com Question 2 of 2 1.0...
I am in desperate need of help with this project. Apparently my
answers are all wrong.
3:02 PM Thu Feb 27 4796% AC 321 Intl - FA19 - Comprehensive Project Insert Draw Formulas Data Review View 8 Q o Calibri (Body) 12 B U Home B ^ A = 1 EE tx ã į 19 2 3 4 All work must be completed using this Excel spreadsheet. All journal extries, financial statements, etc. must be prepared in clean, proper form....