Budget app ledger problem

hello guys, my problem is that the ledger of a category on replit seems to combine with the legder of other categories. This doesnt happen on pycharm so I dont know what the problem is.

Here is my code on replit

class Category:
    account_book = []
    def __init__(self, name, ledger = []):
        
        
        self.name = name
        self.ledger = ledger
        self.amount_deposit = 0
        self.amount_withdraw = 0
        self.balance = 0

    def deposit(self, amount, description = ''):
        self.ledger.insert(0,{"amount": amount, "description": description})
        self.account_book.append({"amount": amount, "description": description})
        self.amount_deposit += amount
        self.balance += amount
    
    
    def withdraw(self, amount, description = ''):
        if amount < self.balance:
            self.ledger.insert(1,{"amount": - amount, "description": description})
            self.account_book.append({"amount": - amount, "description": description})
            self.amount_withdraw += amount
            self.balance -= amount
            return True
        else:
            return False

    def get_balance(self):    
        return self.balance
    
    def transfer(self, amount, name2):
        if amount < self.balance:
            self.ledger.insert(0, {"amount": amount, "description": f'Transfer from {self.name}'})

            name2.ledger.insert(2, {"amount": - amount, "description": f'Transfer to {name2.name}'})

            self.account_book.append({"amount": - amount, "description": f'Transfer to {name2.name}'})

            name2.account_book.append({"amount": amount, "description": f'Transfer from {self.name}'})

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

           
    def __str__(self):
       first = f'{self.name:*^30}'+ '\n'
       items = ""
       for i in range(len(self.account_book)):
           items += str(self.account_book[i]['description'])\
            + str(self.account_book[i]['amount']).rjust\
            (30-len(self.account_book[i]['description'])) + '\n'

      
       return first + items + 'Total:' + str(self.balance)

Here is the error

FAIL: test_to_string (test_module.UnitTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/boilerplate-budget-app-1/test_module.py", line 83, in test_to_string
    self.assertEqual(actual, expected, 'Expected different string representation of object.')
AssertionError: '****[23 chars]***\ninitial deposit           1000\ngroceries[731 chars]4.33' != '****[23 chars]***\ndeposit                 900.00\nmilk, cer[64 chars]4.33'
Diff is 1146 characters long. Set self.maxDiff to None to see it. : Expected different string representation of object.

And here is the output

*************Food*************
initial deposit           1000
groceries               -10.15
restaurant and more food for dessert-15.89
Transfer to Clothing       -50
Transfer from Food          50
                        -25.55
initial deposit           1000
                           -15
Total:923.96
***********Clothing***********
initial deposit           1000
groceries               -10.15
restaurant and more food for dessert-15.89
Transfer to Clothing       -50
Transfer from Food          50
                        -25.55
initial deposit           1000
                           -15
Total:24.45
None
.F...F.....

Here is the code on pycharm. its a little different since for some reason the test on replit gives me a different output then on pycharm. the main difference is on the transfer function

class Category:

    def __init__(self, name,):
        account_book = []
        ledger = []
        self.name = name
        self.account_book = []
        self.ledger = ledger
        self.amount_deposit = 0
        self.amount_withdraw = 0
        self.balance = 0

    def deposit(self, amount, description=''):
        self.ledger.insert(0, {"amount": amount, "description": description})
        self.account_book.append({"amount": amount, "description": description})
        self.amount_deposit += amount
        self.balance += amount

    def withdraw(self, amount, description=''):
        if amount < self.balance:
            self.ledger.insert(1, {"amount": - amount, "description": description})
            self.account_book.append({"amount": - amount, "description": description})
            self.amount_withdraw += amount
            self.balance -= amount
            return True
        else:
            return False

    def get_balance(self):
        return self.balance

    def transfer(self, amount, name):
        if amount < self.balance:
            self.ledger.insert(2, {"amount": - amount, "description": f'Transfer to {self.name}'})
            name.ledger.insert(0, {"amount": amount, "description": f'Transfer from {self.name}'})
            self.account_book.append({"amount": - amount, "description": f'Transfer to {name.name}'})
            name.account_book.append({"amount": amount, "description": f'Transfer from {self.name}'})
            self.balance -= amount
            name.balance += amount
            return True
        else:
            return False

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

    def __str__(self):
        first = f'{self.name:*^30}' + '\n'
        items = ""
        for i in range(len(self.account_book)):
            items += str(self.account_book[i]['description']) \
                     + str(self.account_book[i]['amount']).rjust \
                         (30 - len(self.account_book[i]['description'])) + '\n'

        return first + items + '\n' + 'Total:' + str(self.balance)

And here is the output

973.96
*************Food*************
initial deposit           1000
groceries               -10.15
restaurant and more food for dessert-15.89
Transfer to Clothing       -50

Total:923.96
***********Clothing***********
Transfer from Food          50
                        -25.55

Total:24.45

as you can see I used two different list to record the transanctions. the ledger list uses insert in a specific location so I can pass the tests and the account_book list uses append for the right order. Either way in both lists the the elements get combined

In the first code the account_book is a class variable declared. This means it is shared among all instances of the class and mutated by those. In the second version it is an instance variable , so such behavior doesn’t happen.

yep, that was it. Thanks! I really dont know how I didn’t see that lol!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.