0

Good day everyone, I'm fairly new to python and I had some questions regarding creating menus...

So I recently made a menu using the while loop, and it works like it's supposed to. My question, however, is whether or not it's possible to create a menu using a for loop. I know a for loop is used when you want something to cycle for an x amount of times.

I tried searching for the answer already, but I couldn't really find anything related. If anyone can point me in the right direction, I'd appreciate it.

Here is my menu using "while":

def mainMenu():
    print("SELECT A FUNCTION")
    print("")
    print("e1- Calculate The Area Of A Sphere")
    print("e2- Calculate The Volume Of A Cube")
    print("e3- Multiplication Table")
    print("e4- Converting Negatives To Positives")
    print("e5- Average Student Grades")
    print("e6- Car Sticker Color")
    print("e7- Exit")
    print("")

    while True:

        selection = input("Enter a choice: ")

        if(selection == "e1"):
            e1()
            break
        elif(selection == "e2"):
            e2()
            break
        elif(selection == "e3"):
            e3()
            break
        elif(selection == "e4"):
            e4()
            break
        elif(selection == "e5"):
            e5()
            break
        elif(selection == "e6"):
            e6()
            break
        elif(selection == "e7"):
            print("Goodbye")
            break
        else:
            print("Invalid choice. Enter 'e1'-'e7'")
            print("")
            mainMenu()
Sean Breckenridge
  • 1,932
  • 16
  • 26
Eddy R
  • 3
  • 1
  • 5
  • 1
    Possible duplicate of [Looping from 1 to infinity in Python](https://stackoverflow.com/questions/9884213/looping-from-1-to-infinity-in-python) – vishal-wadhwa Mar 18 '18 at 06:09
  • 1
    Possible duplicate of [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – Thierry Lathuille Mar 18 '18 at 06:19
  • 1
    Even if there is a solution it wouldn't be an efficient choice for such a task. I think your time will be better spent moving forward with Python instead of overthinking up a solution to your concern. – Michael Swartz Mar 18 '18 at 06:47
  • The short answer is definitely "yes"; but to elicit better answer, can you explain why you want to use a for loop instead of a while loop? E.g., do you want to only ask for menu items a fixed number of times, or do you want to see if you can get exactly the same behavior (looping forever until you get a response)? – sasmith Mar 18 '18 at 06:48
  • I need for a class assignment; but I can't figure out the structure. I need the same menu just with' for' this time – Eddy R Mar 18 '18 at 22:38

1 Answers1

0

My guess is that your instructor wanted you to use a generator. Based on your question, I'm going to assume that you are not familiar with generators. If you already know about them, skip to the second section, otherwise it might be worth your time to learn about them first.

Generators

In short, a generator acts like a function but instead of using a return statement it uses a yield statement. Calling next on a generator will run it until it reaches a yield statement and then suspend the process (and save the state of the generator, as opposed to normal functions, which typically don't save state between calls) until next is called on the generator again, at which point the control flow will be resumed where the generator left off.

The following code should give you an idea of how generators work:

# Define a generator function. This function will return our generator iterator.
def test_gen():
    numCalls = 0
    print("Start. This code is only executed once.")
    while numCalls < 10:
        print("Entering while loop.")
        yield("Yielding. numCalls = %d." %(numCalls))
        numCalls += 1
        print("Resuming control flow inside generator.")
    print("End. This code is only executed once.")
    yield("Last yield.")
# End test_gen.

# Test the behavior of our generator function.
def run_test_gen():
    # Create generator iterator by calling the generator function.
    gen = test_gen()

    # Continuously get the next value from the gen generator.
    while True:
        # If the generator has not been exhausted (run out of values to yield), then print the next value.
        try:
            print(next(gen))
        # Break out of the loop when the generator has been exhausted.
        except StopIteration:
            print("Generator has been exhausted.")
            break
# End run_test_gen.

run_test_gen()

If you want to know more about generators I'd check out the Python docs and the explanation Jeff Knupp has here.

Making a Menu With a Generator and a for Loop

Now that we know about generators, we can use them to create a menu based on a for loop. By placing a while True statement inside of a generator we can create a generator that yields an infinite number of values. Since generators are iterable, we can iterate over the yielded values in a for loop. See the below code for an example.

def infinite_gen():
    """
    First, create a generator function whose corresponding generator iterator 
    will yield values ad infinitum. The actual yielded values are irrelevant, so 
    we use the default of None.
    """
    while True:
        yield
# End infinite_gen.

def print_str_fun(string):
    """
    This function simply returns another function that will print out the value
    of string when called. This is only here to make it easier to create some
    mock functions with the same names that you used.
    """
    return(lambda : print("Calling function %s." %(string)))
# End print_str.

# Create a tuple of the function names that you used.
fun_name_tuple = ('e%d' %(ii) for ii in range(1, 7))

# Create a dictionary mapping the function names as strings to the functions themselves.
fun_dict = {fun_name: print_str_fun(fun_name) for fun_name in fun_name_tuple}

# Add the e7 function separately because it has distinct behavior.
fun_dict['e7'] = lambda : print("Goodbye.")

def mainMenu():
    """
    Example mainMenu function that uses for loop iterating over a generator
    instead of a while loop.
    """

    # Create our infinite generator.
    gen = infinite_gen()

    # Iterate over the values yielded by the generator. The code in the for loop
    # will be executed once for every value yielded by the generator.
    for _ in gen:
        # Get function name from user input.
        selection = input("Enter a choice: ")

        # Try to call the function selected by the user.
        try:
            fun_dict[selection]()
            break

        # Print a note to user and then restart mainMenu if they supplied an
        # unsupported function name.
        except KeyError:
            print("Invalid choice. Enter 'e1' - 'e7'.")
            print()
            mainMenu()
# End mainMenu.

# Allows one to run the script from the command line.
if __name__ == '__main__':
    mainMenu()