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