This main purpose of this part of the recipe is to exhibit a simple state machine that accepts a five-digit American zip code.
The approach indicated in this recipe might be alright for testing a particular state machine against actual input strings. Unit testing would be better.
What Objects are Involved
No notable Python or wxPython classes or modules are employed in this code.
The state machine defined in this recipe accepts only strings consisting of exactly five digits. There are only two states, and only one of these is of any size at all.
The main thing to notice is that the state defined by local raises a special exception when it encounters an unnacceptable character. I suspect that, in most cases, this might be the only type of exception that will need to be raised in state machines meant for use in validators.
Notice too that the state machine is defined only once but that the function display redefines the sequence of input tokens for the state machine, once for each string that the function processes.
Convenience code in the state machine converts state machine exceptions into various result values that can be readily processed by a validator.
I should have used real unit testing in this code, eh.
1 from StateMachine import EBadCharacter, BADCHARACTER, STRINGTOOLONG, OK, StateMachine 2 3 def local ( self, token ) : 4 5 for c in range ( 5 ) : 6 if not token . isdigit ( ) : raise EBadCharacter ( ) 7 if c < 4 : token = self . nextToken ( ) 8 return 'complete', None 9 10 def complete ( self, token ) : pass 11 12 statemachine = StateMachine ( ) 13 statemachine . addState ( local ) 14 statemachine . addState ( complete, True ) 15 statemachine . setStartState ( local ) 16 17 if __name__ == "__main__" : 18 19 def display ( input ) : 20 21 statemachine . allTokens = [ ] 22 print input, 23 result = statemachine . testString ( input ) 24 print result, 25 if result . rejectCharacter ( ) : print 'reject last character, ', 26 else : print 'accept last character, ', 27 if result . validatedString ( ) : 28 print 'validated string ', 29 print " [accumulator: %s]" % '' . join ( statemachine . allTokens ) 30 else : print 'not validated' 31 32 display ( '22' ) 33 display ( '22x' ) 34 display ( '2291' ) 35 display ( '229x' ) 36 display ( '22999' )
I welcome your comments. - Bill Bell