Cenário:
Não é sobre: DFA, NFA, GNFA, Moore, Mealy, classificações...
Considere um semáforo:
Sintomas de que você pode precisar de uma máquina de estados:
state
ou status no seu modelo.published
, paid
, started
, finished
.published_at
, paid_at
.from statemachine import StateMachine, State
class TrafficLightMachine(StateMachine):
"A traffic light machine"
green = State('Green', initial=True)
yellow = State('Yellow')
red = State('Red')
slowdown = green.to(yellow)
stop = yellow.to(red)
go = red.to(green)
def on_slowdown(self):
print('Calma, lá!')
def on_stop(self):
print('Parou.')
def on_go(self):
print('Valendo!')
stm = TrafficLightMachine()
stm.slowdown()
stm.stop()
stm.go()
Calma, lá! Parou. Valendo!
stm.is_green
True
try:
stm.stop()
except Exception as e:
print(e, type(e))
Can't stop when in Green. <class 'statemachine.exceptions.TransitionNotAllowed'>
from statemachine import StateMachine, State
class TrafficLightMachine(StateMachine):
"A traffic light machine"
green = State('Green', initial=True)
yellow = State('Yellow')
red = State('Red')
cycle = green.to(yellow) | yellow.to(red) | red.to(green)
def on_enter_green(self):
print('Valendo!')
def on_enter_yellow(self):
print('Calma, lá!')
def on_enter_red(self):
print('Parou.')
stm = TrafficLightMachine()
stm.cycle()
stm.cycle()
stm.cycle()
Calma, lá! Parou. Valendo!
class PackageStateMachine(StateMachine):
# States
created = State('Criado', initial=True)
scanned = State('Escaneado')
measured = State('Medido')
waiting_routing = State('Aguardando roteirização')
routed = State('Roteirizado')
dispatched = State('Expedido')
rejected = State('Rejeitado')
unfit = State('Fora do perfil')
cancelled = State('Cancelado')
Definimos as transições e os eventos:
# transitions
scan = (
created.to(scanned, rejected) |
rejected.to(scanned) |
unfit.to(scanned, rejected)
)
measure = scanned.to(measured, unfit)
sort = (
measured.to(waiting_routing, rejected) |
unfit.to(unfit) |
rejected.to(unfit)
)
route = waiting_routing.to(routed)
dispatch = routed.to(dispatched)
status_changed = (
created.to(created, cancelled) |
dispatched.to(dispatched)
)
update = created.to(created) | rejected.to(rejected)