Skip to content

Instantly share code, notes, and snippets.

@toby-p
Created October 27, 2020 20:16
Show Gist options
  • Save toby-p/202a4f043820b39615525d7f248846c2 to your computer and use it in GitHub Desktop.
Save toby-p/202a4f043820b39615525d7f248846c2 to your computer and use it in GitHub Desktop.
Get user choice from an enumerated iterable, with pagination of options.
def input_iterable_paginated(msg: str, iterable: object, page_length: int = 5,
more: str = "m"):
"""List numbered items from any iterable to be chosen by user input."""
def get_input(valid: list):
value = input().strip().lower()
try:
value = int(value)
if value - 1 in range(len(valid)):
return valid[value - 1]
else:
print(f"Invalid input: {value}")
return get_input(valid)
except (ValueError, TypeError):
if value == more:
return value
else:
print(f"Invalid input: {value}")
return get_input(valid)
if not page_length:
page_length = len(iterable)
# Calculate maximum string width of largest number in options:
max_width = len(str(len(iterable)))
print(msg)
if page_length < len(iterable):
print(f"(Enter `{more}` to see more available options.)")
paginate_from, enumerate_from = 0, 1
choices_displayed = list()
while True:
choices = iterable[paginate_from:paginate_from + page_length]
choices_displayed += choices
display_options = "\n".join([f"{str(n).rjust(max_width)}: {x}" for n, x in enumerate(choices, enumerate_from)])
print(display_options)
user_choice = get_input(valid=choices_displayed)
if user_choice == more:
paginate_from += page_length
enumerate_from += page_length
if paginate_from >= len(iterable):
print("No more options to display!")
else:
return user_choice
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment