[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