[Tutor] comapring lists
Jacob S.
keridee at jayco.net
Sun Dec 5 14:38:39 CET 2004
Wow! I never thought of using dictionaries to store function objects like
that! The "table-driven" approach is much better than my own! Thanks a lot!
Jacob Schmidt
>
>
> On Thu, 2 Dec 2004, Jacob S. wrote:
>
> > If you or anybody else is interested, I've written a script for codes
like
> > kids in junior high use to write notes to each other with...
>
> Hi Jacob,
>
> Cool! Do you mind if I make some comments on the code? If you do mind...
> um... skip this message. *grin*
>
>
> The main body of the program feels a bit too long: it screams to be broken
> into a few helper functions. I see that there are two critical variables
> that are used to figure out which part of the program comes next:
>
>
> ###
> unordo = raw_input('Are we going to decipher or cipher? ')
> type = raw_input('Which type of code would you like? ').lower()
>
> if type == 'mixed letters':
> if unordo == 'cipher':
> # ... do mixed letter ciphering
> if unordo == 'decipher':
> # ... do mixed letter deciphering
> if type == 'insideout':
> if unordo == 'cipher':
> # ... do insideout ciphering
> if unordo == 'decipher':
> # ... do mixed letter decipering
> # ... rest of the program follows similar structure
> ###
>
>
>
> In a case like this, we can break the program into separate functions,
> like this:
>
> ###
> def dispatchOnTypeAndUnordo(type, unordo):
> if type == 'mixed letters':
> if unordo == 'cipher':
> mixedLetterCipher()
> if unordo == 'decipher':
> mixedLetterDecipher()
> if type == 'insideout':
> if unordo == 'cipher':
> insideoutCipher()
> if unordo == 'decipher':
> insideoutDecipher()
> # ... rest of the program follows similar structure
> ###
>
> We make each 'body' of the inner "if"'s into their own functions, like
> 'mixedLetterCipher()'. This restructuring doesn't improve the program's
> performance at all, but it does help readability: the main improvement is
> to make the overall shape of the program all visible at once.
>
>
> This structural change also paves the way for a "table-driven" way to
> implement a decision tree. Experienced programmers really try to avoid
> code that looks like "if/if/if/if/if..." because that's probably some kind
> of repeating structure that we can take advantage of.
>
>
> The logic on the function dispatchOnTypeAndUnordo() has an internal rhythm
> that we can capture as a data structure. Here's a dictionary that tries
> to capture the essentials of the beat:
>
> ###
> dispatchTable = { 'mixed letters': (mixedLetterCipher,
> mixedLetterDecipher),
> 'insideout' : (insideOutCipher,
> insideOutDecipher),
> ## ... rest of the dictionary follows similar structure
> }
> ###
>
> [Note: the values in this dictionary --- the function names --- are
> intentionally without parentheses. We don't want to "call" the functions
> just yet, but just want to store them off.]
>
>
> If we have a dispatch table like this, then the dispatchOnTypeandUnordo()
> magically dissolves:
>
> ###
> def dispatchOnTypeAndUnordo(type, unordo):
> (cipherFunction, decipherFunction) = dispatchTable[type]
> if unordo == 'cipher':
> cipherFunction()
> elif unordo == 'decipher':
> decipherFunction()
> ###
>
>
> This is a "table-driven" or "data-driven" approach. The choices available
> to the program have been migrated away from the explicit, separate 'if'
> statements, and now really live as part of the 'dispatchTable' dictionary.
>
>
> Does this make sense so far? Please feel free to ask questions.
>
>
>
More information about the Tutor
mailing list