Coding a simple state machine in python

R

Ronaldo

How do I write a state machine in python? I have identified the states and the conditions. Is it possible to do simple a if-then-else sort of an algorithm? Below is some pseudo code:

if state == "ABC":
do_something()
change state to DEF

if state == "DEF"
perform_the_next_function()
....

I have a class to which certain values are passed from a GUI and the functions above have to make use of those variables. How do I go about doing this? I have the following algorithm:

class TestClass():
def __init__(self, var1, var2): #var1 and var2 are received from a GUI
self.var1 = var1
....
if state == "ABC"
doSomething(var1, var2)
...

Could someone point me in the right direction? Thank you!
 
T

Tim Daneliuk

How do I write a state machine in python? I have identified the states and the conditions. Is it possible to do simple a if-then-else sort of an algorithm? Below is some pseudo code:

if state == "ABC":
do_something()
change state to DEF

if state == "DEF"
perform_the_next_function()
...

I have a class to which certain values are passed from a GUI and the functions above have to make use of those variables. How do I go about doing this? I have the following algorithm:

class TestClass():
def __init__(self, var1, var2): #var1 and var2 are received from a GUI
self.var1 = var1
...
if state == "ABC"
doSomething(var1, var2)
..

Could someone point me in the right direction? Thank you!

There are probably lots of ways to do it, but I'd use a dictionary and
a variable to hold the current state:

CURRENT_STATE = "Start"
DFA_STATE_MACHINE = {"Start" : start_fn, "State1" : state1_fn, "State2" : state2_fn ....}

#####
# Functions for each state go here. They end by setting CURRENT_STATE to some value
#####

def start_fn():
..
..
..


def state1_fn():

..
..
..


# And so on


# Now run the state machine

while ( CURRENT_STATE != "Done"):

# Execute the function for the current state

DFA_STATE_MACHINE[CURRENT_STATE]()


Like I said, there are other - more compact ways - to do this, but this
is the general idea. Now - go do your own homework :)
 
T

Tim Daneliuk

And, to extend Tim's suggestion of a dictionary just a bit, note that since Python functions are happy to pass function names as arguments, you can use a dictionary to make a really nice compact dispatch table. That is, function A does its thing, gets to a new state, and returns as one of its return arguments the key into the dictionary that points to the next function_name to be called based on that new state.

Stackoverflow has a couple of compact examples here:

http://stackoverflow.com/questions/...t-a-dispatch-table-in-your-language-of-choice

Bill


Now you're making it TOO easy Bill ;)
 
T

Tim Daneliuk

And, to extend Tim's suggestion of a dictionary just a bit, note that since Python functions are happy to pass function names as arguments, you can use a dictionary to make a really nice compact dispatch table. That is, function A does its thing, gets to a new state, and returns as one of its return arguments the key into the dictionary that points to the next function_name to be called based on that new state.

Stackoverflow has a couple of compact examples here:

http://stackoverflow.com/questions/...t-a-dispatch-table-in-your-language-of-choice

Bill


Now you're making it TOO easy Bill ;)
 
P

Peter Otten

William said:
And, to extend Tim's suggestion of a dictionary just a bit, note that
since Python functions are happy to pass function names as arguments, you
can use a dictionary to make a really nice compact dispatch table. That
is, function A does its thing, gets to a new state, and returns as one of
its return arguments the key into the dictionary that points to the next
function_name to be called based on that new state.

Stackoverflow has a couple of compact examples here:

http://stackoverflow.com/questions/715457/how-do-you-implement-a-dispatch-
table-in-your-language-of-choice

Why have the function return a name? Why not just another function?
 
M

Marko Rauhamaa

Peter Otten said:
Why have the function return a name? Why not just another function?

As people have said, there are many ways to skin the cat.

A function can represent a state if it is the only type of event the
state machine must process. A regular expression parser would be an
example.

In the general case, a state machine is a matrix of M states by N types
of event. Then, one natural manner of representing a state is a nested
class:

class Lackey:
def __init__(self):
lackey = self

class Idle:
def handle_ding(self):
lackey.start_timer(10)
lackey.set_state(Dinged)

class Dinged:
def handle_dong(self):
lackey.cancel_timer()
lackey.open_door()
lackey.ask_for_name()
lackey.start_timer(20)
lackey.set_state(AwaitingName)

def handle_timeout(self):
lackey.open_door()
lackey.shoo_visitor_away()
lackey.set_state(Annoyed)

# other state classes here...
self.set_state(Idle)

def set_state(self, state):
log("Lackey(): New state: {}".format(
id(self), state.__class__.__name__))
self.state = state()

def handle_ding(self):
self.state.handle_ding()

def handle_dong(self):
self.state.handle_dong()

def handle_timeout(self):
self.state.handle_timeout()

def start_timer(self):
# etc etc


Marko
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top