Still trying to understand python. It is so different than php.
I set the choice to integer, the problem is on my menu I need to use letters as well.
How c
Let me answer your question with another question:
Is it really necessary to mix letters and numbers?
Can't they just be all strings?
Well, let's take the long way and see what the program is doing:
Point 1. Let's make a function for this:
def display_menu():
menu_text = """\
Draw a Shape
============
1 - Draw a triangle
2 - Draw a square
D - Display what was drawn
X - Exit"""
print menu_text
display_menu
is very simple so there's no need to explain what it does, but we'll see later the advantage of putting this code into a separate function.
Point 2. This will be done with a loop:
options = ['1', '2', 'D', 'X']
while 1:
choice = raw_input(' Enter your choice: ')
if choice in options:
break
else:
print 'Try Again!'
Point 3. Well, after a second thought maybe the special tasks are not so special, so let's put them too into a function:
def exit():
"""Exit""" # this is a docstring we'll use it later
return 0
def display_drawn():
"""Display what was drawn"""
print 'display what was drawn'
def draw_triangle():
"""Draw a triangle"""
print 'triangle'
def draw_square():
"""Draw a square"""
print 'square'
Now let's put it all together:
def main():
options = {'1': draw_triangle,
'2': draw_square,
'D': display_drawn,
'X': exit}
display_menu()
while 1:
choice = raw_input(' Enter your choice: ').upper()
if choice in options:
break
else:
print 'Try Again!'
action = options[choice] # here we get the right function
action() # here we call that function
The key to your switch lies in options
that now is no more a list
but a dict
, so if you simply iterate on it like if choice in options
your iteration is on the keys:['1', '2', 'D', 'X']
, but if you do options['X']
you get the exit function (isn't that wonderful!).
Now let's improve again, because maintaining the main menu message and the options
dictionary it's not too good, a year from now I may forget to change one or the other, I will not get what I want and I'm lazy and I don't want to do twice the same thing, etc...
So why don't pass the options
dictionary to display_manu
and let display_menu
do all the work using the doc-strings in __doc__
to generate the menu:
def display_menu(opt):
header = """\
Draw a Shape
============
"""
menu = '\n'.join('{} - {}'.format(k,func.__doc__) for k,func in opt.items())
print header + menu
We'll need OrderedDict
instead of dict
for options
, because OrderedDict
as the name suggests keep the order of its items (take a look at the official doc). So we have:
def main():
options = OrderedDict((('1', draw_triangle),
('2', draw_square),
('D', display_drawn),
('X', exit)))
display_menu(options)
while 1:
choice = raw_input(' Enter your choice: ').upper()
if choice in options:
break
else:
print 'Try Again!'
action = options[choice]
action()
Beware that you have to design your actions so that they all have the same signature (they should be like that anyway, they are all actions!). You may want to use callables as actions: instances of class with __call__
implemented. Creating a base Action
class and inherit from it will be perfect here.