# Expenses


class Move:
    def __init__(self, concept: str, amountInCents: int):
        self.__concept = concept
        self.__amount = amountInCents
    ...    
        
    @property
    def amountInCents(self) -> int:
        return self.__amount
    ...
    
    @property
    def amount(self) -> float:
        return self.__amount / 100.0
    ...
    
    @property
    def concept(self) -> float:
        return self.__concept
    ...
    
    def __str__(self) -> str:
        return f"{self.amount}€ ({self.concept})"
    ...
...


class Expense(Move):
    def __init__(self, concept: str, amountInCents: int):
        super().__init__(concept, -abs(amountInCents))
    ...    
        
    def __str__(self):
        return "\t" + super().__str__()
    ...
...


class Income(Move):
    def __init__(self, concept: str, amountInCents):
        super().__init__(concept, amountInCents)
    ...    
...


class Account:
    def __init__(self):
        self.__moves = []
    ...
    
    @property
    def expenses(self) -> list[Move]:
        return list(self.__moves)
    ...
    
    def add(self, move: Move):
        self.__moves.append(move)
    ...
    
    def balanceInCents(self) -> int:
        toret = 0
        
        for m in self.__moves:
            toret += m.amountInCents
        ...
        
        return toret
    ...
    
    def balance(self) -> float:
        return self.balanceInCents() / 100.0
    ...
    
    def __str__(self):
        return str.join( "\n", [str(x) for x in self.__moves]) \
                + f"\n\nBalance: {self.balance()}€"
    ...
...


import unittest


class Test(unittest.TestCase):
    def setUp(self):
        self._acc = Account()
    ...
    
    def test_income(self):
        concept = "salary"
        salary = 150000
        i1 = Income(concept, salary)
        self.assertEqual(concept, i1.concept)
        self.assertEqual(salary, i1.amountInCents)
        self.assertEqual(salary / 100.0, i1.amount)
        self.assertEqual(f"{salary / 100.0}€ ({concept})", str(i1))
    ...
    
    def test_expense(self):
        concept = "super"
        amount = 12000
        e1 = Expense(concept, amount)
        self.assertEqual(concept, e1.concept)
        self.assertEqual(-amount, e1.amountInCents)
        self.assertEqual(-amount / 100.0, e1.amount)
        self.assertEqual(f"\t-{amount / 100.0}€ ({concept})", str(e1))
    ...
    
    def test_account(self):
        self._acc.add(Income("salary", 150050))
        self._acc.add(Expense("super", 11010))
        self._acc.add(Expense("rent", 60010))
        print(self._acc)
        self.assertEqual(790.3, self._acc.balance())
    ... 
...


if __name__ == "__main__":
    unittest.main()
...

