Solved

menu

Posted on 2012-03-15
11
240 Views
Last Modified: 2012-03-20
Hi,

I got the following:

def step1():
   print "MENU"
   print "1) select DB1"
   print "2) select DB2"
   print "3) EXIT"
   x=raw_input("select a DB?")
   if x == "1":
       db1()
   if x == "2":
       db2()
   if x == "3":
      sys.exit()

Open in new window


When DB is selected, as you can see, I have another function that is performing some database stuff, once it is done, I want to prompt the user to select another DB. So instead of calling step1() which displays all the menu option, I have created another function (see below please) and I call that function once db1() is done:


def step1-2():
    x=raw_input("select another DB?")
    if x == "1":
       db1()
    if x == "2":
       db2()
    if x == "3":
       sys.exit()

Open in new window


I would like to somehow avoid using the second function (step1-2()) and just use the "Step1" function to achieve what I'm after...

what is the best way to do this? or is calling the second function a good idea?

Thanks.
0
Comment
Question by:ezzadin
  • 6
  • 5
11 Comments
 
LVL 28

Expert Comment

by:pepr
ID: 37728267
You definitely should separat the choosing from the menu and getting the identification of the wanted action from performing the action.

Humans like a hierarchical approach more, technical solutions are better to be flat.  This way, you should get the hierarchical way for asking the action (menu hierarchy), and flat list of actions to be done.  Then you can easily modify the structure of the menu without the need to change the code bound to the identified action.

These problems can generally be observed when building GUI application, but your case is similar in that sense.

Have a look at my comment http:Q_27626604.html#a37718823.

The algorithms and data structures are often interchangable in the sense that you can solve a problem or by designing more complex algorithm or by designing more complex data structure.  It need not to be neccessarily too complex.  Generally, it must be clear and understandable.  If interested, we can design something that would fit your needs and that can be used more generally.  But it is always better to focus on what should be solved and not on what code should look like ;)
0
 

Author Comment

by:ezzadin
ID: 37729390
Thanks.

In the solution you have provided, you are displaying the prompt using len(menu):

    
# Build the prompt.
    prompt = 'Please, type 1-' + str(len(menu)) + ': '

Open in new window


Is there a way in Python to display number of option is sequence? meaning that if the menu has 4 options, then it should say

Please type 1, 2, 3 or 4?

Thanks.
0
 
LVL 28

Expert Comment

by:pepr
ID: 37729610
Yes. Try the modified example (only the prompt building was modified):

b.py
def selectItemFrom(menu):
    '''Returns identification of the selected item.'''

    # Build the prompt.
    n = len(menu)                                   # e.g. 4, then...
    s1 = ', '.join(str(x) for x in xrange(1, n))    # ... '1, 2, 3'
    s2 = ' or ' + str(n)                            # ... ' or 4'
    prompt = 'Please, type ' + s1 + s2 + ': '

    # Display the menu once.
    print
    for n, txt in enumerate(menu):
        print '{0} - {1}'.format(n + 1, txt)  # zero-based to one-based
    print

    selected = 0
    while selected < 1 or selected > len(menu):

        # Ask the user and get his/her input.
        selected = raw_input(prompt)

        # Convert the typed-in string to the integer value.
        try:
            selected = int(selected)
        except:
            selected = 0

    return menu[selected - 1]   # one-based to zero-based


if __name__ == '__main__':

    print 'What do you prefer?'
    menu = ('milk', 'egg')     # Here a tuple but it can also be a list.
    answer = selectItemFrom(menu)
    print 'OK, you prefer', answer

    print '\nWhat type of pasta do you like?'
    answer = selectItemFrom(('spaghetti', 'spaghettini', 'macaroni', 'farfale'))
    print 'OK, you prefer', answer

Open in new window


The xrange(1, n) generates the values from 1 (including) to n-1 (i.e. excluding n).  The str(x) for x in xrange(1, n) is so called generator expression that gets the numbers from the xrange() and converts them to the string representation.  The .join() joins the sequence of the string representation of the numbers and joins them with the value of the string object that it is called for (i.e. ', ').

Anyway, it may be better to use a bit more complex data structure for the hierarchical menu using tuples with a symbolic identification and with the text of the item.  The returned value would only be the symbolic one, and this could be use to identify the wanted action.
0
 

Author Comment

by:ezzadin
ID: 37729791
Thanks again.

I decided to use what I originally had. So I did something like this:

def step1(n):
if n =="1":   
   print "MENU"
   print "1) select DB1"
   print "2) select DB2"
   print "3) EXIT"
   x=raw_input("select a DB?")

if n =="2":
   x=raw_input("select another DB?")


if x == "1":
       db1()
   if x == "2":
       db2()
   if x == "3":
      sys.exit()

Open in new window


but the issue is if n ==1 when I press 1 nothing happen. I'm missing something in the "if" statements or this would not work?

Thanks a lot.
0
 
LVL 28

Expert Comment

by:pepr
ID: 37733725
I am not sure if it is the copy/paste problem.  Definitely, the indentation is wrong.  Try the following:

def step1(n):
    if n =="1":   
        print "MENU"
        print "1) select DB1"
        print "2) select DB2"
        print "3) EXIT"
        x=raw_input("select a DB?")

        if x == "1":
            db1()
        elif x == "2":
            db2()
        elif x == "3":
            sys.exit()

    elif n =="2":
        x = raw_input("select another DB?")
        # process another db x

Open in new window

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:ezzadin
ID: 37738185
Thanks, but this doesn't work.

Again, I don't want to repeat the same menu again. I want to define x once. So:

elif n =="2":
 x = raw_input("select another DB?")  

I want to use the same X defined on top of that line instead of repeating it.

Thanks.
0
 
LVL 28

Expert Comment

by:pepr
ID: 37741072
How do you want to call the step1() function?  You expect the argument 1 or 2 inside.  What should that argument mean?  Show the examples of steps of the prompts, of the user input, and of the actions done.  Show the intention, the wanted behaviour.
0
 

Author Comment

by:ezzadin
ID: 37742966
Program starts by calling:
 
step1("1")

Open in new window


So the program displays the menu because n==1:

def step1(n):
     if n =="1":   
     print "MENU"
     print "1) select DB1"
     print "2) select DB2"
     print "3) EXIT"
     x=raw_input("select a DB?")

     if n =="2":
     x=raw_input("select another DB?")


      if x == "1":
      db1()
      if x == "2":
      db2()
      if x == "3":
      sys.exit()

Open in new window


if 1 is pressed, then I call db1()

def db1():
# perform some Database stuff then
step1("2") 

Open in new window


As you can see as soon as task is done, I'm calling step1("2") which I want to prompt the user to "Select another DB" without displaying the entire menu again.

How can I do it in a simple way? The above code that I got is not working if n==1 but it works if n==2 and the reason is because I defined X after n ==2. How can I define X so that it works for both n==1 and n==2?

Thanks.
0
 
LVL 28

Accepted Solution

by:
pepr earned 500 total points
ID: 37743103
The indentation (as shown in your last comment) is definitely wrong and it cannot compile.  Does it actually look like this?

def step1(n):
    if n =="1":   
        print "MENU"
        print "1) select DB1"
        print "2) select DB2"
        print "3) EXIT"
        x=raw_input("select a DB?")

    if n =="2":
        x=raw_input("select another DB?")


    if x == "1":
        db1()
    if x == "2":
        db2()
    if x == "3":
        sys.exit()

Open in new window


Be careful with 2 and "2" as Python treats the values as different types.  There is no automatic conversion between strings and integers as in Visual Basic.  Definitely, the x is defined both after "1" and after "2".  It is filled by raw_input() in both cases.  If in doubt, print it near the place where you think the problem is.
0
 

Author Comment

by:ezzadin
ID: 37744007
This works. Thanks. As you said, the indentation was wrong.

Thanks again.
0
 
LVL 28

Expert Comment

by:pepr
ID: 37744793
You are welcome :)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Python Hue issue with import 12 72
Python negative lookahead for aaa:bbb@hostname 6 91
Effective way to iterate over a python list 8 99
How can I do this in Pyhton? 12 109
The really strange introduction Once upon a time there were individuals who intentionally put the grass seeds to the soil with anticipation of solving their nutrition problems. Or they maybe only played with seeds and noticed what happened... Som…
Article by: Swadhin
Introduction of Lists in Python: There are six built-in types of sequences. Lists and tuples are the most common one. In this article we will see how to use Lists in python and how we can utilize it while doing our own program. In general we can al…
Learn the basics of strings in Python: declaration, operations, indices, and slicing. Strings are declared with quotations; for example: s = "string": Strings are immutable.: Strings may be concatenated or multiplied using the addition and multiplic…
Learn the basics of lists in Python. Lists, as their name suggests, are a means for ordering and storing values. : Lists are declared using brackets; for example: t = [1, 2, 3]: Lists may contain a mix of data types; for example: t = ['string', 1, T…

948 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now