class SavingsAccount:
"""A savings account whose balance (in cents) can never go below zero."""
def __init__(self, owner, opening_cents=0):
if opening_cents < 0:
raise ValueError("opening balance cannot be negative")
self.owner = owner
self._balance = opening_cents # internal: change only through methods
self._history = []
@property
def balance(self):
"""The current balance in cents (read-only)."""
return self._balance
def deposit(self, cents):
"""Add a positive amount of money."""
if cents <= 0:
raise ValueError("deposit must be positive")
self._balance += cents
self._history.append(("deposit", cents))
def withdraw(self, cents):
"""Remove money; refuse if it would overdraw the account."""
if cents <= 0:
raise ValueError("withdrawal must be positive")
if cents > self._balance:
raise ValueError("insufficient funds")
self._balance -= cents
self._history.append(("withdraw", cents))
def history(self):
"""Return a copy of the list of transactions."""
return list(self._history)
acct = SavingsAccount("Priya", 5000)
acct.deposit(2500)
try:
acct.withdraw(10000)
except ValueError as err:
print("Refused:", err)
acct.withdraw(1500)
print(acct.balance)
print(acct.history())
try:
acct.balance = 999999
except AttributeError:
print("balance is read-only")
savings.py: encapsulated data, a read-only property and validating methods.