Solved

menu

Posted on 2012-03-15
11
237 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:ezzadin
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
This works. Thanks. As you said, the indentation was wrong.

Thanks again.
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
You are welcome :)
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
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…

744 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

17 Experts available now in Live!

Get 1:1 Help Now