I’m stuck at the very last test of the Python Budge App project that tests the “create_spend_chart”. Here’s what I did:
counted the number of characters of the output chart
compared it against the example given in the project description
doubled checked that each bar should show the “rounded down” (14.9 should be considered as 20, where as 14.0 should be 10) version of percentage of “total expenses of a category over total deposit”
Could anyone please help ?
class Category:
def __init__(self, name):
self.name = name
self.ledger = [] #must be an instance instead of class variable
self.balance = 0
self.totalwithdrawal = 0
self.totaldeposit = 0
def __str__(self):
#print title of Category with centered in between asterixes
lenobjname = len(self.name)
rightstars = int( (30 - len(self.name))/2)
leftstars = int( (30-len(self.name)) /2 ) + ( len(self.name) % 2 >0)
output = ("*" * rightstars) + (self.name) + ("*" * leftstars)
itemlist = []
for item in self.ledger:
item_descript = item.get("description")
item_amount = item.get("amount")
output = output + "\n" + (str(item_descript))[:23].ljust(23) + ("%.2f"%item_amount)[:7].rjust(7)
#itemlist.append((str(item_descript)).ljust(23) + ("%.2f"%item_amount).rjust(7))
lastline = "Total: " + "%.2f"%self.get_balance()
output = output + "\n" + lastline.strip()
#itemlist.append("Total: " + "%.2f"%self.get_balance())
#print(itemlist, end='')
return output
def deposit(self, amount, description=""):
ledger_item = {
"amount": amount,
"description": description,
}
self.ledger.append(ledger_item)
self.balance += amount
self.totaldeposit += amount
def withdraw(self, amount, description=""):
if (self.check_funds(amount)):
ledger_item_withdrawn = {
"amount": amount*(-1),
"description": description,
}
self.ledger.append(ledger_item_withdrawn)
self.balance -= amount
self.totalwithdrawal += amount
return True
else:
return False
def get_balance(self):
l=0;
for item in self.ledger:
l = l+item.get("amount")
#print("balance of ", self.name , l)
return l
def transfer(self, num, toobj):
if (self.check_funds(num)):
self.withdraw(num, "Transfer to "+toobj.name)
toobj.deposit(num, "Transfer from "+ self.name)
return True
else:
return False
def check_funds(self, num):
if (num>self.get_balance()):
return False
else:
return True
def create_spend_chart(categories):
num_of_cats = len(categories)
if (num_of_cats < 5):
withdraw_percentages = []
for i in categories:
withdraw_percentages.append(round(((i.totalwithdrawal/i.totaldeposit)*100),1)-10)
print(withdraw_percentages)
chart = "Percentage spent by category" + "\n"
for a in range (100,-10,-10):
line = (str(a) + "|" ).rjust(5)
for j in withdraw_percentages:
if j >= a:
line = line + " o "
else:
line = line + " "
line = line + " \n"
chart = chart + line
line = " "
for j in withdraw_percentages:
line = line + "---"
line = line + "- \n"
chart = chart + line
longestname = 0
for j in categories:
if len(j.name) > longestname:
longestname = len(j.name)
for i in range (0,longestname):
line = " "
for c in categories:
if len(c.name) > i:
line = line + " " + c.name[i] + " "
else:
line = line + " "
line = line + " \n"
chart = chart + line
chart2 = list(chart)
chart2 = "".join([chart[i] for i in range(len(chart)-1)])
return chart2
thanks Ilenia. I removed one space at the beginning of each line now.
I also made sure that:
there is one space at the end of each line
each percentage bar should be (total expenses / total deposit ) rounded DOWN meaning a result of 65.78238748 or 69.9938382 should be treated as 60 (like math.floor())
but i still couldn’t pass … please kind shed some lights
Thanks again ilenia.
Did you mean clicking on the “Console” ? After I clicked on it, i got the following message:
// running tests create_spend_chart should print a different chart representation. Check that all spacing is exact. // tests completed
Below is the code:
class Category:
def __init__(self, name):
self.name = name
self.ledger = [] #must be an instance instead of class variable
self.balance = 0
self.totalwithdrawal = 0
self.totaldeposit = 0
def __str__(self):
#print title of Category with centered in between asterixes
lenobjname = len(self.name)
rightstars = int( (30 - len(self.name))/2)
leftstars = int( (30-len(self.name)) /2 ) + ( len(self.name) % 2 >0)
output = ("*" * rightstars) + (self.name) + ("*" * leftstars)
itemlist = []
for item in self.ledger:
item_descript = item.get("description")
item_amount = item.get("amount")
output = output + "\n" + (str(item_descript))[:23].ljust(23) + ("%.2f"%item_amount)[:7].rjust(7)
#itemlist.append((str(item_descript)).ljust(23) + ("%.2f"%item_amount).rjust(7))
lastline = "Total: " + "%.2f"%self.get_balance()
output = output + "\n" + lastline.strip()
#itemlist.append("Total: " + "%.2f"%self.get_balance())
#print(itemlist, end='')
return output
def deposit(self, amount, description=""):
ledger_item = {
"amount": amount,
"description": description,
}
self.ledger.append(ledger_item)
self.balance += amount
self.totaldeposit += abs(amount)
def withdraw(self, amount, description=""):
if (self.check_funds(amount)):
ledger_item_withdrawn = {
"amount": amount*(-1),
"description": description,
}
self.ledger.append(ledger_item_withdrawn)
self.balance -= amount
self.totalwithdrawal += abs(amount)
return True
else:
return False
def get_balance(self):
l=0;
for item in self.ledger:
l = l+item.get("amount")
#print("balance of ", self.name , l)
return l
def transfer(self, num, toobj):
if (self.check_funds(num)):
self.withdraw(num, "Transfer to "+toobj.name)
toobj.deposit(num, "Transfer from "+ self.name)
return True
else:
return False
def check_funds(self, num):
if (num>self.get_balance()):
return False
else:
return True
def create_spend_chart(categories):
num_of_cats = len(categories)
if (num_of_cats < 5):
withdraw_percentages = []
for i in categories:
withdraw_percentages.append(round(((i.totalwithdrawal/i.totaldeposit)*100)))
print("withdraw_percentages = ", withdraw_percentages)
chart = "Percentage spent by category" + "\n"
for a in range (100,-10,-10):
line = (str(a) + "|" ).rjust(4)
for j in withdraw_percentages:
if j >= a:
line = line + " o "
else:
line = line + " "
line = line + " \n"
chart = chart + line
line = " "
for j in withdraw_percentages:
line = line + "---"
line = line + "-\n"
chart = chart + line
longestname = 0
for j in categories:
if len(j.name) > longestname:
longestname = len(j.name)
for i in range (0,longestname):
line = " "
for c in categories:
if len(c.name) > i:
line = line + " " + c.name[i] + " "
else:
line = line + " "
line = line + " \n"
chart = chart + line
chart2 = list(chart)
chart2 = "".join([chart[i] for i in range(len(chart)-1)])
return chart2
I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.
You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.
Your create_spend_chart is not working properly, I don’t know if it’s not calculating the percentages properly, or if you don’t put in the correct dots, but it’s giving the wrong output
your output for the tests:
Percentage spent by category
100|
90|
80|
70|
60|
50|
40|
30|
20|
10| 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
The one the tests want:
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
The freecodecamp tests are generating output and sending it to the console, but that’s just not being sent to the coding interface console on the freecodecamp website.
thanks , i’m down to my last project and would really love to know how I could make use of browser console (I’m using Chrome) to debug.
Attached is a screenshots what the browser console returned:
import copy
import random
class Hat:
def __init__(self, **kwargs):
self.contents = []
for color, num in kwargs.items():
for i in range (0,num):
self.contents.append(color)
def draw(self, num):
if num >= len(self.contents):
return self.contents
else:
for i in range(1,num):
self.contents.pop(random.randrange(len(self.contents)))
return self.contents