Advertisement
UniQuet0p1

Untitled

Nov 16th, 2020
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. """Bank."""
  2. import datetime
  3. import random
  4.  
  5.  
  6. class PersonError(Exception):
  7. """Person error."""
  8. pass
  9.  
  10.  
  11. class TransactionError(Exception):
  12. """Transaction error."""
  13. pass
  14.  
  15.  
  16. class Person:
  17. """Person class."""
  18.  
  19. def __init__(self, first_name: str, last_name: str, age: int):
  20. """
  21. Person constructor.
  22.  
  23. :param first_name: first name
  24. :param last_name: last name
  25. :param age: age, must be greater than 0
  26. """
  27. if age <= 0:
  28. raise PersonError("Age is lower or equal to 0")
  29. self.first_name = first_name
  30. self.last_name = last_name
  31. self.bank_account = None
  32. self._age = age
  33.  
  34. @property
  35. def full_name(self) -> str:
  36. """Get person's full name. Combination of first and last name."""
  37. return f"{self.first_name} {self.last_name}"
  38.  
  39. @property
  40. def age(self) -> int:
  41. """Get person's age."""
  42. return self._age
  43.  
  44. @age.setter
  45. def age(self, value: int):
  46. """Set person's age. Must be greater than 0."""
  47. if value <= 0 and value < self._age:
  48. raise PersonError("Age is lower or equal to 0")
  49. else:
  50. self._age = value
  51.  
  52. def __repr__(self) -> str:
  53. """
  54. Person representation.
  55.  
  56. :return: person's full name
  57. """
  58. return f"{self.first_name} {self.last_name}"
  59.  
  60.  
  61. class Bank:
  62. """Bank class."""
  63.  
  64. def __init__(self, name: str):
  65. """
  66. Bank constructor.
  67.  
  68. :param name: name of the bank
  69. """
  70. self.name = name
  71. self.customers = []
  72. self.transactions = []
  73.  
  74. def add_customer(self, person: Person) -> bool:
  75. """
  76. Add customer to bank.
  77.  
  78. :param person: person object
  79. :return: was customer successfully added
  80. """
  81. if person not in self.customers:
  82. self.customers.append(person)
  83. person.bank_account = Account(0, person, self)
  84. return True
  85. else:
  86. return False
  87.  
  88. def remove_customer(self, person: Person) -> bool:
  89. """
  90. Remove customer from bank.
  91.  
  92. :param person: person object
  93. :return: was customer successfully removed
  94. """
  95. if person in self.customers:
  96. person.bank_account = None
  97. self.customers.remove(person)
  98. return True
  99. else:
  100. return False
  101.  
  102. def __repr__(self) -> str:
  103. """
  104. Bank representation.
  105.  
  106. :return: name of the bank
  107. """
  108. return self.name
  109.  
  110.  
  111. class Transaction:
  112. """Transaction class."""
  113.  
  114. def __init__(self, amount: float, date: datetime.date, sender_account: 'Account', receiver_account: 'Account',
  115. is_from_atm: bool):
  116. """
  117. Transaction constructor.
  118.  
  119. :param amount: value
  120. :param date: date of the transaction
  121. :param sender_account: sender's object
  122. :param receiver_account: receiver's object
  123. :param is_from_atm: is transaction from atm
  124. """
  125. self.amount = amount
  126. self.date = date
  127. self.sender_account = sender_account
  128. self.receiver_account = receiver_account
  129. self.is_from_atm = is_from_atm
  130.  
  131. def __repr__(self) -> str:
  132. """
  133. Transaction representation.
  134.  
  135. :rtype: object's values displayed in a nice format
  136. """
  137. amount = self.amount
  138. if self.is_from_atm:
  139. amount = self.amount
  140. return f"({amount} €) ATM"
  141. if self.amount <= 0:
  142. amount = -self.amount
  143. return f"({amount} €) {self.sender_account.person.full_name} -> {self.receiver_account.person.full_name}"
  144.  
  145.  
  146. class Account:
  147. """Account class."""
  148.  
  149. def __init__(self, balance: float, person: Person, bank: 'Bank'):
  150. """
  151. Account constructor.
  152.  
  153. :param balance: initial account balance
  154. :param person: person object
  155. :param bank: bank object
  156. """
  157. self._balance = balance
  158. self.person = person
  159. self.bank = bank
  160. self.transactions = []
  161. self.number = self.random_number()
  162.  
  163. @staticmethod
  164. def random_number():
  165. letter = "EE"
  166. letter += str(random.randint(100000000000000000, 999999999999999999))
  167. return letter
  168.  
  169. @property
  170. def balance(self) -> float:
  171. """Get account's balance."""
  172. return self._balance
  173.  
  174. def deposit(self, amount: float, is_from_atm: bool = True):
  175. """Deposit money to account."""
  176. if amount <= 0:
  177. raise TransactionError("Amount is lower or equal to 0")
  178. elif is_from_atm:
  179. transaction = Transaction(amount, datetime.date.today(), self, self, is_from_atm)
  180. self.transactions.append(transaction)
  181. self._balance += amount
  182.  
  183. def withdraw(self, amount: float, is_from_atm: bool = True):
  184. """Withdraw money from account."""
  185. if amount <= 0:
  186. raise TransactionError("Amount is lower or equal to 0")
  187. if amount > self._balance:
  188. raise TransactionError("Amount is lower or equal to 0")
  189. elif is_from_atm:
  190. transaction = Transaction(-amount, datetime.date.today(), self, self, is_from_atm)
  191. self.transactions.append(transaction)
  192. self._balance -= amount
  193.  
  194. def transfer(self, amount: float, receiver_account: 'Account'):
  195. """Transfer money from one account to another."""
  196. if amount <= 0:
  197. raise TransactionError("Amount is lower or equal to 0")
  198. elif self._balance < amount:
  199. raise TransactionError("Amount is lower or equal to 0")
  200. elif receiver_account.bank != self.bank and self._balance < amount + 5:
  201. raise TransactionError("Amount is lower than 5 or not enough money")
  202. elif self == receiver_account:
  203. raise TransactionError("The bank is the same")
  204. else:
  205. transaction = Transaction(-amount, datetime.date.today(), self, receiver_account, False)
  206. self.transactions.append(transaction)
  207. self.bank.transactions.append(transaction)
  208. if receiver_account.bank != self.bank:
  209. self.withdraw(5, False)
  210. receiver_account.deposit(amount, False)
  211. receiver_account.bank.transactions.append(transaction)
  212. receiver_account.transactions.append(transaction)
  213. self.withdraw(amount, False)
  214. receiver_account._balance += amount
  215.  
  216. def account_statement(self, from_date: datetime.date, to_date: datetime.date) -> list:
  217. """All transactions in given period."""
  218. stat = []
  219. for transaction in self.transactions:
  220. if from_date <= transaction.date <= to_date:
  221. stat.append(transaction)
  222. return stat
  223.  
  224. def get_debit_turnover(self, from_date: datetime.date, to_date: datetime.date) -> float:
  225. """
  226. Get total income in given period.
  227.  
  228. :param from_date: from date object (included)
  229. :param to_date: to date object (included)
  230. :return: debit turnover number
  231. """
  232. debit_sum = 0
  233. for each in self.transactions:
  234. if from_date <= each.date <= to_date:
  235. if each.amount >= 0:
  236. debit_sum += each.amount
  237. return debit_sum
  238.  
  239. def get_credit_turnover(self, from_date: datetime.date, to_date: datetime.date) -> float:
  240. """
  241. Get total expenditure in given period.
  242.  
  243. :param from_date: from date object (included)
  244. :param to_date: to date object (included)
  245. :return: credit turnover number
  246. """
  247.  
  248. credit_sum = 0
  249. for each in self.transactions:
  250. if from_date <= each.date <= to_date:
  251. if each.amount <= 0:
  252. credit_sum += each.amount
  253. return credit_sum
  254.  
  255. def get_net_turnover(self, from_date: datetime.date, to_date: datetime.date) -> float:
  256. """
  257. Get net turnover (income - costs) in given period.
  258.  
  259. :param from_date: from date object (included)
  260. :param to_date: to date object (included)
  261. :return: net turnover number
  262. """
  263. net_sum = self.get_debit_turnover(from_date, to_date) + self.get_credit_turnover(from_date, to_date)
  264. return net_sum
  265.  
  266. def __repr__(self) -> str:
  267. """
  268. Account representation.
  269.  
  270. :return: account number
  271. """
  272. return self.number
  273.  
  274.  
  275. def test_defferent_things():
  276. Roman = Person('Roman', 'Malosev', 20)
  277. Alina = Person('Alina', 'Amjaga', 21)
  278. Artjom = Person('Artjom', 'Pagonini', 20)
  279. assert Roman.full_name == 'Roman Malosev'
  280. assert Roman.age == 20
  281. Roman.age = 16
  282. assert Roman.age == 16
  283. bank1 = Bank('Swedbank')
  284. bank2 = Bank('LHV')
  285. bank1.add_customer(Roman)
  286. bank1.add_customer(Artjom)
  287. assert bank1.add_customer(Roman) is False
  288. bank2.add_customer(Alina)
  289. Roman.bank_account.deposit(300)
  290. print(Roman.bank_account.balance)
  291. assert str(Roman.bank_account.transactions[0]) == '(300 €) ATM'
  292. Roman.bank_account.transfer(100, Alina.bank_account)
  293. print(Roman.bank_account.balance)
  294. assert str(Roman.bank_account.transactions[1]) == '(100 €) Roman Malosev -> Alina Amjaga'
  295. Roman.bank_account.transfer(100, Alina.bank_account)
  296. print(Roman.bank_account.balance)
  297. Roman.bank_account.transfer(50, Artjom.bank_account)
  298. print(Roman.bank_account.balance)
  299. print(Roman.bank_account.get_debit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)))
  300. print(Roman.bank_account.get_credit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)))
  301. print(Roman.bank_account.get_net_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)))
  302. assert len(bank1.customers) == 2
  303. assert Roman.bank_account.get_debit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)) == 300
  304. assert Roman.bank_account.get_credit_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)) == -250
  305. assert Roman.bank_account.get_net_turnover(datetime.date(2019, 1, 1), datetime.date(2022, 1, 1)) == 50
  306. bank2.remove_customer(Alina)
  307. assert bank2.customers == []
  308. Roman.bank_account.transfer(10, Artjom.bank_account)
  309. assert Artjom.bank_account.balance == 60
  310.  
  311.  
  312. test_defferent_things()
  313.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement