Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Coding a simple state machine in python

1,637 views
Skip to first unread message

Ronaldo

unread,
Feb 24, 2014, 8:30:26 PM2/24/14
to
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!

Tim Daneliuk

unread,
Feb 24, 2014, 8:46:13 PM2/24/14
to
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 :)



--
----------------------------------------------------------------------------
Tim Daneliuk tun...@tundraware.com
PGP Key: http://www.tundraware.com/PGP/

William Ray Wing

unread,
Feb 24, 2014, 9:55:31 PM2/24/14
to Ronaldo, pytho...@python.org, William Ray Wing
> --
> https://mail.python.org/mailman/listinfo/python-list

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

Bill

Tim Daneliuk

unread,
Feb 24, 2014, 10:27:30 PM2/24/14
to
Now you're making it TOO easy Bill ;)

Tim Daneliuk

unread,
Feb 24, 2014, 10:27:30 PM2/24/14
to William Ray Wing, Ronaldo, pytho...@python.org
On 02/24/2014 08:55 PM, William Ray Wing wrote:
>

alex23

unread,
Feb 25, 2014, 12:19:57 AM2/25/14
to
On 25/02/2014 1:27 PM, Tim Daneliuk wrote:
> On 02/24/2014 08:55 PM, William Ray Wing wrote:
>> On Feb 24, 2014, at 8:30 PM, Ronaldo <abhish...@gmail.com> wrote:
>>> How do I write a state machine in python?
>>
>> Stackoverflow has a couple of compact examples here:
>
> Now you're making it TOO easy Bill ;)

No, the _easy_ solution is:

https://pypi.python.org/pypi?%3Aaction=search&term=state++machine&submit=search

Mark Lawrence

unread,
Feb 25, 2014, 3:35:52 AM2/25/14
to pytho...@python.org
Or several recipes on Activestate.

--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com


Peter Otten

unread,
Feb 25, 2014, 5:01:24 AM2/25/14
to pytho...@python.org
Easy? By the time I have evaluated these I've written my own ;)

Peter Otten

unread,
Feb 25, 2014, 5:04:26 AM2/25/14
to pytho...@python.org
William Ray Wing wrote:

>
> On Feb 24, 2014, at 8:30 PM, Ronaldo <abhish...@gmail.com> wrote:
>
>> --
>> https://mail.python.org/mailman/listinfo/python-list
>
> 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?


Marko Rauhamaa

unread,
Feb 25, 2014, 6:20:23 AM2/25/14
to
Peter Otten <__pet...@web.de>:
> 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

Roy Smith

unread,
Feb 24, 2014, 8:54:06 PM2/24/14
to
In article <65ac9612-fd48-472a...@googlegroups.com>,
Ronaldo <abhish...@gmail.com> wrote:

> 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()

There's lots of ways to code state machines in Python. The last time I
did one, I made each state a function. Each function returned a
(next_state, output) tuple. I don't know if that's the best way, but it
worked and seemed logical to me. Here's a trivial example with just two
states:

class StateMachine:
def __init__(self):
self.state = self.start

def process(self, input):
for item in input:
self.state, output = self.state(item)
print output

def start(self, item):
if item > 5:
return self.end, "done"
else:
return self.start, "still looking"

def end(self, item):
if item < 3:
return self.start, "back to the beginning"
else:
return self.end, "still stuck at the end"

sm = StateMachine()
sm.process([1, 2, 6, 4, 2, 2])


When you run it, it should print:

still looking
still looking
done
still stuck at the end
back to the beginning
still looking

alex23

unread,
Mar 2, 2014, 11:49:56 PM3/2/14
to
On 25/02/2014 8:01 PM, Peter Otten wrote:
> alex23 wrote:
>> No, the _easy_ solution is [find a suitable package on PyPI]
>
> Easy? By the time I have evaluated these I've written my own ;)

It's never writing a solution that's the problem...it's maintaining it
over time :)

0 new messages