NEWBIE: M. Lutz's Programming Python

Gordon McMillan gmcm at hypernet.com
Thu Sep 9 00:04:32 EDT 1999


Shannon Watters wrote:

> I'm reading Programming Python and I've come across a problem with
> running one of the examples.  In Chapter 9 there is a module to
> generalize list and dictionary menus using functions.  When I test
> the functions I get an unexpected result (my module looks just like
> Mr. Lutz's, or I'm just bleary eyed).

[snip snip]

> >>> from menu0 import interact
> >>> interact(lmenu)
>          E)ggs
>          S)top
> ?E
> EGGS
>          E)ggs
>          S)top
> ?S
> what? - try again

That comes from this part of interactList:
>           for name, func in menu:
>                if tool == name[0] or tool == name:
>                     exitflag = func()
>                     break
>                else:
>                     print 'what? - try again'
>                     continue
>           if exitflag: break

That is, the "else" is paired with the "if", so if it's not found the 
first time, you get the "what" message. This should be:

           for name, func in menu:
                if tool == name[0] or tool == name:
                     exitflag = func()
                     break
           else:
                print 'what? - try again'
                continue
           if exitflag: break

That is, the "else" should be paired with the "for". The else-block 
will be executed if break is never executed. This is an unusual 
construct, but one that many of us find quite handy.


> Traceback (innermost last):
>   File "<pyshell#2>", line 1, in ?
>     interact(dmenu)
>   File "menu0.py", line 34, in interact
>     interactDict(menu)
>   File "menu0.py", line 11, in interactDict
>     menu[tool]()
> SystemExit:

This happens because Mark wrote it that way - that's what "exit()" 
does. I'd suggest rewriting to use the same technique as 
interactList, which just falls off the end.

- Gordon

----rest of message----------------------------------------
> Here is the module (menu0.py):
> 
> from string import upper, lower
> 
> def interactDict(menu):
>      while 1:
>           for name in menu.keys():
>                print '\t' + name
>           tool = raw_input('?')
>           try:
>                menu[tool]()
>           except KeyError:
>                print 'what? - try again'
> 
> def interactList(menu):
>      while 1:
>           for name, func in menu:
>                print '\t' + upper(name[0]) + ')' + name[1:]
>           tool = lower(raw_input('?'))
>           for name, func in menu:
>                if tool == name[0] or tool == name:
>                     exitflag = func()
>                     break
>                else:
>                     print 'what? - try again'
>                     continue
>           if exitflag: break
> 
> def interact(menu):
>      try:
>           if type(menu) == type([]):
>                interactList(menu)
>           elif type(menu) == type({}):
>                interactDict(menu)
>           else:
>                print "bad menu: must be a list or dictionary"
>      except EOFError: pass
> 
> -------------------------------------------------------------
> 
> We (me and Mr. Lutz :-) use another module of simple menus to test
> the above module(testmenu.py):
> 
> from sys import stdout, exit
> 
> dmenu = {'spam' : lambda:stdout.write('SPAM\n'), 'stop' : exit }
> 
> lmenu = [('eggs', lambda:stdout.write('EGGS\n')), ('stop',
> lambda:1)]
> 
> --------------------------------------------------------------------
> ---
> 
> When I go to test menu0 in the interaction window I get this:
> 
> >>> from testmenu import *
> >>> from menu0 import interact
> >>> interact(lmenu)
>          E)ggs
>          S)top
> ?E
> EGGS
>          E)ggs
>          S)top
> ?S
> what? - try again
> >>> interact(dmenu)
>          spam
>          stop
> ?spam
> SPAM
>          spam
>          stop
> ?stop
> Traceback (innermost last):
>   File "<pyshell#2>", line 1, in ?
>     interact(dmenu)
>   File "menu0.py", line 34, in interact
>     interactDict(menu)
>   File "menu0.py", line 11, in interactDict
>     menu[tool]()
> SystemExit:
> >>>
> 
> What I don't understand is why it prints 'what? - try again' since
> my raw-input was a valid choice.  I'm not exactly sure why I get the
> traceback when I stop using dmenu either.
> 
> I would appreciate any reply and I hope that the answer isn't one
> that makes me say 'damn, I should have seen that!'.
> 
> Thanks,
> Shannon
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> -- 
> http://www.python.org/mailman/listinfo/python-list




More information about the Python-list mailing list