summaryrefslogtreecommitdiff
path: root/examples/statemachine
diff options
context:
space:
mode:
Diffstat (limited to 'examples/statemachine')
-rw-r--r--examples/statemachine/statemachine.py32
-rw-r--r--examples/statemachine/trafficLightDemo.py37
-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)