Skip to content

Instantly share code, notes, and snippets.

@azylinski
Created March 18, 2024 09:48
Show Gist options
  • Save azylinski/1c09e4ffd552d3a382ff3844ccc76268 to your computer and use it in GitHub Desktop.
Save azylinski/1c09e4ffd552d3a382ff3844ccc76268 to your computer and use it in GitHub Desktop.
katas/bank
import datetime
from dataclasses import dataclass
# exceptions.py
class NoMoneyException(Exception):
pass
class InvalidValueException(Exception):
pass
@dataclass
class TransactionLog:
created_at: datetime.datetime
amount: int
# 14/01/2012 || -500 || 2500
def print(self, current_balance):
return f"{self.created_at} || {self.amount} || {current_balance}\n"
NO_TRANSACTIONS_MSG = "no transactions yet"
class AccountService:
transactionLog : list[TransactionLog]
blanace : int # RO: current balance; to speed up validation
def __init__(self):
self.transactionLog = []
self.blanace = 0
def deposit(self, amount:int):
if amount <= 0:
raise InvalidValueException(f"amount must be positive; got: {amount}")
self._update_balance(amount)
def withdraw(self, amount:int):
if amount <= 0:
raise InvalidValueException(f"amount must be positive; got: {amount}")
if amount > self.blanace:
raise NoMoneyException(f"not enough money on the accout; want: {amount} got {self.blanace}")
self._update_balance(-amount)
def printStatement(self):
# TODO: max transactions
# TODO: print from latest
if len(self.transactionLog) == 0:
return NO_TRANSACTIONS_MSG
self._prepre_for_print()
log = self.transactionLog # deepcopy
log.reverse()
out = "Date || Amount || Balance\n"
current_balance = self.blanace
for tl in log:
out += tl.print(current_balance)
current_balance += -tl.amount
return out
def _update_balance(self, amount:int):
# TODO: wrap for test with static time
time_now = datetime.datetime.now()
tl = TransactionLog(
created_at=time_now,
amount=amount,
)
self.transactionLog.append(tl)
self.blanace += amount
def test_NoTransactions():
ac = AccountService()
got = ac.printStatement()
want = NO_TRANSACTIONS_MSG
assert got == want
def test_NoMoneyValidation():
ac = AccountService()
ac.deposit(100)
# assert NoMoneyException:
# ac.withdraw(300)
def test_SingleTransaction():
ac = AccountService()
ac.deposit(100)
want = """
Date || Amount || Balance
14/01/2012 || 100 || 100
"""
got = ac.printStatement()
assert got == want
def test_ProvidedInput():
ac = AccountService()
ac.deposit(1000)
ac.deposit(2000)
ac.withdraw(500)
want = """
Date || Amount || Balance
14/01/2012 || -500 || 2500
13/01/2012 || 2000 || 3000
10/01/2012 || 1000 || 1000
"""
got = ac.printStatement()
assert got == want
# #2: validation: not an int; float, "above limit" (max-int), ...
# #3: possive scenario: 10x deposits, 10x withdraw, print - expect 0 balance left; expect 20 lines in print...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment