Tell us what’s happening:
Hello! I’m having trouble with the budget-app challenge from Scientific Computing with Python Certification and would appreciate if someone could help me.
My problem is in the second part, with the create_spend_chart function. Specifically, dispalying the letters.
I made the mistake of building and testing my function based on the input to the function being a list of strings. In that case everything works fine. But the problem is that in the complete program (and not in a separate file where I was testing it with a list of strings) the input has to be a list of objects. So my code fails because I need to convert those objects to strings and I can’t think a way of how to do it.
Your code so far
class Category:
def __init__(self,budgetname):
self.budget = budgetname
self.ledger = []
self.funds = 0
#self.positivebalance = 0
self.negativebalance = 0
def deposit(self, amount, description = ""):
self.ledger.append({"amount": amount, "description": description})
self.funds += amount
#self.positivebalance += amount
def withdraw(self, amount, description = ""):
if self.check_funds(amount) == True:
self.ledger.append({"amount": -amount, "description": description})
self.funds -= amount
self.negativebalance += amount
return True
else:
return False
def get_balance(self):
return self.funds
def check_funds(self, amount):
if amount > self.funds:
return False
else:
return True
def transfer(self, amount, category):
self.withdraw(amount, f"Transfer to {category.budget}")
if self.check_funds(amount) == True:
category.deposit(amount, f"Transfer from {self.budget}")
return True
else:
return False
def __str__(self):
totalstars = 30 - len(self.budget)
if totalstars%2 == 0:
lstars = int(totalstars/2)
rstars = int(totalstars/2)
elif totalstars%2 != 0:
lstars = int(totalstars/2)
rstars = int(totalstars/2) + 1
leftstars = "*" * lstars
rightstars = "*" * rstars
display = ""
for entry in self.ledger:
desc = entry["description"]
am = entry["amount"]
if isinstance(am,int):
am = str(am) + ".00"
if len(desc) <= 23:
wspaces = " " * (30 - len(desc) - len(str(am)))
display += f"{desc}{wspaces}{am}\n"
else:
dif = len(desc) - 23
wspaces = " " * (7 - len(str(am)))
display += f"{desc[:-(dif)]}{wspaces}{am}\n"
finaldisplay = f"{leftstars}{self.budget}{rightstars}\n" + display + f"Total: {self.get_balance()}"
return finaldisplay
def get_percentage(self):
#actual funds
balance = self.funds
#total withdrawals
withdraw = self.negativebalance
#percentage calculation
percentage_spend = int((10 * withdraw) / (balance + withdraw))
return percentage_spend
def create_spend_chart(categories):
grid = []
for category in categories:
#create a list for each element in "categories" with empty strings in the first 10 elements
column = [" "," "," "," "," "," "," "," "," "," "]
#add the capitalized-category-name as individual letters at the end of the corresponding "column" list
cap = category.capitalize() ##ERROR HERE##
splitletters = list(cap)
column.extend(splitletters)
#append all lists to "grid" list
grid.append(column)
per = get_percentage(category)
#replace empty strings with "o" according to percentage
for j in range(0, len(grid)):
for i in range(0,per):
grid[j][i] = "o"
#preparing percentage display
graph = ""
for j in range (9,-1, -1):
row = " "
for i in range (0, len(categories)):
element = grid[i][j] + " "
row += element
pernum = (j+1)*10
margin = " " * (3 - len(str(pernum)))
graph += "\n" + margin + str(pernum) + "|" + row
dashes = ("---" * len(categories) ) + "-"
#preparing words display
longestword = max(categories, key=len) ##ERROR HERE##
lenlongestword = len(longestword)
letters = ""
for j in range(10,lenlongestword + 10):
line = " "
for i in range(0, len(categories)):
try:
element = grid[i][j] + " "
line += element
except:
line += " "
letters += "\n " + line
display = "Percentage spent by category" + graph +"\n " + dashes + letters
print(display)
#return display
#TEST
food = Category("Food")
food.deposit(100, "deposit")
food.withdraw(80, "pizza")
clothing = Category("Clothing")
clothing.deposit(100, "deposit")
clothing.withdraw(50, "boots")
entretainment = Category("Entretainment")
entretainment.deposit(100, "deposit")
entretainment.withdraw(10, "cinema")
create_spend_chart([food, clothing, entretainment])
Errors in my editor console
line 86, in create_spend_chart
cap = category.capitalize() ##ERROR HERE##
AttributeError: ‘Category’ object has no attribute ‘capitalize’
line 112, in create_spend_chart
longestword = max(categories, key=len) ##ERROR HERE##
TypeError: object of type ‘Category’ has no len()
An additional problem that I also see coming is that in the line in which I use the get_percentage function I need the input to be an object, which will not be coherent if I transform everything into strings …
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36.
Challenge: Budget App
Link to the challenge: