Created
April 6, 2014 21:23
-
-
Save jbpotonnier/10011636 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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