I'm training my skills of design patterns. With a Factory schema i tried to get and pop example numbers from a imited list.
With initialization of seccond account i recieved an IndexError. In debug mote i noticed that between initialisation of acc01 and acc02 I have a 4 uses of AccountManager.number() func. Same with AccountManager.account_id().
from abc import ABC
from random import choice, randint
class AccountsManager:
def __init__(self) -> None:
self._last_id_number = 0
self._allowed_numbers = [randint(10_000, 99_999) for _ in range(5)]
@property
def number(self) -> int:
if not self._allowed_numbers:
raise IndexError
number = choice(self._allowed_numbers)
self._allowed_numbers.pop(self._allowed_numbers.index(number))
return number
@property
def account_id(self) -> int:
account_id = self._last_id_number
self._last_id_number += 1
return account_id
class TemplateBankAccount(ABC):
def __init__(self, manager, owner: str, account_type: str = '') -> None:
self.manager = manager
self.id_number = manager.account_id
self.account_number = manager.number
self.owner = owner
self.account_type = account_type
self._amount = 0
def __str__(self) -> None:
raise NotImplementedError
@property
def amount(self) -> int:
return self._amount
@amount.setter
def amount(self, direction: str, value: int) -> None:
if direction == '+':
self._amount += value
elif direction == '-':
self._amount -= value
else:
raise ValueError
class PersonalBankAccount(TemplateBankAccount):
def __init__(self, manager, owner) -> None:
super().__init__(manager, owner, account_type='Personal Account')
def __str__(self) -> str:
return f'{self.account_type}: {self.owner}'
class CompanyBankAccount(TemplateBankAccount):
def __init__(self, manager, owner) -> None:
super().__init__(manager, owner, account_type='Company Account')
def __str__(self) -> str:
return f'{self.account_type}: owner name restricted.'
class SavingsBankAccount(TemplateBankAccount):
def __init__(self, manager, owner) -> None:
super().__init__(manager, owner, account_type='Savings Account')
def __str__(self) -> str:
return f'{self.account_type}: {self.owner}'
class AccountCreator:
def __init__(self) -> None:
self.manager_group = AccountsManager()
def create_account(self, owner_name, account_type):
allowed_types = {'Personal': PersonalBankAccount(self.manager_group, owner_name),
'Company': CompanyBankAccount(self.manager_group, owner_name),
'Savings': SavingsBankAccount(self.manager_group, owner_name)}
return allowed_types.get(account_type, 'Non offered account type')
def main() -> None:
creator = AccountCreator()
create_account = creator.create_account
acc_01 = create_account('Andrew Wiggins', 'Personal')
acc_02 = create_account('NASA Inc.', 'Company')
acc_03 = create_account('John Paul Wieczorek', 'Savings')
list_of_accounts = [str(account) for account in (acc_01, acc_02, acc_03)]
print('\n'.join(list_of_accounts))
if __name__ == '__main__':
main()
I do not know how to change code to get values from self._last_id_number and self._allowed_numbers only once per create_account call.
Aucun commentaire:
Enregistrer un commentaire