1# 2# vending_machine.py 3# 4# Example of using the statemachine parser without importing a .pystate module. 5# 6# A vending machine that dispenses candy and chips in a 4x4 grid, A1 thru D4. 7# To dispense a product, you must press an alpha button, then a digit button. 8# 9 10import statemachine 11 12# Vending machine buttons: 13# A, B, C, D 14# 1, 2, 3, 4 15# 16vending_machine_state_description = """\ 17statemachine VendingMachineState: 18 Idle-(press_alpha_button)->WaitingOnDigit 19 WaitingOnDigit-(press_alpha_button)->WaitingOnDigit 20 WaitingOnDigit-(press_digit_button)->DispenseProduct 21 DispenseProduct-(dispense)->Idle 22""" 23 24# convert state machine text to state classes 25generated = statemachine.namedStateMachine.transformString( 26 vending_machine_state_description 27) 28# print(generated) 29# exec generated code to define state classes and state mixin 30exec(generated) 31 32 33class VendingMachine(VendingMachineStateMixin): 34 def __init__(self): 35 self.initialize_state(Idle) 36 self._pressed = None 37 self._alpha_pressed = None 38 self._digit_pressed = None 39 40 def press_button(self, button): 41 if button in "ABCD": 42 self._pressed = button 43 self.press_alpha_button() 44 elif button in "1234": 45 self._pressed = button 46 self.press_digit_button() 47 else: 48 print("Did not recognize button {!r}".format(str(button))) 49 50 def press_alpha_button(self): 51 try: 52 super().press_alpha_button() 53 except VendingMachineState.InvalidTransitionException as ite: 54 print(ite) 55 else: 56 self._alpha_pressed = self._pressed 57 58 def press_digit_button(self): 59 try: 60 super().press_digit_button() 61 except VendingMachineState.InvalidTransitionException as ite: 62 print(ite) 63 else: 64 self._digit_pressed = self._pressed 65 self.dispense() 66 67 def dispense(self): 68 try: 69 super().dispense() 70 except VendingMachineState.InvalidTransitionException as ite: 71 print(ite) 72 else: 73 print("Dispensing at {}{}".format(self._alpha_pressed, self._digit_pressed)) 74 self._alpha_pressed = self._digit_pressed = None 75 76 77vm = VendingMachine() 78for button in "1 A B 1".split(): 79 print(">> pressing {!r}".format(button)) 80 vm.press_button(button) 81 print("Vending machine is now in {} state".format(vm.state)) 82