def query(question, values, default=None, list_values = False, ignorecase = True ):
    """Preset a few options
    
    The question argument is a string, nothing magical.
    
    The values argument accepts input in two different forms. The simpler form
    (a tuple with strings) looks like:
    
        .. code-block:: python
        
            ('Male','Female')
    
    And it will pop up a question asking the user for a gender and requiring
    the user to enter either 'male' or 'female' (case doesn't matter unless
    you set the third arguement to false).
    The other form is something like:
    
        .. code-block:: python
        
            ({'values':('Male','M'),'fg':'cyan'},
            {'values':('Female','F'),'fg':'magenta'})
    
    This will pop up a question with Male/Female (each with appropriate
    colouring). Additionally, if the user types in just 'M', it will be
    treated as if 'Male' was typed in. The first item in the 'values' tuple
    is treated as default and is the one that is returned by the function
    if the user chooses one in that group.
    In addition the function can handle non-string objects quite fine. It
    simple displays the output object.__str__() and compares the user's input
    against that. So the the code
    
        .. code-block:: python
        
            query("Python rocks? ",(True, False))
    
    will return a bool (True) when the user types in the string 'True' (Of
    course there isn't any other reasonable answer than True anyways :P)
    
    ``default`` is the value function returns if the user types nothing in. This is
    can be used to cancel the input so-to-speek
    
    Using list_values = False will display a list, with descriptions printed out
    from the 'desc' keyword
    """
    values = list(values)
    for i in range(len(values)):
        if not isinstance(values[i], dict):
            values[i] = {'values': [values[i]]}
    try:
        import readline, rlcomplete
        wordlist = [ str(v) for value in values
                    for v in value['values']]
        completer = rlcomplete.ListCompleter(wordlist, ignorecase)
        readline.parse_and_bind("tab: complete")
        readline.set_completer(completer.complete)
    except ImportError:
        pass
    valuelist = []
    for item in values:
        entry = ( display('bright', item.get('fg'), item.get('bg')) +
            str(item['values'][0]) + display(['default']) )
        if str(item['values'][0]) == str(default): entry = '['+entry+']'
        if list_values: entry += ' : ' + item['desc']
        valuelist.append(entry)
    if list_values: question += os.linesep + os.linesep.join(valuelist) + os.linesep
    else: question += ' (' + '/'.join(valuelist) + ')'
    return input_object(question, cast = query_cast, default=default,
                 castarg=[values,ignorecase])