Source code for experimental_lowqa.prompts

"""
A module implementing interfaces for prompting the user for input.
"""

# built-in
from typing import Dict, Iterable, NamedTuple, Optional


[docs] def select_option( options: Iterable[str], prompt: str = "selection? ", print_options: bool = False, ) -> Optional[int]: """ Given a list of options, prompt user until they select a valid index and return it. """ options = list(options) assert len(options) > 0 if len(options) == 1: return 0 if print_options: print("options:") for idx, option in enumerate(options): print(f" {idx}: '{option}'") selection: int = -1 while selection < 0 or selection >= len(options): try: value = input(prompt) selection = int(value) except ValueError: if value in options: selection = options.index(value) except KeyboardInterrupt: return None return selection
[docs] class SelectOpts(NamedTuple): """Manual select method options.""" default: str = "" allow_prompt: bool = True custom_option: bool = False descriptions: Optional[Dict[str, str]] = None
[docs] def manual_select( label: str, options: Iterable[str], **kwargs, ) -> Optional[str]: """ Prompt the user until an option from the provided set of options is chosen. """ opts = SelectOpts(**kwargs) options = list(options) custom_idx = -1 if opts.custom_option: options.append("<enter manually>") custom_idx = len(options) - 1 if not options: print(f"no options for '{label}'!") return None # select the default if it was provided and valid, or if custom options are # enabled and a non-empty default was provided if opts.default and ( (opts.default in options or not opts.allow_prompt) or opts.custom_option ): return opts.default print(f"options for '{label}':") for idx, option in enumerate(options): item_str = f" {idx}: '{option}'" if opts.descriptions and option in opts.descriptions: item_str += f" ({opts.descriptions[option]})" print(item_str) selection = None if not opts.allow_prompt: print(f"not prompting and '{opts.default}' not in options") else: selection = select_option(options) if selection is None or selection < 0: return None if selection == custom_idx: if not opts.allow_prompt: print("error: selected manual entry option but prompts disabled") return None return str(input("value: ")) return options[selection]