Doubt about percentages in the chart + Solved Code

Hi, here is how i solved it, but still having a question!

class Category:

  def __init__(self, name):
    self.name = name
    self.ledger = []
  
  def check_funds(self, amount):
    if amount > self.get_balance():
      return False
    else:
      return True


  def deposit(self, amount, description = ""):
    self.ledger.append({"amount": amount, "description": description})
  
  def withdraw(self, amount, description = ""):
    if self.check_funds(amount):
      self.ledger.append({"amount": -amount, "description": description})
      return True
    else:
      return False
    
  def get_balance(self):
    tot = 0
    for i in self.ledger:
      tot += i["amount"]
    return tot

  def transfer(self, amount, objname):
    if not self.check_funds(amount):
      return False

    tranfw = "Transfer to " + objname.name
    self.withdraw(amount, tranfw)

    tranfd = "Transfer from " + self.name
    objname.deposit(amount, tranfd)
    return True

  def __str__(self):
    title = f"{self.name:*^30}\n"
    items = ""
    for i in self.ledger:
      print(i)
      items += f"{i['description'][0:23]:23}" + f"{i['amount']:>7.2f}" + "\n"
    return title + items + "Total: " + str(self.get_balance())




def create_spend_chart(categories):
  title = "Percentage spent by category\n"
  balance = []
  chart = []
  names = []
  tot_spent = 0
  longest = 0
  for cate in categories:
    if len(cate.name) > longest:longest = len(cate.name)
    cate_spent = sum((value['amount'] for value in cate.ledger if value['amount'] < 0))
    balance.append(cate_spent)
    tot_spent += cate_spent
    names += [cate.name.capitalize()]

  percentages = [round((i/tot_spent)*10, 0)*10 for i in balance] 

  for i in range(12 + longest):
    line = ''
    if i < 11:
      value = (10-i)*10
      line += f"{value:>3}|"
      dots = (" o " if elem >= value else "   " for elem in percentages)
      line += "".join(dots) + " "
    elif i == 11:
        line = "    " + "---"*len(percentages) + "-"
    else:
        letters = list(" "+ name[i-12] +" " if len(name) > i-12 else "   " for name in names)
        line += "    "+ "".join(letters) + " "
    chart.append(line)
    
  return title + "\n".join(chart)

in the create_spend_chart() function, while running the test_module i have a problem:
My porcentages from the test categories (rounded) are [10%, 70%, 20%] for [Buss, Food, Enter], but the test_module asks for 0% in Bussines. I don’t understand why? since the spent in each category is [-10.99, -105.55, -33.4], which being divided by the total spent is [0.07329598506069095, 0.7039482459650527, 0.22275576897425636]. The first category should be 10% rounded…

Thanks and great excercice, hope my code helps!

Well, i found a solution to this pretty fast, i had to change the rounding applied.

def create_spend_chart(categories):
  title = "Percentage spent by category\n"
  balance = []
  chart = []
  names = []
  tot_spent = 0
  longest = 0
  for cate in categories:
    if len(cate.name) > longest:longest = len(cate.name)
    cate_spent = sum((value['amount'] for value in cate.ledger if value['amount'] < 0))
    balance.append(cate_spent)
    tot_spent += cate_spent
    names += [cate.name.capitalize()]
    
  print(balance)
##### -> CHANGE HERE
  percentages = [(i/tot_spent)*100 for i in balance] 
#####  
print(percentages)
  f = list(x/tot_spent for x in balance)
  print(f)
  
  for i in range(12 + longest):
    line = ''
    if i < 11:
      value = (10-i)*10
      line += f"{value:>3}|"
##### -> CHANGE HERE
      dots = ("   " if elem < value else " o " for elem in percentages)
##### 
      line += "".join(dots) + " "
    elif i == 11:
        line = "    " + "---"*len(percentages) + "-"
    else:
        letters = list(" "+ name[i-12] +" " if len(name) > i-12 else "   " for name in names)
        line += "    "+ "".join(letters) + " "
    chart.append(line)
    
  return title + "\n".join(chart)