Budget App - Transfer Method not working

Hi all,

My code is as follow for the budget app thus far. I could not get it to update the transfer from in another object and I don’t understand what is wrong with how I am calling the other object’s deposit method.

class Category:

CategoryName = ""
Ledger = []

def __init__(self, name, ledger=[]):
    self.CategoryName = name
    self.Ledger = ledger

def deposit (self, amount, description =""):
    self.Ledger.append([amount , description])
    
def withdraw (self, amount, description = ''):
    if self.check_funds(amount):
        self.Ledger. append([0 - amount, description])
    else:
        pass

def get_balance (self):
    t = 0
    for i in range (len(self.Ledger)):
        t = t + self.Ledger[i][0]
    return t

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

def transfer (self, amount, Other_cat):
    if self.check_funds(amount):
        Transfer_to = "Transfer to " + Other_cat.CategoryName
        self.Ledger.append([0 - amount, Transfer_to])
        Transfer_from = "Transfer from " + self.CategoryName
        Other_cat.deposit(amount, Transfer_from)
        return True
    else:
        return False

def create_spend_chart(categories):
pass

Appreciate your help in pointing out my mistake.

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0.

Challenge: Budget App

Link to the challenge:

I’m not sure if I understand what issue you are having. Can you write what you expect to be happening and what is happening instead? Are you getting any error?

Hi Sanity,

For this part of the code:

def transfer (self, amount, Other_cat):
        if self.check_funds(amount):
            Transfer_to = "Transfer to " + Other_cat.CategoryName
            self.Ledger.append([0 - amount, Transfer_to])
            Transfer_from = "Transfer from " + self.CategoryName
            Other_cat.deposit(amount, Transfer_from)
            return True
        else:
            return False
    def transfer (self, amount, Other_cat):
        if self.check_funds(amount):
            Transfer_to = "Transfer to " + Other_cat.CategoryName
            self.Ledger.append([0 - amount, Transfer_to])
            Transfer_from = "Transfer from " + self.CategoryName
            Other_cat.deposit(amount, Transfer_from)
            print (self.Ledger)
            print (Other_cat.Ledger)
            return True
        else:
            return False

I expect to print the amount transferred from the “Food” ledger to the “Clothing” ledger but when I added a print statement to the end “print (self.Ledger)” had both (-50, transfer to clothing) and (50, transfer from food) in the same ledger. When i print “print (Other_cat.Ledger)”, it also had both records and I don’t understand why.

Ah, I see it now.

Take a look at this line

def __init__(self, name, ledger=[]):

Python evaluates default parameters in functions and methods just once. As list is a mutable data type, what this basically means is, in case when ledger is not passed when class instance is created, the same list will be used for every such instance.

To avoid such behavior something like this can be used:

def func(default=None):
    if default is None:
         default = []

And one slightly unrelated tip - CategoryName and Ledger don’t need to be defined below class as class variables. Their presence there may result in some unexpected behavior. Defining them in __init__ as instance variables preceded with self. is enough for what they are used in here.

Hi Sanity,

Thanks for your explanation and tip! I would never have known that the problem with the transfer method was caused by how I defined the ledger.