(options, multiple_choice=True, update=None, auto_choose_on_fail=False, _show_choice_only=None, _selection=None)
Ask for either single or multiple choice input.

    Parameters:
        options (list/tuple): Information on the selection.
            options[0] = return value (str)
            options[1] = default (bool)
            options[2] = name
            options[3:] = anything

        multiple_choice (bool): If multiple answers can be chosen.
            Default: True

        update (bool/None): If the options list should be modified in place.
            Disable if the default values need to be used again.
            By default it is set to match the multiple_choice option.
            Default: None

        auto_choose_on_fail (bool): If a random choice should be used when nothing is selected.
            If disabled without multiple_choice, None will be returned and an error will be printed.
            Default: False
        
        _show_choice_only (bool/None): If the choice should be shown, or input disabled.
            Only should be used if overriding the function.
            If set to True, a list of options will be shown with no input.
            If set to False, an input will be requested without options.
            If set to "input_override", it acts as True but asks for the input and instantly returns it.

        _selection (str/None): Pre-chosen selection to override the input.

    Return Values:
        If multiple_choice is True: 
            Return list of booleans for each option value

        If multiple_choice is False:
            If one option chosen:
                Return option[0] (the return value) of chosen option
            If more than one option chosen:
                Return None
            If auto_choose_on_fail is False and no selection given: 
                Return None

        If _show_choice_only is True:
            Return None

        If _show_choice_only is "input_override":
            Return user input

    >>> options = [
    ...     ['option_1', False, 'Option 1'],
    ...     ['option_2', False, 'Option 2'],
    ...     ['option_3', False, 'Option 3']
    ... ]
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=False) <press 1>
    option_1
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=False) <press 1 2>
    None
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=False) <no choice>
    None
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=True) <no choice>
    option_2
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=False) <press 1>
    [True, False, False]
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=False) <press 1 2>
    [True, True, False]
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=False) <no choice>
    [False, False, False]
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=True) <no choice>
    [True, False, True]
Ask for either single or multiple choice input.
Ask for either single or multiple choice input .
def select_options(options, multiple_choice=True, update=None, auto_choose_on_fail=False, _show_choice_only=None, _selection=None):
    """Ask for either single or multiple choice input.

    Parameters:
        options (list/tuple): Information on the selection.
            options[0] = return value (str)
            options[1] = default (bool)
            options[2] = name
            options[3:] = anything

        multiple_choice (bool): If multiple answers can be chosen.
            Default: True

        update (bool/None): If the options list should be modified in place.
            Disable if the default values need to be used again.
            By default it is set to match the multiple_choice option.
            Default: None

        auto_choose_on_fail (bool): If a random choice should be used when nothing is selected.
            If disabled without multiple_choice, None will be returned and an error will be printed.
            Default: False
        
        _show_choice_only (bool/None): If the choice should be shown, or input disabled.
            Only should be used if overriding the function.
            If set to True, a list of options will be shown with no input.
            If set to False, an input will be requested without options.
            If set to "input_override", it acts as True but asks for the input and instantly returns it.

        _selection (str/None): Pre-chosen selection to override the input.

    Return Values:
        If multiple_choice is True: 
            Return list of booleans for each option value

        If multiple_choice is False:
            If one option chosen:
                Return option[0] (the return value) of chosen option
            If more than one option chosen:
                Return None
            If auto_choose_on_fail is False and no selection given: 
                Return None

        If _show_choice_only is True:
            Return None

        If _show_choice_only is "input_override":
            Return user input

    >>> options = [
    ...     ['option_1', False, 'Option 1'],
    ...     ['option_2', False, 'Option 2'],
    ...     ['option_3', False, 'Option 3']
    ... ]
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=False) <press 1>
    option_1
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=False) <press 1 2>
    None
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=False) <no choice>
    None
    >>> select_options(options, multiple_choice=False, auto_choose_on_fail=True) <no choice>
    option_2
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=False) <press 1>
    [True, False, False]
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=False) <press 1 2>
    [True, True, False]
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=False) <no choice>
    [False, False, False]
    >>> select_options(options, multiple_choice=True, auto_choose_on_fail=True) <no choice>
    [True, False, True]
    """
    if update is None:
        update = multiple_choice

    #List possible options
    if multiple_choice and _show_choice_only is None:
        Message(LANGUAGE.strings['GenerationInput']['SeparateOptions'].format_custom(VALUE=', '.join(i[2] for i in options if i[1]), 
                ID=', '.join(str(i+1) for i, value in enumerate(options) if value[1])))

    for i, values in enumerate(options):

        #Set name to return value if name doesn't exist
        if len(values) == 2:
            values.append(values[0])

        if _show_choice_only is None or _show_choice_only: 
            if multiple_choice or not values[1]:
                Message(LANGUAGE.strings['GenerationInput']['ListItem'].format_custom(ID=i+1, OPTION=values[2]))
            else:
                Message(LANGUAGE.strings['GenerationInput']['ListItemDefault'].format_custom(ID=i+1, OPTION=values[2]))
    
    #Handle override to show/hide choice
    if _show_choice_only and _show_choice_only != 'input_override':
        return None
    elif _show_choice_only is None or _show_choice_only:
        Message()
    
    if _selection is None:
        choice = input(LANGUAGE.strings['Input']['UserChoice'] + ' ')
    else:
        choice = _selection

    if _show_choice_only == 'input_override':
        return choice

    #Get choice results, and update options if needed
    result = value_select(choice, [option[1] for option in options], start=1, revert_to_default=not auto_choose_on_fail)
    if update:
        for i, value in enumerate(result):
            options[i][1] = value
    
    #Return different output depending on if multiple choices were allowed
    joined = [options[i][0] for i, value in enumerate(result) if value]
    if any(result):
        _options = list_to_str(options[i][2] for i, value in enumerate(result) if value)
        if len(joined) == 1:
            Message(LANGUAGE.strings['GenerationInput']['OptionChosenSingle'].format_custom(OPTION=_options))
        else:
            Message(LANGUAGE.strings['GenerationInput']['OptionChosenMultiple'].format_custom(OPTION=_options))
    
    #Automatically choose if no selection given
    elif auto_choose_on_fail and not choice:
        if multiple_choice:
            num_results = len(result) - 1
            while not any(result):
                result = [not random.randint(0, num_results) for _ in result]
            _options = list_to_str(options[i][2] for i, value in enumerate(result) if value)
            if sum(result) == 1:
                Message(LANGUAGE.strings['GenerationInput']['OptionRandomSingle'].format_custom(OPTION=_options))
            else:
                Message(LANGUAGE.strings['GenerationInput']['OptionRandomMultiple'].format_custom(OPTION=_options))
        else:
            result = random.choice(options)[0]
            Message(LANGUAGE.strings['GenerationInput']['OptionRandomSingle'].format_custom(OPTION=result))
            return result
    
    #End if multiple choice
    if multiple_choice:
        Message()
        return result

    #Check too many options haven't been chosen
    elif joined:
        _option_count = len(joined)
        if _option_count > 1:
            Message(LANGUAGE.strings['GenerationInput']['OptionInvalidSingleChoice'].format_custom(OPTION_COUNT=_option_count))
            Message()
            return None
        Message()
        return joined[0]
    
    #End if random choice was chosen
    else:
        if not auto_choose_on_fail:
            Message(LANGUAGE.strings['GenerationInput']['OptionInvalidInput'])
            Message()
            return None
        else:
            Message(LANGUAGE.strings['GenerationInput']['OptionValid'].format_custom(OPTION=choice))
            Message()
            return choice
def select_options ( options , multiple_choice = True , update = None , auto_choose_on_fail = False , _show_choice_only = None , _selection = None ) : if update is None : update = multiple_choice #List possible options if multiple_choice and _show_choice_only is None : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'SeparateOptions' ] . format_custom ( VALUE = ', ' . join ( i [ 2 ] for i in options if i [ 1 ] ) , ID = ', ' . join ( str ( i + 1 ) for i , value in enumerate ( options ) if value [ 1 ] ) ) ) for i , values in enumerate ( options ) : #Set name to return value if name doesn't exist if len ( values ) == 2 : values . append ( values [ 0 ] ) if _show_choice_only is None or _show_choice_only : if multiple_choice or not values [ 1 ] : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'ListItem' ] . format_custom ( ID = i + 1 , OPTION = values [ 2 ] ) ) else : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'ListItemDefault' ] . format_custom ( ID = i + 1 , OPTION = values [ 2 ] ) ) #Handle override to show/hide choice if _show_choice_only and _show_choice_only != 'input_override' : return None elif _show_choice_only is None or _show_choice_only : Message ( ) if _selection is None : choice = input ( LANGUAGE . strings [ 'Input' ] [ 'UserChoice' ] + ' ' ) else : choice = _selection if _show_choice_only == 'input_override' : return choice #Get choice results, and update options if needed result = value_select ( choice , [ option [ 1 ] for option in options ] , start = 1 , revert_to_default = not auto_choose_on_fail ) if update : for i , value in enumerate ( result ) : options [ i ] [ 1 ] = value #Return different output depending on if multiple choices were allowed joined = [ options [ i ] [ 0 ] for i , value in enumerate ( result ) if value ] if any ( result ) : _options = list_to_str ( options [ i ] [ 2 ] for i , value in enumerate ( result ) if value ) if len ( joined ) == 1 : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionChosenSingle' ] . format_custom ( OPTION = _options ) ) else : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionChosenMultiple' ] . format_custom ( OPTION = _options ) ) #Automatically choose if no selection given elif auto_choose_on_fail and not choice : if multiple_choice : num_results = len ( result ) - 1 while not any ( result ) : result = [ not random . randint ( 0 , num_results ) for _ in result ] _options = list_to_str ( options [ i ] [ 2 ] for i , value in enumerate ( result ) if value ) if sum ( result ) == 1 : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionRandomSingle' ] . format_custom ( OPTION = _options ) ) else : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionRandomMultiple' ] . format_custom ( OPTION = _options ) ) else : result = random . choice ( options ) [ 0 ] Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionRandomSingle' ] . format_custom ( OPTION = result ) ) return result #End if multiple choice if multiple_choice : Message ( ) return result #Check too many options haven't been chosen elif joined : _option_count = len ( joined ) if _option_count > 1 : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionInvalidSingleChoice' ] . format_custom ( OPTION_COUNT = _option_count ) ) Message ( ) return None Message ( ) return joined [ 0 ] #End if random choice was chosen else : if not auto_choose_on_fail : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionInvalidInput' ] ) Message ( ) return None else : Message ( LANGUAGE . strings [ 'GenerationInput' ] [ 'OptionValid' ] . format_custom ( OPTION = choice ) ) Message ( ) return choice