python console menu level looping
ROGER GRAYDON CHRISTMAN
dvl at psu.edu
Mon Sep 25 11:51:20 EDT 2017
On Mon, Sep 24, 2017 09:41 PM, Daiyue Weng <daiyueweng at gmail.com> wrote:
>
Hi, I tried to make a menu using print statements in Python 3. The code is
>as follows,
>
>print('insert data into: ')
>data_insert_method = ['new collection', 'existing collection']
>for index, elem in enumerate(data_insert_method):
>print(index, '-', elem)
>
>while 1:
>how_to_insert = input('Choose a method for inserting data: ')
>if how_to_insert:
>try:
>how_to_insert = int(how_to_insert)
>how_to_insert = data_insert_method[how_to_insert]
>break
>except ValueError:
>print('Please type in an integer corresponding to the data insert method')
>continue
>except IndexError:
>print('insert method index out of range')
>continue
>
>if how_to_insert == 'new collection':
>
>print('Set up collection name : ')
>db_name_setup = ['manual setup', 'return to the main menu']
>for index, elem in enumerate(db_name_setup):
>print(index, '-', elem)
>
>while 1:
>how_to_setup = input('Choose a method for setting up collection: ')
>if how_to_setup:
>try:
>how_to_setup = int(how_to_setup)
>how_to_setup = db_name_setup[how_to_setup]
>break
>except ValueError:
>print('Please type in an integer corresponding to the collection setup
>method')
>continue
>except IndexError:
>print('collection setup method index out of range')
>continue
>
>if how_to_setup == 'manual setup':
>print('Please type in collection name: ')
>elif how_to_setup == 'return to main menu':
>print('return to main menu')
>
>It is a 2-level menu, on the 2nd level menu 'new collection', there is an
>option - 'return to the main menu', I am wondering how to loop back to the
>1st level menu, i.e. ['new collection', 'existing collection'],
>whenever 'return
>to the main menu' is selected.
>
As one of those pesky teacher purists, my first response is 'ick'.
I see 'break' statements used for 'normal' loop exits.
I see 'continue' statements that have no effect, so serve no purpose.
I see lists being used just for display purposes, and not to actually solve any
problem
and then the question about 'how to loop back' at the end
-- if you want to go from the bottom of a loop to the top of loop,
all you have to do is make sure they are the same loop
I would take this approach:
I am inserting .'s to indent, because I do not trust my mailer
to preserve the indentation
data_insert_method = ['exit program',new collection','existing collection']
db_name_setup = ['return to previous menu','manual setup']
first_menu = -1 # feed the first loop
while first_menu != 0::
. . for counterin range(len(data_insert_method)):
. . . . index = (counter+1) % len(data_insert_method)
. . . . print(index,'-',data_insert_method(index)
. . . . # the quit option is always 0, and appears last
. . . . # obtain and verify integer input here
. . . . if first_menu == 1: # new collection
. . . . . . second_menu = -1
. . . . . . while second_menu != 0:
. . . . . . . . # the same thing as the outer loop, just nested
. . . . . . . < trim >
. . . . elif first_menu == 2: # existing collection
There are still some wide open design problems here:
It seems the only difference between 'new collection' and
'existing collection' is whether data already exists.
But the code structure as presented seems to suggest that
there will be one whole section to the program that works
on an empty set, and different whole section that works on
a non-emtpty set -- which suggests a humongous amount
of unnecessary code duplication.
Do you really expect to go back to the outer menu for
'new collection' more than once, when running this program,
or does it seem more likely that initalizing an empty data base
would happen only once at program startup, after which it
behaves just like an 'existing collection' with less data?
As someone else pointed out, your tests along the lines of
if how_to_insert == 'new collection':
are error prone, just from typing errors. If you are going to
have a user type in discrete integers, you might as well
just test using those integers.
On the other hand, if you intend to make the code's decisions
appear to be self-documenting, then skip the integers completely,
and instead use string inputs, like single letters or short keywords.
That would then eliminate any worry about ValueErrors.
A dictionary can easily associate the short inputs with the
longer method descriptions, and could even conceivably
link directly to a function object.
Roger Christman
Pennsylvania State University
More information about the Python-list
mailing list