[Tutor] Better structure?

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Tue Feb 1 10:21:29 CET 2005



On Mon, 31 Jan 2005, Jacob S. wrote:

> BTW, it was a few months ago, not days... but the thought still counts.
> At least you remember.


Hi Jacob,

Wait, was it really a few months ago?  Let me check the archive...

    http://mail.python.org/pipermail/tutor/2004-December/033728.html

You're right.  Wow, I'm getting that much more senile by the minute.


> I was getting stumped by the difference in comparing y The check for
> seeing what the first word is made me slamp my forehead...

I'm glad that you enjoyed one of those "ah ha!" moments.  *grin* If you
ever get the chance, you may want to take a look at a book called
Programming Pearls:

    http://www.cs.bell-labs.com/cm/cs/pearls/

for a few more examples of "ah ha!" moments of enlightenment.


As a side note: it's possible to do the same sort of thing that we did in
the last post --- with class instances --- but it's slightly more
heavyweight compared to using first-class function values.  Let's see what
that looks like, just for comparison.


The following variant will probably feel more comfortable to Java
programmers: here's a sketch of how we can do this dispatch technique with
classes instead of first-class functions:


######
class Command(object):
    def execute(self, args):
        raise NotImplementedError

class ClearCommand(Command):
    def execute(self, args):
        ...

class QuitCommand(Command):
    def execute(self, args):
        ...

...

commandDispatchTable = { 'clear' : ClearCommand(),
                         'quit' : QuitCommand(),
                         ...
                       }

def evaluate(line):
   """Evaluates the line."""
   pieces = line.split()
   cmd, rest = pieces[0], pieces[1:]
   if cmd in commandDispatchTable:
       dispatchTable[cmd].execute(rest)
   elif isAssignment(line):
       ...
   else:
       ...
######


It's the same general idea.  But just more typing.  *grin*


An advantage of using the class approach is that it is easy to extend the
commands to respond to different methods besides direct execution.  For
example, we might want to add a "help()" Command that provides a
functionality similar to the one provided by the builtin Python help()
function.  If each of the Commands implements a help() method, then we can
do something like:

###
class Command(object):
    def execute(self, args):
        raise NotImplementedError

    def help(self):
        return self.__doc__


class HelpCommand(Command):
    """Displays help for a command.
    Syntax: help [command name].
    Example Usage: help clear
    """

    def getHelpString(self, commandName):
        if commandName in dispatchTable:
            return dispatchTable[commandName].help()
        else:
            return "Unknown command."

    def execute(self, args):
        if not args:
            commandName = 'help'
        else:
            commandName = args[0]
        print "help on %r: %s" % (commandName,
                                  self.getHelpString(commandName))
###

We can get more complicated from here.  I'm not sure if this help()
Command is a good idea, but it's an option.


And perhaps not coincidently, if we look at your program's structure again
now, we might notice that it's gradually looking more and more like an
interpreter.  *grin*


Best of wishes to you!



More information about the Tutor mailing list