Scientific computing with python projects/budget app

So I’ve written code which seems to me to perfectly match the desired output. It passes all except the last two tests:

  • Failed:Printing a Category instance should give a different string representation of the object.

  • Failed:create_spend_chart should print a different chart representation. Check that all spacing is exact.

I have counted spaces and looked this over and I can’t figure out why it doesn’t pass.

class Category:

    # init method or constructor
    def __init__(self, category):
        self.category = category
        self.balance = 0.0
        self.ledger = []
        self.total_spent = 0.0

    def __str__(self):
        asterisk_length = int((30-len(self.category))/2)
        output = "\n" + "*"*asterisk_length + str(self.category) + "*"*asterisk_length + "\n"
        for line in self.ledger:
            output += line["description"][:23] #print first 23 char of description
            if len(line["description"])<23:
                output += " "* (23-len(line["description"])) #add spaces as needed to get 23 char
            if len(str(line["amount"]))>7:
                output += str(line["amount"])[-7:] #print last 7 char of amount
            else:
                output += " "* (7-len(str(line["amount"]))) + str(line["amount"])
            output += "\n"
        output += "Total: " + str(self.balance)
        return str(output)

    def __repr__(self):
        return str(self)
    # deposit
    def deposit(self, amount, description=""):
        self.balance += float(amount)
        self.ledger.append({"amount": amount, "description": description})

    def withdraw(self, amount, description=""):
        if self.check_funds(amount):
            self.balance -= float(amount)
            self.ledger.append({"amount":  (amount*-1), "description": description})
            self.total_spent += float(amount)
            return True
        else:
            return False

    def get_balance(self):
        return self.balance

    def transfer(self, amount, receiving_category):
        if self.check_funds(amount):
            self.balance -= amount
            receiving_category.balance +=amount
            self.ledger.append({"amount":  (amount*-1), "description": "Transfer to "+str(receiving_category.category)})
            receiving_category.ledger.append({"amount": (amount * 1), "description": "Transfer from " + str(self.category)})
            return True
        else:
            return False

    def check_funds(self, amount):
        if amount > self.balance:
            return False
        else:
            return True



food = Category("Food")
food.deposit(1000, "deposit")
food.withdraw(10.15, "groceries")
food.withdraw(15.89, "restaurant and more food for dessert")
clothing = Category("Clothing")
food.transfer(50, clothing)
clothing.withdraw(10.00, "shirt")
auto = Category("Auto")
auto.deposit(1000, "deposit")
auto.withdraw(25.15, "groceries")
auto.withdraw(75.89, "restaurant and more food for dessert")

print(repr(food))
#print(food.ledger[1])
#print(food.ledger[1]["description"])



def create_spend_chart(categories):
    percentage_string_list = ["100| ", " 90| ", " 80| ", " 70| ", " 60| ", " 50| ", " 40| ", " 30| ", " 20| ", " 10| ", "  0| "]
    categories_names_list = []
    sum_total_spent = 0.0
    dashes_string = "    -"
    length_of_longest_category = 0
    for category in categories:
        sum_total_spent += category.total_spent
        if len(category.category) > length_of_longest_category: #find longest category name for when we display them vertically
            length_of_longest_category = len(category.category)
    for i in range(length_of_longest_category):
        categories_names_list.append("     ") #make a list of empty strings equal in number to the longest category name
    for count, category in enumerate(categories):
        percentage_spent = int(10 * float(category.total_spent)/float(sum_total_spent))
        for i in reversed(range(11)):
            if percentage_spent >= i: #build the graph o's or spaces
                percentage_string_list[10-i] += "o  "
            else:
                percentage_string_list[10 - i] += "   "
        dashes_string += "---" #add bottom dashes for each category
        for i in range(length_of_longest_category):
            if i <= len(category.category): #build the vertcal category names
                try:
                    categories_names_list[i] += str(category.category[i]) + "  "
                except:
                    pass
            else:
                categories_names_list[i] += "   "


    output_string = "Percentage spent by category\n" + "\n".join(percentage_string_list) + "\n" + dashes_string + "\n" + "\n".join(categories_names_list)
    return output_string

categories = (clothing, food, auto)
print(repr(create_spend_chart(categories)))
print(create_spend_chart(categories))

Hi there. Can you please provide a link to the challenge you’re referencing?

The amount should be right aligned, contain two decimal places, and display a maximum of 7 characters.

The instructions ask for two decimal places.
The example:
image
your code:
image
so, instead of 1000 it should be 1000.00, and son

If you use a different order for the products in the chart, the letters look like this

1 Like

Ok I fixed the issues with the spend chart and that part is passing, but my printing of the Category is still not passing although to me it looks identical to the required output.

class Category:

    # init method or constructor
    def __init__(self, category):
        self.category = category
        self.balance = 0.0
        self.ledger = []
        self.total_spent = 0.0

    def __str__(self):
        asterisk_length = int((30-len(self.category))/2)
        output = "\n" + "*"*asterisk_length + str(self.category) + "*"*asterisk_length
        if len(self.category) % 2:
            output += "*" + "\n"
        else:
            output += "\n"
        for line in self.ledger:
            new_amount = self.dollars_and_cents(line["amount"])
            output += line["description"][:23] #print first 23 char of description
            if len(line["description"])<23:
                output += " "* (23-len(line["description"])) #add spaces as needed to get 23 char
            if len(new_amount)>7:
                output += new_amount[:7  ] #print 7 char of amount
            else:
                output += " "* (7-len(new_amount)) + new_amount
            output += "\n"

        new_balance = self.dollars_and_cents(self.balance)
        if len(new_balance) > 22:
            output += "Total: " + new_balance[:22]
        else:
            output += "Total: " + new_balance
        return str(output)
    def dollars_and_cents(self, amount):
        amount_split = []
        if "." in str(amount):
            amount_split = str(amount).split(".")
            if len(amount_split[1]) ==1:
                amount_split[1]+= "0"
        else:
            amount_split = [str(amount), "00"]
        amount_str = amount_split[0] + "." + amount_split[1][:2]
        return amount_str

    # deposit
    def deposit(self, amount, description=""):
        self.balance += float(amount)
        self.ledger.append({"amount": amount, "description": description})

    def withdraw(self, amount, description=""):
        if self.check_funds(amount):
            self.balance -= float(amount)
            self.ledger.append({"amount":  (amount*-1), "description": description})
            self.total_spent += float(amount)
            return True
        else:
            return False

    def get_balance(self):
        return self.balance

    def transfer(self, amount, receiving_category):
        if self.check_funds(amount):
            self.balance -= amount
            receiving_category.balance +=amount
            self.ledger.append({"amount":  (amount*-1), "description": "Transfer to "+str(receiving_category.category)})
            receiving_category.ledger.append({"amount": (amount * 1), "description": "Transfer from " + str(self.category)})
            return True
        else:
            return False

    def check_funds(self, amount):
        if amount > self.balance:
            return False
        else:
            return True



food = Category("Food")
food.deposit(545908345.50, "deposit")
food.withdraw(10.15, "groceries")
food.withdraw(15.89, "restaurant and more food for dessert")
clothing = Category("Clothing")
food.transfer(50, clothing)
clothing.withdraw(10.00, "shirt")
auto = Category("Auto")
auto.deposit(1000, "deposit")
auto.withdraw(25.15, "groceries")
auto.withdraw(75.89, "restaurant and more food for dessert")
print(food)
print(clothing)
#print(food.ledger[1])
#print(food.ledger[1]["description"])



def create_spend_chart(categories):
    percentage_string_list = ["100| ", " 90| ", " 80| ", " 70| ", " 60| ", " 50| ", " 40| ", " 30| ", " 20| ", " 10| ", "  0| "]
    categories_names_list = []
    sum_total_spent = 0.0
    dashes_string = "    -"
    length_of_longest_category = 0
    for category in categories:
        sum_total_spent += category.total_spent
        if len(category.category) > length_of_longest_category: #find longest category name for when we display them vertically
            length_of_longest_category = len(category.category)
    for i in range(length_of_longest_category):
        categories_names_list.append("     ") #make a list of empty strings equal in number to the longest category name
    for count, category in enumerate(categories):
        percentage_spent = int(10 * float(category.total_spent)/float(sum_total_spent))
        for i in reversed(range(11)):
            if percentage_spent >= i: #build the graph o's or spaces
                percentage_string_list[10-i] += "o  "
            else:
                percentage_string_list[10 - i] += "   "
        dashes_string += "---" #add bottom dashes for each category
        for i in range(length_of_longest_category):
            if i < len(category.category): #build the vertical category names
                try:
                    categories_names_list[i] += str(category.category[i]) + "  "
                except:
                    pass
            else:
                categories_names_list[i] += "   "


    output_string = "Percentage spent by category\n" + "\n".join(percentage_string_list) + "\n" + dashes_string + "\n" + "\n".join(categories_names_list)
    return output_string

categories = (food, clothing, auto)
#print(repr(create_spend_chart(categories)))
#print(create_spend_chart(categories))

I fixed the issue with the decimal places so I’m not sure what else is wrong.

If you open the dev tools (F12) and look at the console, you can see this error

AssertionError: 
'\n*************Food*************\ndeposit[98 chars]4.33' !=
'*************Food*************\ndeposit  [96 chars]4.33'

Your output is first, and it starts with the \n but the expected output doesn’t. You probably added this to account for the >>> command prompt

1 Like

Thanks! That worked.

1 Like