What am I doing wrong here? It prints exactly as should each time. I see no difference between expected and actual…
FreeCodeCamp-BudgetApp:
TestModule:
Error 1: Line 102
self.assertEqual(actual, expected, ‘Expected different chart representation. Check that all spacing is exact.’)
Expected Result:
"Percentage spent by category\n100| \n 90| \n 80| \n 70| o \n 60| o \n 50| o \n 40| o \n 30| o \n 20| o o \n 10| o o \n 0| o o o \n ----------\n B F E \n u o n \n s o t \n i d e \n n r \n e t \n s a \n s i \n n \n m \n e \n n \n t "
Error 2: Line 91
self.assertEqual(actual, expected, ‘Expected different string representation of object.’)
# Budget App
class Category:
def __init__(self, name):
self.name = name
self.balance = 0
self.ledger = []
def __repr__(self): # or __str__ ?
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 = []
padded = []
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"
for name in zip(*padded):
p += (' ' + (' '.join(name))) + ' \n'
return p
# ***********************************END OF PROJECT*********************************** #
Thanks,
-T
From my limited experience, all I can say is that the format is not quite right. The ‘+’ signs from the testing module signals extra spaces that shouldn’t be there or something. All of the symbols on the left of the chart mean something, maybe experiment and see how you can reduce them.
I will have a further look when I have time. I hope that helps at least somewhat.
I made the implied edits:
1. reduced spaces after last charted bar from 2 to 1 space.
2. added a vertical space after (below) the longest word length (now 27 lines instead of 26).
The test now throws the same 2 errors, but with more edit points indicated. Did I read the differencechecker incorrectly? I used the charts saying “Original Text” vs “Changed Text”, using the “changed text” as the desired target and the original as what I assumed was my erroneous output.
Here are the test failure outputs:
.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: 'Perc[34 chars] \n 90| \n 80| \n 70| o[347 chars] \n' != 'Perc[34 chars] \n 90| \n 80| \n 70| [340 chars] t '
Percentage spent by category
- 100|
+ 100|
? +
- 90|
+ 90|
? +
- 80|
+ 80|
? +
- 70| o
+ 70| o
? +
- 60| o
+ 60| o
? +
- 50| o
+ 50| o
? +
- 40| o
+ 40| o
? +
- 30| o
+ 30| o
? +
- 20| o o
+ 20| o o
? +
- 10| o o
+ 10| o o
? +
- 0| o 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
? -
+ 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.030s
FAILED (failures=2)
KeyboardInterrupt
Here is my current code from the create/spend chart:
def create_spend_chart(categories):
p = "Percentage spent by category\n"
percentages = []
names_list = []
nums_list = []
padded = []
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+1) for name in names_list] # NEW EDIT 2/24
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 " # NEW EDIT 2/24
else:
p += " "
p += "\n"
p += f"{' ' + '-' + (('-' * 3) * len(categories))}\n"
for name in zip(*padded):
p += (' ' + (' '.join(name))) + ' \n'
return p
…after closer inspection of the test module:
-the test expected \n (new line) at the BEGINNING of each line, whereas
-my code had \n (new line) at the END of each line.
Total errors down from 2 to 1.
From test module:
expected = "Percentage spent by category**\n**100| \n 90| \n 80| \n 70| o \n 60| o \n 50| o \n 40| o \n 30| o \n 20| o o \n 10| o o \n 0| o o o \n ----------\n B F E \n u o n \n s o t \n i d e \n n r \n e t \n s a \n s i \n n \n m \n e \n n \n t "
vs my erroneous old code:
p = "Percentage spent by category**\n**" **# Mine ENDS with N)**
percentages = []
names_list = []
nums_list = []
padded = []
for cat in categories: # use.method
names_list.append(cat.name)
nums_list.append(cat.get_withdrawls())
height_full = (len(max(names_list, key=len)))
height_dif = (height_full-(len(cat.name)))
padded = [name.ljust(height_full) 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"
for name in zip(*padded):
p += (' ' + (' '.join(name))) + **' \n'** **# Mine ENDS with N)**
return p
How particular! There is no way to know about this from the FCC instructions alone. A person MUST examine the test module to make this correction.
Thank you for your help, and for getting me to look closer at the test code.
PASSING CODE with \n at the BEGINNING of each printed line:
def create_spend_chart(categories):
p = "Percentage spent by category"
percentages = []
names_list = []
nums_list = []
padded = []
for cat in categories: # use.method
names_list.append(cat.name)
nums_list.append(cat.get_withdrawls())
height_full = (len(max(names_list, key=len)))
height_dif = (height_full-(len(cat.name)))
padded = [name.ljust(height_full) 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{n:>3}" + "| " # NEW EDIT 2/24 *********
for percent in percentages_big:
if percent >= n:
p += "o " # NEW EDIT 2/24 *********
else:
p += " "
#p += "\n"
p += f"\n{' ' + '-' + (('-' * 3) * len(categories))}"
for name in zip(*padded):
p += ('\n ' + (' '.join(name))) + ' '
return p
# ***********************************END OF PROJECT*********************************** #
def __repr__(self): # or __str__ ?
s = f"{self.name:*^30}"
# 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"\n{descriptions: <23}")
a = (f"{float(amounts): >#7.2f}")
s += d
s += a[0:7]
s += (f"\nTotal: {self.balance:<#3.2f}")[0:30] **# changed from <#23.2 to <#3.2**
return s
In the line for the total and amount, my original code produced extra spaces after the total. The above is now correct, although I’m not sure HOW it got rid of the spaces, and since I wrote this stuff almost a year ago, I forgot how those ‘format specifiers’ even work. But it produced the right answer.
SEE BELOW for solution to Line 102 Error.
Thanks,
-T