# Scientific Computing with Python Projects - Budget App

I have an issue with the bar chart part of the project. It functions well when it comes to printing the bar out in a well formatted way but I have issues with calculating the percentage which fails the tests. The instructions in the project aren’t clear on what I would have to calculate exactly. It just says to use the withdrawals and not the deposits, but I still need a “full” value to calculate the percentage the withdrawals make up from them. For example: (`total_withdrawals / initial_deposit) * 100`.

User Agent is: `Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0`

Challenge: Scientific Computing with Python Projects - Budget App

You’re calculating the percentage of the total spending spent in each category. So, your denominator is the total spent over all categories.

But then what’s the numerator if it’s not the initial deposit?

I found the solution, the percentage in question was the percentage of the individual category spending from the total spending.

NEW QUESTION:

Hi, I submitted my Budget.py app on Replit and I have 2 errors I just can’t seem to solve. Can you help, please?

My output seems to be spot on, except, when the test module runs the 2nd (hidden) test, the test module manages to add an errant (.) period just before the spend_chart. Why?

Here’s the error descriptions (there are 2):

973.96
Food
initial deposit 1000.00
groceries -10.15
restaurant and more foo -15.89
Transfer to Clothing -50.00
Total: 923.96
Clothing
Transfer from Food 50.00
-25.55
Total: 24.45
Percentage spent by category
100|
90|
80|
70|
60| o
50| o
40| o
30| o
20| o o
10| o o o
0| o o o
----------
F C A
o l u
o o t
d t o
h
i
n
g

None
.Percentage spent by category
100|
90|
80|
70| o
60| o
50| o
40| o
30| o
20| o o
10| o o
0| o o o
----------
B F E
u o n
s o t
i d e
n r
e t
s a
s i
n
m
e
n
t

# F…F…

## FAIL: test_create_spend_chart (test_module.UnitTests)

Traceback (most recent call last):
File “/home/runner/boilerplate-budget-app-1/test_module.py”, line 102, in test_create_spend_chart
self.assertEqual(actual, expected, ‘Expected different chart representation. Check that all spacing is exact.’)
AssertionError: None != 'Percentage spent by category\n100| [384 chars] t ’ : Expected different chart representation. Check that all spacing is exact.

## ====================================================================== FAIL: test_to_string (test_module.UnitTests)

Traceback (most recent call last):
File “/home/runner/boilerplate-budget-app-1/test_module.py”, line 91, in test_to_string
self.assertEqual(actual, expected, ‘Expected different string representation of object.’)
AssertionError: ‘[92 chars]Transfer to Entertainme -20.00\nTotal: 834.33 ’ != '[92 chars]Transfer to Entertainme -20.00\nTotal: 834.33’
Food
deposit 900.00
milk, cereal, eggs, bac -45.67
Transfer to Entertainme -20.00

• Total: 834.33 + Total: 834.33 : Expected different string representation of object.

Ran 11 tests in 0.009s

FAILED (failures=2)

KeyboardInterrupt

And here’s the code I submitted:

``````# Budget App

class Category:

def __init__(self, name):
self.name = name
self.balance = 0
self.ledger = []

def __str__(self):
s = f"{self.name:*^30}\n"
# Here’s the grammar of a format specifier: [[fill]align][sign][#][0][width][grouping_option][.precision][type]

for n in self.ledger:
descriptions = (n['description'])[0:23]  # each character of the string up until the 23rd.
amounts = str(n['amount'])  # entire amount as a string.
d = (f"{descriptions: <23}")
a = (f"{float(amounts): >#7.2f}\n")
s += d
s += (a)[0:7] + "\n"
s += (f"Total: {self.balance:<#23.2f}\n")[0:30]
#s += "\n"

return s

# DEFINE METHODS = FUNCTIONS (with self-contained variables)
def get_balance(self):
return self.balance

def check_funds(self, amount):  # per category
self.amount = amount

if self.amount <= self.balance:
return True
else:
return False

def deposit(self, amount, description=""):
self.balance += amount
self.ledger.append({"amount": amount, "description": description})  # can take ONE argument
return True

def withdraw(self, amount, description=""):

if self.check_funds(amount):
self.balance -= amount
self.ledger.append({"amount": -abs(amount), "description": description})
return True
else:
amount = 0
return False

def transfer(self, amount, instance):

if self.check_funds(amount):
description_transfer = f"Transfer \${amount} from {self.name} to {instance.name}."
self.withdraw(amount, f"Transfer to {instance.name}")
instance.deposit(amount, f"Transfer from {self.name}")
return True
else:
return False

def print_ledger(self):
print(self.__str__())

def get_withdrawls(self):
global cat_total
cat_total = 0

for item in self.ledger[0:]:
if int(item['amount']) < 0:
cat_total += item['amount']

return cat_total

# -------------------OUTSIDE OF CLASS------------------- #
def get_totals(names):
total = 0
totals = []
for each in names:
total += Category.get_withdrawls(self=each)
totals.append(Category.get_withdrawls(self=each))
rounded = list(map(lambda x: math_reduce(x / total), totals))  # x is each in totals list, x/grand total for each.
return rounded

def math_reduce(n):
multiplier = 10
return int(n * multiplier) / multiplier

# ***********************************^^^WORKS^^^*********************************** #

def create_spend_chart(categories):

p = "Percentage spent by category\n"
percentages = []
names_list = []
nums_list = []

for cat in categories:  # use.method
names_list.append(cat.name)
nums_list.append(cat.get_withdrawls())
height = (len(max(names_list, key=len)))
padded = [name.ljust(height) for name in names_list]

percentages.append(get_totals(categories))

# PERCENTAGES FOR CHART
percentages_big = []
for i in percentages[0]:
multiplied = i * 100
percentages_big.append(multiplied)

# THE CHART
for n in range(100, -1, -10):
p += f"{n:>3}" + "| "
for percent in percentages_big:
if percent >= n:
p += "o  "
else:
p += "   "
p += "\n"
p += f"{'    ' + '-' + (('-' * 3) * len(categories))}\n"