I need to create a 'Balance' class which will be a son of two parent classes 'Income' and 'Expenses'. 'Income' and 'Expenses' should be conteiners where I will put some numbers and find the difference between sum of 'Income' and sum of 'Expenses' later on.
from dataclasses import dataclass
@dataclass
class Income:
first_Income: int = 0
second_Income: int = 0
third_Income: int = 0
def all_vars_Income(self):
return [attr for attr in dir(self) if not callable(getattr(self, attr)) and not attr.startswith('__')]
def sum_Income(self):
return sum([getattr(self, var) for var in self.all_vars_Income()])
@dataclass
class Expenses:
first_Expenses: int = 0
second_Expenses: int = 0
third_Expenses: int = 0
def all_vars_Expenses(self):
return [attr for attr in dir(self) if not callable(getattr(self, attr)) and not attr.startswith('__')]
def sum_Expenses(self):
return sum([getattr(self, var) for var in self.all_vars_Expenses()])
class Balance(Income, Expenses):
def sum_Balance(self):
return Income.sum_Income(self) - Expenses.sum_Expenses(self)
user = Balance()
print(Balance.all_vars_Income(user))
# ['first_Expenses', 'first_Income', 'second_Expenses', 'second_Income', 'third_Expenses', 'third_Income']
print(Income.all_vars_Income(user))
# ['first_Expenses', 'first_Income', 'second_Expenses', 'second_Income', 'third_Expenses', 'third_Income']
print(Income.all_vars_Income(Income))
# ['first_Income', 'second_Income', 'third_Income']
user.__setattr__('first_Income', 50)
user.__setattr__('second_Expenses', 100)
print(Income.sum_Income(user))
# 150
print(user.sum_Balance())
# 0
So, the problem is, as you can see, that variables of the first class and the variables of the second class are kinda mixed up. I want to keep variables within approriate classes and use only sum of those variables to be able to count the difference.
When I this line "user.__setattr__('first_Income', 50)"
, I want to change the value of the Income class only, so that I could keep the sum of all variables of the Expenses class equals to 0.
Probably, it was chaotic but I hope you get the point.
I propose this way to build your code, which not only solves your main problems but also complies with python's style guide and makes better use of classes' capabilities and functionalities (although for simplicity I've omitted handling of exceptions):
from dataclasses import dataclass, field
@dataclass
class Income:
incomes: list[int] = field(default_factory=list)
def sum_incomes(self):
return sum(self.incomes)
def add_income(self, income):
self.incomes.append(income)
def modify_income(self, number, income):
self.incomes[number] = income
@dataclass
class Expenses:
expenses: list[int] = field(default_factory=list)
def sum_expenses(self):
return sum(self.expenses)
def add_expense(self, expense):
self.expenses.append(expense)
def modify_expense(self, number, expense):
self.expenses[number] = expense
@dataclass
class Balance(Income, Expenses):
def sum_balance(self):
return self.sum_incomes() - self.sum_expenses()
user = Balance()
user.add_income(50)
user.add_expense(100)
print(user.sum_incomes())
# 50
print(user.sum_balance())
# -50
user.modify_income(0, 200)
print(user.sum_balance())
# 100