How to do it...

In this example, we see how to use coroutines to simulate a finite state machine with five states.

A finite state machine or finite state automaton is a mathematical model that is widely used in engineering disciplines, but also in sciences such as mathematics and computer science.

The automaton that we want to simulate the behavior of using coroutines is as follows:

    Finite-state machine 

The states of the system are S0, S1, S2, S3, and S4, with 0 and 1: the values for which the automaton can pass from one state to the next state (this operation is called a transition). So, for example, state S0 can pass to state S1, but only for the value 1, and S0 can pass to state S2, but only for the value 0.

The following Python code simulates a transition of the automaton from state S0 (the start state), up to state S4 (the end state):

  1. The first step is obviously to import the relevant libraries:
import asyncio
import time
from random import randint
  1. Then, we define the coroutine relative to start_state. The input_value parameter is evaluated randomly; it can be 0 or 1. If it is 0, then the control goes to coroutine state2; otherwise, it changes to coroutine state1:
@asyncio.coroutine
def start_state():
print('Start State called ')
input_value = randint(0, 1)
time.sleep(1)
if input_value == 0:
result = yield from state2(input_value)
else:
result = yield from state1(input_value)
print('Resume of the Transition: Start State calling'+ result)
  1. Here is the coroutine for state1. The input_value parameter is evaluated randomly; it can be 0 or 1. If it is 0, then the control goes to state2; otherwise, it changes to state1
@asyncio.coroutine
def state1(transition_value):
output_value ='State 1 with transition value = %s '%
transition_value
input_value = randint(0, 1)
time.sleep(1)
print('...evaluating...')
if input_value == 0:
result = yield from state3(input_value)
else:
result = yield from state2(input_value)
return output_value + 'State 1 calling %s' % result
  1. The coroutine for state1 has the transition_value argument that allowed the passage of the state. Also, in this case, input_value is randomly evaluated. If it is 0, then the state transitions to state3; otherwise, the control changes to state2:
@asyncio.coroutine
def state2(transition_value):
output_value = 'State 2 with transition value = %s ' %
transition_value
input_value = randint(0, 1)
time.sleep(1)
print('...evaluating...')
if input_value == 0:
result = yield from state1(input_value)
else:
result = yield from state3(input_value)
return output_value + 'State 2 calling %s' % result
  1. The coroutine for state3 has the transition_value argument, which allowed the passage of the state. input_value is randomly evaluated. If it is 0, then the state transitions to state1; otherwise, the control changes to end_state:
@asyncio.coroutine
def state3(transition_value):
output_value = 'State 3 with transition value = %s ' %
transition_value
input_value = randint(0, 1)
time.sleep(1)
print('...evaluating...')
if input_value == 0:
result = yield from state1(input_value)
else:
result = yield from end_state(input_value)
return output_value + 'State 3 calling %s' % result
  1. end_state prints out the transition_value argument, which allowed the passage of the state, and then stops the computation:
@asyncio.coroutine
def end_state(transition_value):
output_value = 'End State with transition value = %s '%
transition_value
print('...stop computation...')
return output_value
  1. In the __main__ function, the event loop is acquired, and then we start the simulation of the finite state machine, calling the automaton's start_state:
if __name__ == '__main__':
print('Finite State Machine simulation with Asyncio Coroutine')
loop = asyncio.get_event_loop()
loop.run_until_complete(start_state())
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset