from peak.events.trellis import *
##
## Example #1: Bank accounts and policy enforcement (validation)
##
class Account(Component):
balance = attr(0)
interest_rate = attr(1.0)
policy = attr()
@maintain
def enforce_policy(self):
if self.policy is not None:
self.policy.check_account(self)
class StrictPolicy(Component):
min_balance = attr(200)
def check_account(self, account):
if account.balance < self.min_balance:
raise ValueError("Can't withdraw funds")
class RelaxedPolicy(Component):
min_balance = attr(500)
# This rate only applies if balance > min_balance
interest_rate = attr(1.05)
def check_account(self, account):
if account.balance < 0:
raise ValueError("Can't have negative balance")
if account.balance >= self.min_balance:
account.interest_rate = self.interest_rate
else:
account.interest_rate = 1.0
class CreditPolicy(Component):
# This rate applies to accounts with negative balance
interest_rate = attr(0.85)
def check_account(self, account):
if account.balance < 0:
account.interest_rate = self.interest_rate
else:
account.interest_rate = 1.0
##########################################
##########################################
from nose.tools import *
acc = Account(balance=1000, policy=StrictPolicy())
assert_raises(ValueError, setattr, acc, 'balance', 100)
assert acc.balance == 1000
assert acc.interest_rate == 1.0
acc.policy = RelaxedPolicy()
assert acc.interest_rate == 1.05
acc.policy.min_balance = 2000
assert acc.interest_rate == 1.0
acc.balance = 100
assert_raises(ValueError, setattr, acc, 'balance', -100)
acc.policy = CreditPolicy()
assert acc.interest_rate == 1.0
acc.balance = -100
assert acc.interest_rate == 0.85