This tutorial will describe how to create and test a lightweight, object-oriented state machine implementation in Python.

Create State Machine

First, you need to install transitions and import it to your python project.

pip install transitions
from transitions import Machine

Then, we define the states in a class. In this example, we create a state machine where you work out.

Create the class and define the states:

class WorkOut(object):
    states = ['relaxing', 'work_out']

First, we create the machine. This needs to be done in the constructor.

def __init__(self):
    self.machine = Machine(model=self, states=WorkOut.states, initial='relaxing')

Here, you specify the class, the states, and the initial state.

We also have to specify transitions. This is where you specify where you can go from one state to another.

self.machine.add_transition(trigger='go_work_out', source='relaxing', dest='work_out', after='work_out_session')

This way you can choose which state you need to be in to trigger the transition, what the trigger is, as well as the destination and functions to run after the transition is done. So to use this transition, we need to be in the relaxing state, and we need a function work_out_session.

self.machine.add_transition(trigger='complete_training', source='work_out', dest='relaxing')

In this line, you trigger the transition with complete_training, and you need to be in state work_out.

In the work_out_session function, we sleep for 3 seconds (you will have to to import time to your script) and then we trigger the complete-training transition.

def work_out_session(self):
    print "Start workout: %s" % time.ctime()

    print("In state: " +  self.state)
    time.sleep( 3 )

    print "End workout: %s" % time.ctime()
    self.work_out_times +=1

    #Change state again, after 3 seconds of training
    self.complete_training();

All together, this is the code we need:

from transitions import Machine
import time

class WorkOut(object):

    # Define some states. 
    states = ['relaxing', 'work_out']

    def __init__(self):

        # How many times have we worked out this time?
        self.work_out_times= 0

        # Initialize the state machine
        self.machine = Machine(model=self, states=WorkOut.states, initial='relaxing')

        # Add some transitions. See documentation

        # At some point, every superhero must rise and shine and go work out. 
        # Note that we after we go to the work_out state, we run the work_out_session-function.
        self.machine.add_transition(trigger='go_work_out', source='relaxing', dest='work_out', after='work_out_session')

        #Complete training. 
        self.machine.add_transition(trigger='complete_training', source='work_out', dest='relaxing')



    def work_out_session(self):
        print "Start workout: %s" % time.ctime()

        print("In state: " +  self.state);
        time.sleep( 3 );

        print "End Workout: %s" % time.ctime();
        self.work_out_Times +=1;

        #Change state again, after 3 seconds of training. 
        self.complete_training();

Testing the State Machine

To test the state machine, you can run this code:

from <The filename of the file where you created WorkOut> import WorkOut

#create object of the Workout State machine
wo = WorkOut()

#Check which state the state machine starts in.

print "The first state in the state machine is: %s" % wo.state

#Start to work out/Change State. 
wo.go_work_out();

print "Done working out, in state: %s \nYou have worked out %s times." % (wo.state, str(wo.work_out_times))

#Now you can keep working out as much as you want: 

for i in range(0, 5):
    wo.go_work_out();
    print "Done working out, in state: %s \nYou have worked out %s times." % (wo.state, str(wo.work_out_times))

In this script, you can see that you call a transition by triggering the name of the state machine instance.

wo.go_work_out() –> runs the go_work_out() transition.