ScatterHQ / machinist

A library for constructing finite state machines
Apache License 2.0
57 stars 12 forks source link

Add an introduction and a very simple example #32

Closed exarkun closed 10 years ago

exarkun commented 10 years ago

The travis configuration is wrong in some way I don't understand, though. It does the sphinx jobs on Python 2.7 and PyPy despite the matrix exclude directive.

coveralls commented 10 years ago

Coverage Status

Coverage remained the same when pulling eb53097367cced5b3bed420da4bd062af379532f on simple-examples-3 into ddc85505ee40b5be706bb8f67316a71e421ffae8 on master.

wallrj commented 10 years ago

I saw a similar travis config issue when I was trying to configure Travis for Twisted.

See https://github.com/travis-ci/travis-ci/issues/1228#issuecomment-23571014

This may be the same bug (as yet unfixed).

wallrj commented 10 years ago

Thanks @exarkun.

Notes:

Points:

  1. The turnstile.py example still isn't runnable, so it's difficult to say whether the changes to it and the README.rst are correct. Have you got turnstilelib.py anywhere so that I can test it? And if you've got it, then why not just add it alongside turnstile.py?
  2. Maybe add a readthedocs link / badge to the README (if you intend to publish to RTD)
  3. The new step-by-step example in basics.rst is very nice, and it was interesting to see how you use the sphinx doctest extension for that. What would be even more useful is if it could compile a complete downloadable example script from the snippets in the narrative above. Is that possible? Anyway, I put the snippets together manually and ran them with the correct output. (see below)

So, anyway, I think this is a great improvement. Please answer or address the comments above and then I'd be happy to see it merged.

Results of doctest builder run on 2014-06-02 15:38:01
=====================================================

Document: basics
----------------
1 items passed all tests:
   8 tests in turnstile
8 tests in 1 items.
8 passed and 0 failed.
Test passed.

Doctest summary
===============
    8 tests
    0 failures in tests
    0 failures in setup code
    0 failures in cleanup code
from __future__ import print_function
from twisted.python.constants import Names, NamedConstant

from machinist import TransitionTable
from machinist import MethodSuffixOutputer
from machinist import constructFiniteStateMachine

class Input(Names):
    FARE_PAID = NamedConstant()
    ARM_UNLOCKED = NamedConstant()
    ARM_TURNED = NamedConstant()
    ARM_LOCKED = NamedConstant()

class Output(Names):
    ENGAGE_LOCK = NamedConstant()
    DISENGAGE_LOCK = NamedConstant()

class State(Names):
    LOCKED = NamedConstant()
    UNLOCKED = NamedConstant()
    ACTIVE = NamedConstant()

class Outputer(object):
    def output_ENGAGE_LOCK(self, engage):
        print("Engaging the lock.")

    def output_DISENGAGE_LOCK(self, disengage):
        print("Disengaging the lock.")

def main():
    table = TransitionTable()

    table = table.addTransition(
        State.LOCKED, Input.FARE_PAID, [Output.DISENGAGE_LOCK], State.ACTIVE)

    table = table.addTransition(
        State.UNLOCKED, Input.ARM_TURNED, [Output.ENGAGE_LOCK], State.ACTIVE)

    table = table.addTransitions(
        State.ACTIVE, {
            Input.ARM_UNLOCKED: ([], State.UNLOCKED),
            Input.ARM_LOCKED: ([], State.LOCKED),
        })

    outputer = MethodSuffixOutputer(Outputer())

    turnstile = constructFiniteStateMachine(
        inputs=Input,
        outputs=Output,
        states=State,
        table=table,
        initial=State.LOCKED,
        richInputs=[],
        inputContext={},
        world=outputer,
    )

    turnstile.receive(Input.FARE_PAID)
    turnstile.receive(Input.ARM_UNLOCKED)
    turnstile.receive(Input.ARM_TURNED)
    turnstile.receive(Input.ARM_LOCKED)

if __name__ == '__main__':
    raise SystemExit(main())
itamarst commented 10 years ago

Sphinx includes support for including source code by Python object, as well as "text in between these two strings" (in particular, comments would be relevant). So this would allow you to have a full file as an example and include only parts of it: http://sphinx-doc.org/markup/code.html#includes

In order to run the doctests, you could add this to tox or travis:

$ python -m doctest -v examples/yourexample.py
exarkun commented 10 years ago

I moved the code for the example into a file and included it piecewise into the document. Doctests are still run with make doctest. You can see the docs from this branch built on http://machinist.readthedocs.org/en/simple-examples-3/index.html

itamarst commented 10 years ago

OK, will take a look.

itamarst commented 10 years ago

OK, address above as necessary and merge if build is green. Looks good!