Skip to content

Instantly share code, notes, and snippets.

@juftin
Created June 18, 2020 04:41
Show Gist options
  • Save juftin/b585089e69a1f0d2c524e79282410a39 to your computer and use it in GitHub Desktop.
Save juftin/b585089e69a1f0d2c524e79282410a39 to your computer and use it in GitHub Desktop.
Here is an quick example of a finite state machine from the Python transitions package
#!/usr/bin/env python3
# Author:: Justin Flannery (mailto:[email protected])
"""
State Machine Example.
"""
import logging
from enum import Enum
from transitions import Machine
# noinspection PyArgumentList
logging.basicConfig(format="%(asctime)s [%(levelname)8s]: %(message)s",
handlers=[logging.StreamHandler()],
level=logging.INFO
)
class States(Enum):
"""
Configuration Enum Class For Machine States. Enums are nice and are also very auto-refactor
friendly in case you want to change a state name
"""
Baby = 0
Child = 1
Adolescent = 2
Adult = 3
Transitions = [
# All "trigger" keys in the below dictionaries become methods on the object becoming machinized
{
# Method Name
"trigger": "grow_up",
# Source State
"source": States.Baby,
# Destination State
"dest": States.Child,
# Method(s) to execute before machine state transition
"before": "before_transition",
# Method(s) to execute after machine state transition
"after": ["become_a_child", "after_transition"]
},
{
"trigger": "puberty",
"source": States.Child,
"dest": States.Adolescent,
"before": "before_transition",
"after": ["become_an_adolescent", "after_transition"]
},
{
"trigger": "mature",
"source": States.Adolescent,
"dest": States.Adult,
"before": "before_transition",
"after": ["become_an_adult", "after_transition"]
}
]
class Human(object):
"""
This is a person :)
"""
def __init__(self, name: str):
"""
This is our person. Let's give them a name. Let's assume they were just created
and give them an age of zero
Parameters
----------
name: str
Name of our person
"""
self.name = name
self.age = 0
logging.info(f"Hey, my name is {self.name} and I was just born, "
f"I am {self.age} years old.")
def __repr__(self):
"""
Let's go by our name if anyone asks
"""
return self.name
def before_transition(self):
"""
Log what's about to happen before a transition is done
"""
logging.info(f"I'm about to transition from my current state, {self.state.name}")
def after_transition(self):
"""
Log what just happened after a transition is done
"""
logging.info(f"I just transitioned into my new state, {self.state.name}")
def become_a_child(self):
"""
Become a child from a baby
"""
self.age = 5
logging.info(f"I am being raised, now I am {self.age} years old.")
def become_an_adolescent(self):
"""
Become a adolescent from a child
"""
self.age = 16
logging.info(f"I am going through puberty, now I am {self.age} years old.")
def become_an_adult(self):
"""
Become an adult from an adolescent
"""
self.age = 24
logging.info("I am joining the rest of the miserable adults, "
f"now I am {self.age} years old.")
# Create the initial human object, let's call him juftin (his formal name is Justin though)
juftin = Human(name="Justin")
# Let's machinize our Human object, juftin. The juftin object now inherits properties and
# methods from our Transitions array and States enum
Machine(model=juftin, states=States, transitions=Transitions, initial=States.Baby)
# Now let's raise juftin up from a Baby into an Adult
juftin.grow_up()
juftin.puberty()
juftin.mature()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment