docs: def menu(self, choices, prompt='Please choose from the provided options:',
               error='Invalid choice', intro=None, strict=True, default=None,
               numerator=lambda x: [i + 1 for i in range(x)],
               formatter=lambda x, y: '{0:>3}) {1}'.format(x, y),
               clean=utils.safeint):
          """ Print a menu
  
          The choices must be an iterable of two-tuples where the first value is
          the value of the menu item, and the second is the label for that
          matches the value.
  
          The menu will be printed with numeric choices. For example::
  
              1) foo
              2) bar
  
          Formatting of the number is controlled by the formatter function which
          can be overridden by passing the ``formatter`` argument.
  
          The numbers used for the menu are generated using the numerator
          function which can be specified using the ``numerator`` function. This
          function must take the number of choices and return the same number of
          items that will be used as choice characters as a list.
  
          The cleaner function is passed to ``pvpl()`` method can be customized
          using ``clean`` argument. This function should generally be customized
          whenever ``numerator`` is customized, as default cleaner converts
          input to integers to match the default numerator.
  
          Optional ``intro`` argument can be passed to print a message above the
          menu.
  
          The return value of this method is the value user has chosen. The
          prompt will keep asking the user for input until a valid choice is
          selected. Each time an invalid selection is made, error message is
          printed. This message can be customized using ``error`` argument.
  
          If ``strict`` argument is set, then only values in choices are allowed,
          otherwise any value will be allowed. The ``default`` argument can be
          used to define what value is returned in case user select an invalid
          value when strict checking is off.
          """
          numbers = list(numerator(len(choices)))
          labels = (label for _, label in choices)
          values = [value for value, _ in choices]
          # Print intro and menu itself
          if intro:
              self.pstd('\n' + utils.rewrap_long(intro))
          for n, label in zip(numbers, labels):
              self.pstd(formatter(n, label))
          # Define the validator
          validator = lambda x: x in numbers
          val = self.rvpl(prompt, error=error, validator=validator, clean=clean,
                          strict=strict, default=default)
          if not strict and val == default:
              return val
          return values[numbers.index(val)]