What Can I Do Here?

Step 2: What Can I Do Here?

A state machine is most useful when it can tell you what is possible right now, to enable the right buttons, or know when an order is finished. All three answers come straight from the transition table for the current state.

  • can(event): is event allowed from the current state?
  • available_events(): the list of events allowed right now
  • is_terminal(): true when the current state has no outgoing events
Hints
Starter code
class 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"

    def fire(self, event):
        allowed = self.TRANSITIONS.get(self.state, {})
        if event in allowed:
            self.state = allowed[event]
            return True
        return False

    def can(self, event):
        """Is this event allowed from the current state?"""
        # TODO: return event in self.TRANSITIONS.get(self.state, {})
        pass

    def available_events(self):
        """List the events allowed from the current state."""
        # TODO: return list(self.TRANSITIONS.get(self.state, {}).keys())
        pass

    def is_terminal(self):
        """True when no events are possible from the current state."""
        # TODO: return len(self.TRANSITIONS.get(self.state, {})) == 0
        pass
Write it on a laptop

The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.