I have a bot code that needs to be connected to a state machine, how to implement it correctly, please help me, I understand in theory how to do this, but in practice, it does not work
states.py
from transitions import Machine, State
from main import *
states = ['START',
'WAITING_YES',
'CHOOSE SIZE',
'GO PAY'
'CHOOSE PAY METHOD',
'REPEATING ORDER',
'FINISH']
machine = Machine(states=states, initial='START')
machine.add_transition('melt', source='START', dest='WAITING_YES')
if start:
print('-------------------',machine.state,'-------------------')
machine.add_ordered_transitions()
if waiting_yes:
machine.to_WAITING_YES()
print('-------------------',machine.state,'-------------------')
machine.next_state()
elif choose_size:
print('-------------------',machine.state,'-------------------')
machine.next_state()
elif choose_pay_method:
print('-------------------',machine.state,'-------------------')
machine.next_state()
elif repeating_order:
print('-------------------',machine.state,'-------------------')
machine.next_state()
elif finish:
print('-------------------',machine.state,'-------------------')
(In theory, the code should display the status if a person uses a bot, but later I want to remove this)
A common use case for the application of state machines is to get rid of huge 'if-then-else'-constructs and process events 'context-sensitive', meaning that what happens when an event is received depends on the current state of the machine/model.
While this is probably not of interest for maria_hoffman any longer, google might lead someone here with the same intention:
Let's assume we want to build a simple bot that is capable of adding two numbers. We start with defining the necessary states.
We start from
INITand have aWAITINGstate where operation instruction are received. We could skip this one but our bot might be extended in the future to also support multiplication. InADD_1we expect the first number and inADD_2the second number for our sum. When in stateQUITwe want the system to shutdown.Next, we need to define the actual transitions that should happen:
First, we see that we have just two events:
nextandreset. What happens whennextis triggered, depends on the current state. InWAITINGwe process three possibilities: First, when the parameter passed with eventnextis equal toadd, we transition toADD_1and wait for the first number to proces. If the parameter is equal toquit, we transition toQUITand shutdown the system. If both condition checks fail we will use the third transition which will exit and re-enterWAITINGand call a method calledshow_errorbefore doing so. When transitioning fromADD_1toADD_2we call a function to store the passed value. We need to remember it forget_resultwhich is called whennextis received in stateADD_2. Lastly, we have a reset event to roll back things if something did not work out.Now we are almost done, we just need to define some prompts and the aforementioned methods
show_error,store_valueandget_result. We create a simple model for this. The idea is to show prompts depending on the state that has been entered.on_enter_<state>is the right tool for this job. We also intializeself.firstin__init__as a field to store the value of the first number that is passed inADD_1:Note that when we want to pass arguments to callbacks, all callbacks need to be able to deal with it. The documentation of
transitionsstates:So, when we don't need the actual input value, we just put
*argsin the signature to communicate this.That's it. Now we tie everything together and implement some rudimentary error checks and we are good to go. We create a model instance and pass it to the machine. When we receive input we pass it to the model via
nextand let the model do the heavy lifting. While the model is not in stateQUITwe will wait for the next input:This could be a conversation with the bot: