7
\$\begingroup\$
# Standard multi choice question template
def multiChoiceQuestion(options: list):
    while True:
        print("\nEnter the number of your choice - ")
        for x in range(len(options)):
            print(str((x + 1)) + ". " + options[x])
        print("\n")
        try:
            answer = int(input())
        except ValueError:
            print("Doesn't seem like a number! Try again!")
            continue
        if answer < 1 or answer > len(options):
            print("That option does not exist! Try again!")
            continue
        return answer

I created a template to ask a multi choice question in python. The loop will never reach it's end, since there is always a continue or a return statement. Is the while True condition appropriate for it?

\$\endgroup\$
2
  • \$\begingroup\$ "The loop will never reach it's end ... Is the while True condition appropriate for it?" That depends on whether that is the intended behaviour. Is it? \$\endgroup\$
    – Mast
    Commented Mar 7, 2019 at 17:29
  • 1
    \$\begingroup\$ Side note: for x in len(options): will produce an error as Python doesn't allow iteration over an integer. 200_success's approach is the way to go here, but for future reference, use for x in range(len(options)): if you really need to loop a certain number of times. This takes the len(options) integer and creates an interable out of it. \$\endgroup\$
    – JDG
    Commented Mar 7, 2019 at 19:32

2 Answers 2

10
\$\begingroup\$

The while True is fine, and is probably the best way to do it. However, the rest of the flow control is a bit clumsy. By rearranging a few statements, you can eliminate the continues.

PEP 8, the official Python style guide, recommends lowercase_with_underscores for function names unless you have a good reason to deviate.

The loop to print the numbered menu would be better written using enumerate(). Also, Python supports double-ended comparisons for validating that the answer is in range.

def multi_choice_question(options: list):
    while True:
        print("\nEnter the number of your choice - ")
        for i, option in enumerate(options, 1):
            print(f'{i}. {option}')
        print("\n")
        try:
            answer = int(input())
            if 1 <= answer <= len(options):
                 return answer
            print("That option does not exist! Try again!")
        except ValueError:
            print("Doesn't seem like a number! Try again!")
\$\endgroup\$
0
5
\$\begingroup\$

I think that 200_success already covered most points. I would however like to add an alternative idea for the printing part:

print("Enter the number of your choice -",
    *(f'{i}. {opt}' for i, opt in enumerate(options, 1)),
    sep='\n', end='\n\n')

Explanation: from the docs we see that following signature for the print function:

 print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

we can therefore print everything with a single print call instead of three individual ones. I leave it up to you which one you perceive easier to use.

\$\endgroup\$