def input_options(self, options, require=False, prompt=None, fallback_prompt=None,
                      numrange=None, default=None, max_width=72):
        """Prompts a user for input. The sequence of `options` defines the
        choices the user has. A single-letter shortcut is inferred for each
        option; the user's choice is returned as that single, lower-case
        letter. The options should be provided as lower-case strings unless
        a particular shortcut is desired; in that case, only that letter
        should be capitalized.

        By default, the first option is the default. `default` can be provided to
        override this. If `require` is provided, then there is no default. The
        prompt and fallback prompt are also inferred but can be overridden.

        If numrange is provided, it is a pair of `(high, low)` (both ints)
        indicating that, in addition to `options`, the user may enter an
        integer in that inclusive range.

        `max_width` specifies the maximum number of columns in the
        automatically generated prompt string.
        """
        # Assign single letters to each option. Also capitalize the options
        # to indicate the letter.
        letters = {}
        display_letters = []
        capitalized = []
        first = True
        for option in options:
            # Is a letter already capitalized?
            for letter in option:
                if letter.isalpha() and letter.upper() == letter:
                    found_letter = letter
                    break
            else:
                # Infer a letter.
                for letter in option:
                    if not letter.isalpha():
                        continue # Don't use punctuation.
                    if letter not in letters:
                        found_letter = letter
                        break
                else:
                    raise ValueError('no unambiguous lettering found')

            letters[found_letter.lower()] = option
            index = option.index(found_letter)

            # Mark the option's shortcut letter for display.
            if not require and ((default is None and not numrange and first) or
                    (isinstance(default, basestring) and
                     found_letter.lower() == default.lower())):
                # The first option is the default; mark it.
                show_letter = '[%s]' % found_letter.upper()
                is_default = True
            else:
                show_letter = found_letter.upper()
                is_default = False

            # Colorize the letter shortcut.
            show_letter = self.colorize('green' if is_default else 'red',
                                        show_letter)

            # Insert the highlighted letter back into the word.
            capitalized.append(
                option[:index] + show_letter + option[index + 1:]
            )
            display_letters.append(found_letter.upper())

            first = False

        # The default is just the first option if unspecified.
        if require:
            default = None
        elif default is None:
            if numrange:
                default = numrange[0]
            else:
                default = display_letters[0].lower()

        # Make a prompt if one is not provided.
        if not prompt:
            prompt_parts = []
            prompt_part_lengths = []
            if numrange:
                if isinstance(default, int):
                    default_name = str(default)
                    default_name = self.colorize('turquoise', default_name)
                    tmpl = '# selection (default %s)'
                    prompt_parts.append(tmpl % default_name)
                    prompt_part_lengths.append(len(tmpl % str(default)))
                else:
                    prompt_parts.append('# selection')
                    prompt_part_lengths.append(len(prompt_parts[-1]))
            prompt_parts += capitalized
            prompt_part_lengths += [len(s) for s in options]

            # Wrap the query text.
            prompt = ''
            line_length = 0
            for i, (part, length) in enumerate(zip(prompt_parts,
                                                   prompt_part_lengths)):
                # Add punctuation.
                if i == len(prompt_parts) - 1:
                    part += '?'
                else:
                    part += ','
                length += 1

                # Choose either the current line or the beginning of the next.
                if line_length + length + 1 > max_width:
                    prompt += '\n'
                    line_length = 0

                if line_length != 0:
                    # Not the beginning of the line; need a space.
                    part = ' ' + part
                    length += 1

                prompt += part
                line_length += length

        # Make a fallback prompt too. This is displayed if the user enters
        # something that is not recognized.
        if not fallback_prompt:
            fallback_prompt = 'Enter one of '
            if numrange:
                fallback_prompt += '%i-%i, ' % numrange
            fallback_prompt += ', '.join(display_letters) + ':'

        resp = self.input_(prompt)
        while True:
            resp = resp.strip().lower()

            # Try default option.
            if default is not None and not resp:
                resp = default

            # Try an integer input if available.
            if numrange:
                try:
                    resp = int(resp)
                except ValueError:
                    pass
                else:
                    low, high = numrange
                    if low <= resp <= high:
                        return resp
                    else:
                        resp = None

            # Try a normal letter input.
            if resp:
                resp = resp[0]
                if resp in letters:
                    return resp

            # Prompt for new input.
            resp = self.input_(fallback_prompt)
dataset/ETHPy150Open MartinPaulEve/PlotSummary/interactive.py/Interactive.input_options/original