[Tutor] Exception not working as expected?
Alan Gauld
alan.gauld at yahoo.co.uk
Fri Mar 1 19:05:38 EST 2019
On 01/03/2019 19:23, Chip Wachob wrote:
> I'm not sure what you mean by putting the except close to the int().
He means you should have a try/except for the int conversion,
typically something like:
# wait for it...
try: num_items = int(raw_input(": "))
except ValueError:
# try a second time.
if num_items == 0: # individual testing
print "\nIndividual testing requested"
That means the user has a chance of continuing without errors
and you don;t need to use recursion to restart the menu system.
Part of the problem is that your design does not cleanly
separate the presentation of the menus and collection of
user input from the logic behind processing the values.
That usually leads to complicated code that's hard to
debug(and test)
You want to catch the error as soon as possibly after
it happens not at the end of the while loop.
Put the try inside the loop where you read the input
and then when things go wrong you can catch it, fix
it and continue with the program.and it simplifies
the overall structure.
> the layout of the menus. I understand how the sys.exit() works in the case
> of the initial menu, but I don't follow how I can use that same approach to
> navigate 'back' up the menu tree. Each major Test (Type A, Type B, etc) is
> a .py file unto itself.
So you make them modules and import them into your main
program. That way you can call any of them as needed.
And put the menu code in a separate function(or set of
functions) that simply displays the menu and gets a
valid response. Use the return value from that function(s)
to drive an if/elif ladder to determine how to process
the menu selections.
Or you could construct a dictionary that maps menu
choice to a function but, while that's a more flexibly
and extensible approach its also much harder to code
up correctly initially. if/elif is usually good enough.
> Something about this is feeling like maybe it should be a class, or some
> other function that I call throughout my program.
You could create a menu class but I doubt if its needed
here. A simple function (possibly taking a menu string
as input, or just storing the menu internally) that
returns some kind of unique identifies for the users
choice is all you should need.
> How can I best handle this situation and, how do I trap those invalid
> entries and, as you say, "continue" the try statements?
continue the while loop not the try.
Put the try inside the loop and use "continue" once
you fix the error. "continue" jumps you back to the
top of the loop.
So your code might look something like:
while True:
choice = get_menu_option()
if choice == 0;
# do something
elif choice == 1:
# etc
else: break # exit the while loop
And inside get_menu_option() you have something like
def get_menu_option(menu_string)
while True:
print menu_string
try: val = int(raw_input(': '))
except ....
# fix error here
if value_is_valid(val) #is it in range, non negative etc?
return val
# implicit else returns to top of loop
That way your top level code always gets a valid
user choice to process and the error handling is
located beside the place it occurred.
With a multi tiered menu structure you might have
two menu functions, one per level. You might also
have some way of mapping the menu values to a
single unique command ID. But those are just details.
The structure should be broadly the same.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos
More information about the Tutor
mailing list