Skip to content

Instantly share code, notes, and snippets.

@jbpotonnier
Created April 6, 2014 21:23
Show Gist options
  • Save jbpotonnier/10011636 to your computer and use it in GitHub Desktop.
Save jbpotonnier/10011636 to your computer and use it in GitHub Desktop.
LOCKED = 'locked'
UNLOCKED = 'unlocked'
PUSH = 'push'
COIN = 'coin'
class Fsm(object):
def __init__(self, init_state, transitions, handler=None):
self.state = init_state
self.transitions = transitions
self.handler = handler
def feed(self, input):
next_state = self.transitions[self.state][input]
handler_method = getattr(self.handler,
'{}_{}'.format(self.state, next_state),
None)
self.state = next_state
if handler_method:
handler_method(input)
class TransistionHandler(object):
def locked_unlocked(self, input):
print '{} : transition from locked to unlocked'.format(input)
def unlocked_locked(self, input):
print '{} : transition from unlocked to locked'.format(input)
fsm = Fsm(init_state=LOCKED,
transitions={
LOCKED: {PUSH: LOCKED,
COIN: UNLOCKED},
UNLOCKED: {PUSH: LOCKED,
COIN: UNLOCKED}
},
handler=TransistionHandler())
fsm.feed(COIN)
fsm.feed(PUSH)
from collections import namedtuple
Edge = namedtuple('Edge', 'start end label')
def edges(transitions):
return (Edge(start, end, label)
for (start, evt_end) in transitions.iteritems()
for (label, end) in evt_end.iteritems())
def edge_to_dot(edge):
return '{start} -> {end} [ label = "{label}" ];'.format(**edge._asdict())
def dot_file(filename, transitions):
content = 'digraph finite_state_machine {\n%s\n}' % '\n'.join(edge_to_dot(e) for e in edges(transitions))
with open(filename, 'w') as f:
f.write(content)
dot_file('fsm.dot', fsm.transitions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment