Entering a state usually does something: paying charges the card, shipping sends an email. Attach entry actions: callbacks that run when the machine arrives in a state. fire already invokes them; you register them.
on_enter(state, callback): register a callback (called with the order) to run whenever the order enters state; multiple callbacks on the same state run in registration orderclass Order:
TRANSITIONS = {
"cart": {"checkout": "pending"},
"pending": {"pay": "paid", "cancel": "cancelled"},
"paid": {"ship": "shipped", "refund": "cancelled"},
"shipped": {"deliver": "delivered"},
"delivered": {},
"cancelled": {},
}
def __init__(self):
self.state = "cart"
self.history = ["cart"]
self._enter_callbacks = {} # state -> list of callbacks
def fire(self, event):
allowed = self.TRANSITIONS.get(self.state, {})
if event not in allowed:
return False
self.state = allowed[event]
self.history.append(self.state)
for callback in self._enter_callbacks.get(self.state, []):
callback(self)
return True
def on_enter(self, state, callback):
"""Register a callback to run when the order enters the given state."""
# TODO: self._enter_callbacks.setdefault(state, []).append(callback)
pass
def can(self, event):
return event in self.TRANSITIONS.get(self.state, {})
def available_events(self):
return list(self.TRANSITIONS.get(self.state, {}).keys())
def is_terminal(self):
return len(self.TRANSITIONS.get(self.state, {})) == 0
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Entering a state usually does something: paying charges the card, shipping sends an email. Attach entry actions: callbacks that run when the machine arrives in a state. fire already invokes them; you register them.
on_enter(state, callback): register a callback (called with the order) to run whenever the order enters state; multiple callbacks on the same state run in registration orderPress Run Tests or ββ© to check your solution.