-3

I'm doing the budget project in python. If I got it right, my class Category should return a value that when casted as a string, could be printed like this:

*************Food*************
initial deposit        1000.00
groceries               -10.15
restaurant and more foo -15.89
Transfer to Clothing    -50.00
Total: 923.96

The problem is if I make my object return something different of None, I get this error message:

TypeError: __init__() should return None, not 'str'

English isn't my first language, so it's quite possible that I messed up trying to understand what the projects want and what the test_module.py (test_to_string) really expects. Can you clarify for me?

My code:

class Category():
    def __init__(self, c):
        self.category = c
        self.ledger = list()
        
        length = len(self.category)
                    
        temp = int((30-length)/2)
        n =  temp if length <= 30 else 0
        
        title = '*'* n + self.category + '*'*n
        
        amount_f = []
        amount_s = []
        descr = []
        for dic in self.ledger:
            for info in dic.values():
                if type(info) is int or type(info) is float:
                    info = float(info)
                    amount_f.append(info)
                    temp = '{0:>7.2f}'.format(info)
                    amount_s.append(temp)
                    
                elif type(info) is str:
                    descr.append(f'{info[:23]:<23}')
        recipe = ''
        for i in range(len(amount_s)):
            recipe = f'{recipe}\n{descr[i]} {amount_s[i]}'
            
            
        botton = '\nTotal: {:.2f}'.format(sum(amount_f))
        
        self.category = (title + recipe + botton)
        
        return self.category
        
        
    def get_balance(self):
        balance = []
        for dictionary in self.ledger:
            for value in dictionary.values():
                if type(value) is int or type(value) is float:
                    balance.append(value)
                   
        return sum(balance)    


    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) == False:
            return False

        self.ledger.append({'amount': -(amount), 'description': description})
    
        return True
    

    def transfer(self, amount, department):
        if self.check_funds(amount) == False:
            return False
 
        self.withdraw(amount, 'Transfer to ' + department.category)
        department.deposit(amount, 'Transfer from ' + self.category)
        
        return True



def create_spend_chart(categories):
    return 'aaaaaaaaaaa'


#####################################
#####################################

# Testing - Based in the test_module.py from FCC

entertaiment = Category('entertaiment')
food = Category('food')
food.deposit(900, "deposit")
food.withdraw(45.67, "milk, cereal, eggs, bacon, bread")
food.transfer(20, entertaiment)
actual = str(food)

print(actual)

#####################################
#####################################
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Welcome to Stack Overflow! Please take the [tour]. For debugging help, you need to provide a [mre] including your code, in the question itself. For more tips, see [ask]. – wjandrea Apr 22 '21 at 19:44
  • 1
    If you want to customize what `str(foo)` returns, you need to define a `__str__` method. – Barmar Apr 22 '21 at 19:45
  • Please see the answer below, as it will help you. I would also look up some documentation on how Classes work. – CompuGenuis Programs Apr 22 '21 at 19:46
  • Duplicate: [How to create a custom string representation for a class object?](https://stackoverflow.com/q/4932438/4518341) and [How to return a value from `__init__` in Python?](https://stackoverflow.com/q/2491819/4518341) – wjandrea Apr 22 '21 at 19:48

1 Answers1

0

The __init__ method isn't supposed to return a value at all. And that's what the error is telling you: should return None. You are trying to return a value from it.

So what you could do? Modify the code, so that the __init__ does not return any value :)

Feel free to copy and paste this in your project, it work's perfectly. So your code would be:

class Category():
    def __init__(self, c):
        self.category = c
        self.ledger = list()
        
        length = len(self.category)
                    
        temp = int((30-length)/2)
        n =  temp if length <= 30 else 0
        
        title = '*'* n + self.category + '*'*n
        
        amount_f = []
        amount_s = []
        descr = []
        for dic in self.ledger:
            for info in dic.values():
                if type(info) is int or type(info) is float:
                    info = float(info)
                    amount_f.append(info)
                    temp = '{0:>7.2f}'.format(info)
                    amount_s.append(temp)
                    
                elif type(info) is str:
                    descr.append(f'{info[:23]:<23}')
        recipe = ''
        for i in range(len(amount_s)):
            recipe = f'{recipe}\n{descr[i]} {amount_s[i]}'
            
            
        botton = '\nTotal: {:.2f}'.format(sum(amount_f))
        
        self.category = (title + recipe + botton)
        print(self.category)
        
        
    def get_balance(self):
        balance = []
        for dictionary in self.ledger:
            for value in dictionary.values():
                if type(value) is int or type(value) is float:
                    balance.append(value)
                   
        return sum(balance)    


    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) == False:
            return False

        self.ledger.append({'amount': -(amount), 'description': description})
    
        return True
    

    def transfer(self, amount, department):
        if self.check_funds(amount) == False:
            return False
 
        self.withdraw(amount, 'Transfer to ' + department.category)
        department.deposit(amount, 'Transfer from ' + self.category)
        
        return True



def create_spend_chart(categories):
    return 'aaaaaaaaaaa'


entertaiment = Category('entertaiment')
food = Category('food')
food.deposit(900, "deposit")
food.withdraw(45.67, "milk, cereal, eggs, bacon, bread")
food.transfer(20, entertaiment)
actual = str(food)

print(actual)
Henrik
  • 828
  • 8
  • 34