def test_Example5(): statemachine = Example5(XIter(testdata), init_state='low') print(statemachine.__dict__) # Calling statemachine() should iterate over the test data and return the # processed values as list:: print(statemachine()) # only printed if something goes wrong # reset the data iterator as it is "used up" now statemachine.data = XIter(testdata) assert statemachine() == [ 'l(1)', 'l(2)', 'l(3)', 'h(4)', 'h(5)', 'h(4)', None, 'l(3)', 'l(2)', 'l(1)' ]
def __iter__(self): """Generate and return an iterator * convert `data` to an iterator queue * convert the state generators into iterators * (re) set the state_handler attribute to the init-state * pass control to the active states state_handler which should call and process next(self.data_iterator) """ self.data_iterator = XIter(self.data) # queue with `appendleft` method self.high = self.high_handler_generator().__next__ self.low = self.low_handler_generator().__next__ self.state_handler = getattr(self, self.init_state) # now start the iteration while True: yield self.state_handler()
class Example4(SimpleStates2): """two-state machine with generators and backtracking """ # Let the iterator wrap the data in an XIter instance with `appendleft` # method:: def __iter__(self): """Generate and return an iterator * convert `data` to an iterator queue * convert the state generators into iterators * (re) set the state_handler attribute to the init-state * pass control to the active states state_handler which should call and process next(self.data_iterator) """ self.data_iterator = XIter(self.data) # queue with `appendleft` method self.high = self.high_handler_generator().__next__ self.low = self.low_handler_generator().__next__ self.state_handler = getattr(self, self.init_state) # now start the iteration while True: yield self.state_handler() # Add state method generators that use the "backtracking" feature:: def high_handler_generator(self): """Return an iterator, whose next() method returns "h(token)" and switches to `low`, if token > 3 """ for token in self.data_iterator: # print( "high got", token ) if token <= 3: # push back data token self.data_iterator.appendleft(token) # set the new state self.state_handler = self.low # return non-value indicating the state switch yield None else: yield "h(%d)" % token # def low_handler_generator(self): """Return an iterator, whose next() method returns "l(token)" and switches to `high`, if token <=3 """ for token in self.data_iterator: # print( "low got", token ) if token > 3: self.data_iterator.appendleft(token) # push back # set and run the new state self.state_handler = self.high # alternatively, return the token processed by the new # state handler yield self.state_handler() else: yield "l(%d)" % token # The `__str__` converter should ignore the switch-indicator:: def __str__(self): tokens = [token for token in self() if token != None] return " ".join(tokens)
class Example4(SimpleStates2): """two-state machine with generators and backtracking """ # Let the iterator wrap the data in an XIter instance with `appendleft` # method:: def __iter__(self): """Generate and return an iterator * convert `data` to an iterator queue * convert the state generators into iterators * (re) set the state_handler attribute to the init-state * pass control to the active states state_handler which should call and process next(self.data_iterator) """ self.data_iterator = XIter(self.data) # queue with `appendleft` method self.high = self.high_handler_generator().__next__ self.low = self.low_handler_generator().__next__ self.state_handler = getattr(self, self.init_state) # now start the iteration while True: yield self.state_handler() # Add state method generators that use the "backtracking" feature:: def high_handler_generator(self): """Return an iterator, whose next() method returns "h(token)" and switches to `low`, if token > 3 """ for token in self.data_iterator: # print( "high got", token ) if token <= 3: # push back data token self.data_iterator.appendleft(token) # set the new state self.state_handler = self.low # return non-value indicating the state switch yield None else: yield "h(%d)"%token # def low_handler_generator(self): """Return an iterator, whose next() method returns "l(token)" and switches to `high`, if token <=3 """ for token in self.data_iterator: # print( "low got", token ) if token > 3: self.data_iterator.appendleft(token) # push back # set and run the new state self.state_handler = self.high # alternatively, return the token processed by the new # state handler yield self.state_handler() else: yield "l(%d)"%token # The `__str__` converter should ignore the switch-indicator:: def __str__(self): tokens = [token for token in self() if token != None] return " ".join(tokens)