Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """Bank."""
- import datetime
- import random
- class PersonError(Exception):
- """Person error."""
- pass
- class TransactionError(Exception):
- """Transaction error."""
- pass
- class Person:
- """Person class."""
- def __init__(self, first_name: str, last_name: str, age: int):
- """
- Person constructor.
- :param first_name: first name
- :param last_name: last name
- :param age: age, must be greater than 0
- """
- if age <= 0:
- raise PersonError("Age is lower or equal to 0")
- self.first_name = first_name
- self.last_name = last_name
- self.bank_account = None
- self._age = age
- @property
- def full_name(self) -> str:
- """Get person's full name. Combination of first and last name."""
- return f"{self.first_name} {self.last_name}"
- @property
- def age(self) -> int:
- """Get person's age."""
- return self._age
- @age.setter
- def age(self, value: int):
- """Set person's age. Must be greater than 0."""
- if value <= 0 and value < self._age:
- raise PersonError("Age is lower or equal to 0")
- else:
- self._age = value
- def __repr__(self) -> str:
- """
- Person representation.
- :return: person's full name
- """
- return f"{self.first_name} {self.last_name}"
- class Bank:
- """Bank class."""
- def __init__(self, name: str):
- """
- Bank constructor.
- :param name: name of the bank
- """
- self.name = name
- self.customers = []
- self.transactions = []
- def add_customer(self, person: Person) -> bool:
- """
- Add customer to bank.
- :param person: person object
- :return: was customer successfully added
- """
- if person not in self.customers:
- self.customers.append(person)
- person.bank_account = Account(0, person, self)
- return True
- else:
- return False
- def remove_customer(self, person: Person) -> bool:
- """
- Remove customer from bank.
- :param person: person object
- :return: was customer successfully removed
- """
- if person in self.customers:
- person.bank_account = None
- self.customers.remove(person)
- return True
- else:
- return False
- def __repr__(self) -> str:
- """
- Bank representation.
- :return: name of the bank
- """
- return self.name
- class Transaction:
- """Transaction class."""
- def __init__(self, amount: float, date: datetime.date, sender_account: 'Account', receiver_account: 'Account',
- is_from_atm: bool):
- """
- Transaction constructor.
- :param amount: value
- :param date: date of the transaction
- :param sender_account: sender's object
- :param receiver_account: receiver's object
- :param is_from_atm: is transaction from atm
- """
- self.amount = amount
- self.date = date
- self.sender_account = sender_account
- self.receiver_account = receiver_account
- self.is_from_atm = is_from_atm
- def __repr__(self) -> str:
- """
- Transaction representation.
- :rtype: object's values displayed in a nice format
- """
- amount = self.amount
- if self.is_from_atm:
- amount = self.amount
- return f"({amount} β¬) ATM"
- if self.amount <= 0:
- amount = -self.amount
- return f"({amount} β¬) {self.sender_account.person.full_name} -> {self.receiver_account.person.full_name}"
- class Account:
- """Account class."""
- def __init__(self, balance: float, person: Person, bank: 'Bank'):
- """
- Account constructor.
- :param balance: initial account balance
- :param person: person object
- :param bank: bank object
- """
- self._balance = balance
- self.person = person
- self.bank = bank
- self.transactions = []
- self.number = self.random_number()
- @staticmethod
- def random_number():
- letter = "EE"
- letter += str(random.randint(100000000000000000, 999999999999999999))
- return letter
- @property
- def balance(self) -> float:
- """Get account's balance."""
- return self._balance
- def deposit(self, amount: float, is_from_atm: bool = True):
- """Deposit money to account."""
- if amount <= 0:
- raise TransactionError("Amount is lower or equal to 0")
- elif is_from_atm:
- transaction = Transaction(amount, datetime.date.today(), self, self, is_from_atm)
- self.transactions.append(transaction)
- self._balance += amount
- def withdraw(self, amount: float, is_from_atm: bool = True):
- """Withdraw money from account."""
- if amount <= 0:
- raise TransactionError("Amount is lower or equal to 0")
- if amount > self._balance:
- raise TransactionError("Amount is lower or equal to 0")
- elif is_from_atm:
- transaction = Transaction(-amount, datetime.date.today(), self, self, is_from_atm)
- self.transactions.append(transaction)
- self._balance -= amount
- def transfer(self, amount: float, receiver_account: 'Account'):
- """Transfer money from one account to another."""
- if amount <= 0:
- raise TransactionError("Amount is lower or equal to 0")
- elif self._balance < amount:
- raise TransactionError("Amount is lower or equal to 0")
- elif receiver_account.bank != self.bank and self._balance < amount + 5:
- raise TransactionError("Amount is lower than 5 or not enough money")
- elif self == receiver_account:
- raise TransactionError("The bank is the same")
- else:
- transaction = Transaction(-amount, datetime.date.today(), self, receiver_account, False)
- self.transactions.append(transaction)
- self.bank.transactions.append(transaction)
- if receiver_account.bank != self.bank:
- self.withdraw(5, False)
- receiver_account.deposit(amount, False)
- receiver_account.bank.transactions.append(transaction)
- receiver_account.transactions.append(transaction)
- self.withdraw(amount, False)
- receiver_account._balance += amount
- def account_statement(self, from_date: datetime.date, to_date: datetime.date) -> list:
- """All transactions in given period."""
- stat = []
- for transaction in self.transactions:
- if from_date <= transaction.date <= to_date:
- stat.append(transaction)
- return stat
- def get_debit_turnover(self, from_date: datetime.date, to_date: datetime.date) -> float:
- """
- Get total income in given period.
- :param from_date: from date object (included)
- :param to_date: to date object (included)
- :return: debit turnover number
- """
- debit_sum = 0
- for each in self.transactions:
- if from_date <= each.date <= to_date:
- if each.amount >= 0:
- debit_sum += each.amount
- return debit_sum
- def get_credit_turnover(self, from_date: datetime.date, to_date: datetime.date) -> float:
- """
- Get total expenditure in given period.
- :param from_date: from date object (included)
- :param to_date: to date object (included)
- :return: credit turnover number
- """
- credit_sum = 0
- for each in self.transactions:
- if from_date <= each.date <= to_date:
- if each.amount <= 0:
- credit_sum += each.amount
- return credit_sum
- def get_net_turnover(self, from_date: datetime.date, to_date: datetime.date) -> float:
- """
- Get net turnover (income - costs) in given period.
- :param from_date: from date object (included)
- :param to_date: to date object (included)
- :return: net turnover number
- """
- net_sum = self.get_debit_turnover(from_date, to_date) + self.get_credit_turnover(from_date, to_date)
- return net_sum
- def __repr__(self) -> str:
- """
- Account representation.
- :return: account number
- """
- return self.number
- def test_defferent_things():
- Roman = Person('Roman', 'Malosev', 20)
- Alina = Person('Alina', 'Amjaga', 21)
- Artjom = Person('Artjom', 'Pagonini', 20)
- assert Roman.full_name == 'Roman Malosev'
- assert Roman.age == 20
- Roman.age = 16
- assert Roman.age == 16
- bank1 = Bank('Swedbank')
- bank2 = Bank('LHV')
- bank1.add_customer(Roman)
- bank1.add_customer(Artjom)
- assert bank1.add_customer(Roman) is False
- bank2.add_customer(Alina)
- Roman.bank_account.deposit(300)
- print(Roman.bank_account.balance)
- assert str(Roman.bank_account.transactions[0]) == '(300 β¬) ATM'
- Roman.bank_account.transfer(100, Alina.bank_account)
- print(Roman.bank_account.balance)
- assert str(Roman.bank_account.transactions[1]) == '(100 β¬) Roman Malosev -> Alina Amjaga'
- Roman.bank_account.transfer(100, Alina.bank_account)
- print(Roman.bank_account.balance)
- Roman.bank_account.transfer(50, Artjom.bank_account)
- print(Roman.bank_account.balance)
- print(Roman.bank_account.get_debit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)))
- print(Roman.bank_account.get_credit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)))
- print(Roman.bank_account.get_net_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)))
- assert len(bank1.customers) == 2
- assert Roman.bank_account.get_debit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)) == 300
- assert Roman.bank_account.get_credit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)) == -250
- assert Roman.bank_account.get_net_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)) == 50
- bank2.remove_customer(Alina)
- assert bank2.customers == []
- Roman.bank_account.transfer(10, Artjom.bank_account)
- assert Artjom.bank_account.balance == 60
- test_defferent_things()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement