diff options
Diffstat (limited to 'examples/statemachine')
-rw-r--r-- | examples/statemachine/statemachine.py | 32 | ||||
-rw-r--r-- | examples/statemachine/trafficLightDemo.py | 37 | ||||
-rw-r--r-- | examples/statemachine/trafficlightstate.pystate (renamed from examples/statemachine/trafficlight.pystate) | 20 |
3 files changed, 60 insertions, 29 deletions
diff --git a/examples/statemachine/statemachine.py b/examples/statemachine/statemachine.py index 7565375..62ad22b 100644 --- a/examples/statemachine/statemachine.py +++ b/examples/statemachine/statemachine.py @@ -7,15 +7,18 @@ import keyword import sys import os import types +import importlib try: import urllib.parse url_parse = urllib.parse.urlparse except ImportError: + print("import error, Python 2 not supported") + raise import urllib url_parse = urllib.parse -DEBUG = True #False +DEBUG = False from pyparsing import Word, Group, ZeroOrMore, alphas, \ alphanums, ParserElement, ParseException, ParseSyntaxException, \ @@ -54,7 +57,7 @@ def expand_state_definition(source, loc, tokens): fromTo[tn.fromState] = tn.toState # define base class for state classes - baseStateClass = tokens.name + "State" + baseStateClass = tokens.name statedef.extend([ "class %s(object):" % baseStateClass, " def __str__(self):", @@ -63,15 +66,12 @@ def expand_state_definition(source, loc, tokens): " return self._next_state_class()"]) # define all state classes - statedef.extend( - "class {}({}): pass".format(s, baseStateClass) - for s in states) - statedef.extend( - "{}._next_state_class = {}".format(s, fromTo[s]) - for s in states if s in fromTo) + statedef.extend("class {}({}): pass".format(s, baseStateClass) for s in states) - return indent + ("\n" + indent).join(statedef) + "\n" + # define state->state transitions + statedef.extend("{}._next_state_class = {}".format(s, fromTo[s]) for s in states if s in fromTo) + return indent + ("\n" + indent).join(statedef) + "\n" stateMachine.setParseAction(expand_state_definition) @@ -83,7 +83,7 @@ def expand_named_state_definition(source, loc, tokens): states = set() transitions = set() - baseStateClass = tokens.name + "State" + baseStateClass = tokens.name fromTo = {} for tn in tokens.transitions: @@ -147,9 +147,7 @@ def expand_named_state_definition(source, loc, tokens): return indent + ("\n" + indent).join(statedef) + "\n" - -namedStateMachine.setParseAction( - expand_named_state_definition) +namedStateMachine.setParseAction(expand_named_state_definition) # ====================================================================== @@ -196,9 +194,9 @@ class SuffixImporter(object): # entry is thus a path to a directory on the filesystem; # if it's not None, then some other importer is in charge, and # it probably isn't even a filesystem path - if sys.path_importer_cache.get(dirpath, False) is None: - checkpath = os.path.join( - dirpath, '{}.{}'.format(fullname, self.suffix)) + finder = sys.path_importer_cache.get(dirpath) + if isinstance(finder, (type(None), importlib.machinery.FileFinder)): + checkpath = os.path.join(dirpath, '{}.{}'.format(fullname, self.suffix)) yield checkpath def find_module(self, fullname, path=None): @@ -255,4 +253,4 @@ class PystateImporter(SuffixImporter): PystateImporter.register() -print("registered {!r} importer".format(PystateImporter.suffix))
\ No newline at end of file +# print("registered {!r} importer".format(PystateImporter.suffix)) diff --git a/examples/statemachine/trafficLightDemo.py b/examples/statemachine/trafficLightDemo.py index 30fe934..ea42180 100644 --- a/examples/statemachine/trafficLightDemo.py +++ b/examples/statemachine/trafficLightDemo.py @@ -1,12 +1,35 @@ +# +# trafficLightDemo.py +# +# Example of a simple state machine modeling the state of a traffic light +# + import statemachine -import trafficlight +import trafficlightstate + + +class TrafficLight: + def __init__(self): + # start light in Red state + self._state = trafficlightstate.Red() + + def change(self): + self._state = self._state.next_state() + + # get light behavior/properties from current state + def __getattr__(self, attrname): + return getattr(self._state, attrname) + + def __str__(self): + return "{}: {}".format(self.__class__.__name__, self._state) + -tl = trafficLight.Red() +light = TrafficLight() for i in range(10): - print(tl, end='') - print(("STOP", "GO")[tl.carsCanGo]) - tl.crossingSignal() - tl.delay() + print(light, end=' ') + print(("STOP", "GO")[light.carsCanGo]) + light.crossingSignal() + light.delay() print() - tl = tl.nextState() + light.change() diff --git a/examples/statemachine/trafficlight.pystate b/examples/statemachine/trafficlightstate.pystate index 3de7b7f..d0f0a35 100644 --- a/examples/statemachine/trafficlight.pystate +++ b/examples/statemachine/trafficlightstate.pystate @@ -1,10 +1,22 @@ -# define state machine -statemachine TrafficLight: +# +# trafficlightstate.pystate +# +# state machine model of the states and associated behaviors and properties for each +# different state of a traffic light + + +# define state machine with transitions +# (states will be implemented as Python classes, so use name case appropriate for class names) +statemachine TrafficLightState: Red -> Green Green -> Yellow Yellow -> Red +# statemachine only defines the state->state transitions - actual behavior and properties +# must be added separately + + # define some class level constants Red.carsCanGo = False Yellow.carsCanGo = True @@ -18,7 +30,6 @@ def flashCrosswalk(s): return flash - Red.crossingSignal = staticmethod(flashCrosswalk("WALK")) Yellow.crossingSignal = staticmethod(flashCrosswalk("DONT WALK")) Green.crossingSignal = staticmethod(flashCrosswalk("DONT WALK")) @@ -31,7 +42,6 @@ def wait(nSeconds): return waitFn - Red.delay = wait(20) Yellow.delay = wait(3) -Green.delay = wait(15)
\ No newline at end of file +Green.delay = wait(15) |