Damn simple finite state machine
Project description
dsm
Damn simple finite state machine
About
DSM is a observable simple finite state machine implementation for Python. Transitions may be programmed declaratively or imperatively. Inputs and state changes are emitting observable events.
Requirements
- Python 2.7, 3.5, 3.6
observable
six
for compatibility between Python 2 and Python 3
Installation
pip install dsm
Usage
Django integration
It is possible to integrate dsm
with Django models by
declaring a StateMachineField
.
from django.db import models from dsm.fields import StateMachineField class Order(models.Model): status = StateMachineField( transitions=( ('new', ['confirmed'], 'processing'), ('processing', ['cancel'], 'cancelled'), ('processing', ['send'], 'sending'), ('sending', ['deliver'], 'finished'), ), max_length=16, choices=( ('new', _('New')), ('processing', _('Processing')), ('sending', _('Sending')), ('finished', _('Finished')), ('canceled', _('Cancelled')), ), db_index=True, default='new' )
Now you can create an Order
and check it's status:
>>> order = Order.objects.create() >>> order.status new >>> type(order.status) dsm.fields.MachineState
The string representation of status
field is same as state name
provided in transitions declaration, but internally there is always
dsm.fields.MachineState
instance.
Declarative
FSM declaration:
import string import dsm class SumatorMachine(dsm.StateMachine): class Meta: initial = 'init' transitions = ( ('init', list(string.digits), 'digit_enter'), ('digit_enter', list(string.digits), 'digit_enter'), ('digit_enter', '=', 'summarize'), )
Usage:
Initialization:
fsm = SumatorMachine()
Processing one value:
fsm.process(value)
Processing multiple values:
fsm.process_many(iterable)
Gathering the current state:
>>> fsm.state 'summarize'
Resetting to the intial state:
fsm.reset()
Listening on events:
fsm.when('state', func)
Events example:
>>> the_sum = 0 >>> def add_digit(x): global the_sum; the_sum += int(x) >>> def reset(x): global the_sum; the_sum = 0 >>> fsm = SumatorMachine() >>> fsm.when('digit_enter', add_digit) >>> fsm.when('init', reset) >>> fsm.process_many('666=') 'summarize' >>> the_sum 18
Events example (class based):
>>> class Sumator(object): ... def __init__(self): ... self.total = 0 ... self.fsm = SumatorMachine() ... self.fsm.when('digit_enter', self.add) ... self.fsm.when('init', self.reset) ... ... def add(self, x): ... self.total += int(x) ... ... def reset(self, x): ... self.total = 0 ... ... def summarize(self, values): ... self.fsm.reset() ... self.fsm.process_many(values+'=') ... return self.total >>> s = Sumator() >>> s.summarize('666') 18
Imperative
import string import dsm fsm = dsm.StateMachine( initial='init', transitions=dsm.Transitions(( ('init', list(string.digits), 'digit_enter'), ('digit_enter', list(string.digits), 'digit_enter'), ('digit_enter', '=', 'summarize'), )) )
License
BSD
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Filename, size | File type | Python version | Upload date | Hashes |
---|---|---|---|---|
Filename, size dsm-0.5.3-py3-none-any.whl (8.3 kB) | File type Wheel | Python version py3 | Upload date | Hashes View |
Filename, size dsm-0.5.3.tar.gz (5.5 kB) | File type Source | Python version None | Upload date | Hashes View |