the-honk/school/a-level/Y13 2021-2023/OOP/Bank Account Controller with Inheritance.py

152 lines
4.9 KiB
Python
Raw Normal View History

2024-10-09 17:02:48 +00:00
from enum import Enum
from abc import ABC
2024-10-09 17:02:47 +00:00
CONFIRMATION_VALIDATOR = lambda x: x.lower() not in ['yes', 'y', 'no', 'n']
2024-10-09 17:02:48 +00:00
class AccountTypes(Enum):
Current = 1
Savings = 2
class Account(ABC):
2024-10-09 17:02:47 +00:00
def __init__(self):
self.__balance = 0
def getBalance(self):
return self.__balance
def setBalance(self, newBalance):
self.__balance = newBalance
2024-10-09 17:02:48 +00:00
class CurrentAccount(Account):
pass
class SavingsAccount(Account):
INTEREST_RATE = 0.02
def __init__(self):
super().__init__()
def calculateInterest(self):
return self.getBalance() * SavingsAccount.INTEREST_RATE
def setBalance(self, newBalance):
if newBalance < 0:
raise ValueError('You can not have a negative balance!')
return super().setBalance(newBalance)
2024-10-09 17:02:47 +00:00
class Controller:
OVERDRAWN_FEE = 5
def __init__(self, account):
self.__account = account
def __overdrawnFee(self):
balance = self.fetchBalance()
if balance < 0:
self.__account.setBalance(balance - Controller.OVERDRAWN_FEE)
return balance < 0
def fetchBalance(self):
return self.__account.getBalance()
def formatBalance(self):
balance = self.fetchBalance()
sign = '' if balance >= 0 else '-'
return f'{sign}£{abs(balance):.2f}'
def payIn(self, amount):
self.__account.setBalance(self.fetchBalance() + amount)
def withdraw(self, amount):
fee = self.__overdrawnFee()
self.__account.setBalance(self.fetchBalance() - amount)
return fee
2024-10-09 17:02:48 +00:00
def accountType(self):
if isinstance(self.__account, CurrentAccount):
return AccountTypes.Current
elif isinstance(self.__account, SavingsAccount):
return AccountTypes.Savings
def addInterest(self):
if isinstance(self.__account, SavingsAccount):
interest = self.__account.calculateInterest()
self.__account.setBalance(self.fetchBalance() + interest)
return interest
else:
return 0
2024-10-09 17:02:47 +00:00
def fetchValue(caster, typeName, prompt, validator = None, validatorFailMessage = None):
while True:
try:
value = caster(input(prompt))
if validator:
if validator(value):
raise ValueError('validator')
return value
except ValueError as e:
if str(e) == 'validator' and validatorFailMessage:
print(validatorFailMessage)
else:
print(f'Please make sure you input a valid {typeName}.')
def displayBalance():
print(f'You currently have a balance of {controller.formatBalance()}!')
def menu():
2024-10-09 17:02:48 +00:00
print(f"""Welcome to the bank! What would you like to do?
2024-10-09 17:02:47 +00:00
1) View your current balance
2) Pay in money
2024-10-09 17:02:48 +00:00
3) Withdraw money""" + ("""
4) Add interest""" if controller.accountType() == AccountTypes.Savings else ""))
2024-10-09 17:02:47 +00:00
2024-10-09 17:02:48 +00:00
choice = fetchValue(int, 'integer', 'Please make your selection: ', lambda x: (x > 5 or x <= 0))
2024-10-09 17:02:47 +00:00
if choice == 1:
displayBalance()
elif choice == 2:
value = fetchValue(float, 'float', 'Please enter the amount of money you would like to pay in: ')
controller.payIn(value)
displayBalance()
elif choice == 3:
value = fetchValue(float, 'float', 'Please enter the amount of money you would like to withdraw: ')
chargedFee = controller.withdraw(value)
if chargedFee:
print(f'You are currently overdrawn! If you go through with this transaction, you will have to pay a fee of £{Controller.OVERDRAWN_FEE:.2f}, and your balance will become {controller.formatBalance()}.')
confirm = fetchValue(str, 'input', 'Would you like to proceed? (y/n)', CONFIRMATION_VALIDATOR)
if confirm in ['n', 'no']:
controller.payIn(value + Controller.OVERDRAWN_FEE)
print('Your transaction has been cancelled!')
else:
displayBalance()
else:
displayBalance()
2024-10-09 17:02:48 +00:00
elif accountType == AccountTypes.Savings and choice == 4:
interest = controller.addInterest()
print(f'Added £{interest:.2f} worth of interest!')
displayBalance()
2024-10-09 17:02:47 +00:00
if __name__ == '__main__':
2024-10-09 17:02:48 +00:00
print("""Please choose an account type:
1) Current Account
2) Savings Account""")
accountType = AccountTypes.Savings if fetchValue(int, 'account type', 'Please select an account type (1-2): ', lambda x: (x < 1 or x > 2)) == 2 else AccountTypes.Current
account = CurrentAccount() if accountType == AccountTypes.Current else SavingsAccount()
controller = Controller(account)
2024-10-09 17:02:47 +00:00
while True:
menu()
again = fetchValue(str, 'input', 'Would you like to go again? (y/n)', CONFIRMATION_VALIDATOR)
if again in ['n', 'no']:
break