def constraints_check(constraints=None):
    """Check constraints list for consistency and return the list with basic problems corrected.

    A valid constraints list is a list of constraint dictionaries. --> [{const_dict}, ... ,{const_dict}]

    A constraint dictionary specifies individual constraint functions, arguments (args and kwargs), and constraint
    types.  The value corresponding the 'func' key is a callable function which defines the constraint.  Traditional
    functions ('def func(x): ...') and lambda functions ('func = lambda x: ...') both work.  The function signature
    must be of the form 'func(x, *args, **kwargs)' where 'x' is a float or a list of floats representing a vector.
    The return value from 'func' must be a float.  Values corresponding to the 'args' and 'kwargs' keys are any
    additional arguments to be passed to 'func' (both are optional).  Positional arguments (args) are specified as
    a tuple and keyword arguments (kwargs) are specified as a dictionary.  The 'type' key specifies the inequality
    that the value returned from 'func' must obey for the constraint to be satisfied.  Values for the inequality
    specification may be '>0', '>=0', '<0', '<=0'.

    const_dict --> {'type': ineq_spec_string, 'func': callable_func, 'args': (args_tuple), 'kwargs': {kwargs_dict}}

    Args:
        constraints (list): List of constraint dictionaries.

    Returns:
        list: Validated list of constraint dictionaries.

    Raises:
        TypeError: constraints must be a list of dictionaries
        TypeError: constraint is not a dictionary
        TypeError: constraint dictionary does not have required "type" key
        ValueError: constraint["type"] must be >0, >=0, <0, or <=0
        TypeError: constraint dictionary does not have required "func" key
        ValueError: constraint["func"] must be callable
        TypeError: constraint["args"] must be a tuple
        TypeError: constraint["kwargs"] must be a dictionary
    """
    if constraints is not None:
        if not isinstance(constraints, list):
            raise TypeError('constraints must be a list of dictionaries')
        for i, const in enumerate(constraints):
            if not isinstance(const, dict):
                raise TypeError('constraint[%d] is not a dictionary' % i)
            if 'type' not in const.keys():
                raise TypeError(
                    'constraint[%d] dictionary does not have required "type" key'
                     % i)
            if const['type'] not in ['>0', '>=0', '<0', '<=0']:
                raise ValueError(
                    'constraint[%d]["type"] must be >0, >=0, <0, or <=0' % i)
            if 'func' not in const.keys():
                raise TypeError(
                    'constraint[%d] dictionary does not have required "func" key'
                     % i)
            if not callable(const['func']):
                raise TypeError('constraint[%d]["func"] must be callable' % i)
            if 'args' not in const.keys():
                const['args'] = ()
            if not isinstance(const['args'], tuple):
                raise TypeError('constraint[%d]["args"] must be a tuple' % i)
            if 'kwargs' not in const.keys():
                const['kwargs'] = {}
            if not isinstance(const['kwargs'], dict):
                raise TypeError(
                    'constraint[%d]["kwargs"] must be a dictionary' % i)
    return constraints
