How to create a python menu where the options are selectable and unselectable?

Question:

I want to create a python menu that has numbered menu options, and when you select one of these options, an x appears next to it to show that, that particular option has been selected. Then, if the user selects the option again, I want the x to disappear to show that that option is no longer selected.

Here are example images of what I want my program to do:

  1. The Menu is blank.

  2. The option that was selected has a little x next to it.

  3. When selected again, the option becomes blank again.

Here is my test code so far:

test = print("1. Normal Character Generator({})".format(""))
test2 = print("2. Advanded Appearance Generator({})".format(""))


def normalGenerationTrue():
    test = print("1. Normal Character Generator({})".format("X"))


while True:
    try:
        selection = int(input("Please choose one of the menu options.n"))

        if selection == 1:
            normalGenerationTrue()
            new = input("Would you like to make another selection?").lower()
            if new == "yes":
                print(test)
            elif new == "no":
                break
        elif selection == 2:
            advancedGenerationTrue()
            break
        else:
            print("Invalid Choice. Enter one of the menu numbers.")
            test = print("1. Normal Character Generator({})".format(""))
            test2 = print("2. Advanded Appearance Generator({})".format(""))
    except ValueError:
        print("Invalid Choice. Enter one of the menu numbers.")

Asked By: Keenonthedaywalk

||

Answers:

You should keep menu on list

menu = [
   "1. Normal Character Generator",
   "2. Advanded Appearance Generator",
]

And keep last selection in variable (0 means not seletion)

selected = 0

And later you can use both values to display menu with or without X

def display_menu(menu, selected):
    for number, item in enumerate(menu, 1):
        if number == selected:
            print('(X)', item)
        else:
            print('( )', item)

And later you have to assign new value to selected

while True:
    display_menu(menu, selected)

    try:
        # don't assign directly to `selected` because user may choose wrong number
        new_selection = int(input("Please choose one of the menu options.n"))

        if new_selection in (1, 2):
            # assign to `selected` when user choose correct number
            selected = new_selection

            display_menu(menu, selected)
 
            new = input("Would you like to make another selection? [Y/n]").lower()

            if new in ("n", "no"):
                break
        else:
            print("Invalid Choice. Enter one of the menu numbers.")
    except ValueError:
        print("Invalid Choice. Enter one of the menu numbers.")

BTW:

I put (X) ( ) at the beginning of line because it is more readable – and many programs put it at the beginning of line (similar to checkboxes in GUIs).

In second question I check also n because it simpler to write only n instead of no. And many programs do this.

I also use text [Y/n] (similar to other programs) to show possible selection – n or y. Upper Y is popular method to inform user that it is default value which will be used if he/she press only Enter (without typing y).


Full code:

menu = [
    "1. Normal Character Generator",
    "2. Advanded Appearance Generator",
]

selected = 0

def display_menu(menu, selected):
    for number, item in enumerate(menu, 1):
        if number == selected:
            print('(X)', item)
        else:
            print('( )', item)
    
while True:
    display_menu(menu, selected)

    try:
        # don't assign directly to `selected` because user can choose wrong number
        new_selection = int(input("Please choose one of the menu options.n>> "))

        if new_selection in (1, 2):
            # assign to `selected` because it it correct number
            selected = new_selection

            display_menu(menu, selected)
 
            new = input("Would you like to make another selection? [Y/n]n>> ").lower()

            if new in ("n", "no"):
                break
        else:
            print("Invalid Choice. Enter one of the menu numbers.")
    except ValueError:
        print("Invalid Choice. Enter one of the menu numbers.")

Result:

( ) 1. Normal Character Generator
( ) 2. Advanded Appearance Generator
Please choose one of the menu options.
>> 1
(X) 1. Normal Character Generator
( ) 2. Advanded Appearance Generator
Would you like to make another selection? [Y/n]
>> 
(X) 1. Normal Character Generator
( ) 2. Advanded Appearance Generator
Please choose one of the menu options.
>> 2
( ) 1. Normal Character Generator
(X) 2. Advanded Appearance Generator
Would you like to make another selection? [Y/n]
>> y
( ) 1. Normal Character Generator
(X) 2. Advanded Appearance Generator
Please choose one of the menu options.
>> 1
(X) 1. Normal Character Generator
( ) 2. Advanded Appearance Generator
Would you like to make another selection? [Y/n]
>> n
Answered By: furas
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.