B
    Y0d09                 @  s   d Z ddlmZ ddlmZmZ ddlZddlZddl	m
Z
 dd Zdd	 Zd
d Zdd Zdd Zdd Zd#ddZdd Zd$ddZdddddZd%dd d!d"ZdS )&zV
Module that contains many useful utilities
for validating data or function arguments
    )annotations)IterableSequenceN)is_boolc          	   C  sl   |dk rt dt|t|krht|| }t|| }|dkrDdnd}t|  d| d| d| d	d
S )z
    Checks whether 'args' has length of at most 'compat_args'. Raises
    a TypeError if that is not the case, similar to in Python when a
    function is called with too many arguments.
    r   z*'max_fname_arg_count' must be non-negative   argument	argumentsz() takes at most  z (z given)N)
ValueErrorlen	TypeError)fnameargsmax_fname_arg_countcompat_argsZmax_arg_countZactual_arg_countr    r   I/var/www/html/venv/lib/python3.7/site-packages/pandas/util/_validators.py_check_arg_length   s    r   c          	   C  s   x|D ]}yR|| }|| }|dk	r,|dks<|dkrB|dk	rBd}n||k}t |sZtdW n$ tk
r   || || k}Y nX |std| d|  dqW dS )z
    Check that the keys in `arg_val_dict` are mapped to their
    default values as specified in `compat_args`.

    Note that this function is to be called only when it has been
    checked that arg_val_dict.keys() is a subset of compat_args
    NFz'match' is not a booleanzthe 'z=' parameter is not supported in the pandas implementation of z())r   r
   )r   Zarg_val_dictr   keyZv1Zv2matchr   r   r   _check_for_default_values&   s    
 r   c             C  s,   t | ||| tt||}t| || dS )a  
    Checks whether the length of the `*args` argument passed into a function
    has at most `len(compat_args)` arguments and whether or not all of these
    elements in `args` are set to their default values.

    Parameters
    ----------
    fname : str
        The name of the function being passed the `*args` parameter
    args : tuple
        The `*args` parameter passed into a function
    max_fname_arg_count : int
        The maximum number of arguments that the function `fname`
        can accept, excluding those in `args`. Used for displaying
        appropriate error messages. Must be non-negative.
    compat_args : dict
        A dictionary of keys and their associated default values.
        In order to accommodate buggy behaviour in some versions of `numpy`,
        where a signature displayed keyword arguments but then passed those
        arguments **positionally** internally when calling downstream
        implementations, a dict ensures that the original
        order of the keyword arguments is enforced.

    Raises
    ------
    TypeError
        If `args` contains more values than there are `compat_args`
    ValueError
        If `args` contains values that do not correspond to those
        of the default values specified in `compat_args`
    N)r   dictzipr   )r   r   r   r   kwargsr   r   r   validate_argsL   s     r   c             C  s8   t |t | }|r4t|d }t|  d| ddS )z}
    Checks whether 'kwargs' contains any keys that are not
    in 'compat_args' and raises a TypeError if there is one.
    r   z'() got an unexpected keyword argument ''N)setlistr   )r   r   r   diffZbad_argr   r   r   _check_for_invalid_keysu   s    r   c             C  s$   |  }t| || t| || dS )a  
    Checks whether parameters passed to the **kwargs argument in a
    function `fname` are valid parameters as specified in `*compat_args`
    and whether or not they are set to their default values.

    Parameters
    ----------
    fname : str
        The name of the function being passed the `**kwargs` parameter
    kwargs : dict
        The `**kwargs` parameter passed into `fname`
    compat_args: dict
        A dictionary of keys that `kwargs` is allowed to have and their
        associated default values

    Raises
    ------
    TypeError if `kwargs` contains keys not in `compat_args`
    ValueError if `kwargs` contains keys in `compat_args` that do not
    map to the default values specified in `compat_args`
    N)copyr   r   )r   r   r   kwdsr   r   r   validate_kwargs   s    r"   c             C  sl   t | |t|  || tt||}x(|D ] }||kr.t|  d| dq.W || t| || dS )a  
    Checks whether parameters passed to the *args and **kwargs argument in a
    function `fname` are valid parameters as specified in `*compat_args`
    and whether or not they are set to their default values.

    Parameters
    ----------
    fname: str
        The name of the function being passed the `**kwargs` parameter
    args: tuple
        The `*args` parameter passed into a function
    kwargs: dict
        The `**kwargs` parameter passed into `fname`
    max_fname_arg_count: int
        The minimum number of arguments that the function `fname`
        requires, excluding those in `args`. Used for displaying
        appropriate error messages. Must be non-negative.
    compat_args: dict
        A dictionary of keys that `kwargs` is allowed to
        have and their associated default values.

    Raises
    ------
    TypeError if `args` contains more values than there are
    `compat_args` OR `kwargs` contains keys not in `compat_args`
    ValueError if `args` contains values not at the default value (`None`)
    `kwargs` contains keys in `compat_args` that do not map to the default
    value as specified in `compat_args`

    See Also
    --------
    validate_args : Purely args validation.
    validate_kwargs : Purely kwargs validation.

    z-() got multiple values for keyword argument 'r   N)r   tuplevaluesr   r   r   updater"   )r   r   r   r   r   Z	args_dictr   r   r   r   validate_args_and_kwargs   s    &

r&   TFc             C  sN   t | }|r|p| dk}|r*|p(t| t}|sJtd| dt| j d| S )aR  
    Ensure that argument passed in arg_name can be interpreted as boolean.

    Parameters
    ----------
    value : bool
        Value to be validated.
    arg_name : str
        Name of the argument. To be reflected in the error message.
    none_allowed : bool, default True
        Whether to consider None to be a valid boolean.
    int_allowed : bool, default False
        Whether to consider integer value to be a valid boolean.

    Returns
    -------
    value
        The same value as input.

    Raises
    ------
    ValueError
        If the value is not a valid boolean.
    NzFor argument "z$" expected type bool, received type .)r   
isinstanceintr
   type__name__)valuearg_namenone_allowedint_allowedZ
good_valuer   r   r   validate_bool_kwarg   s    r0   c          	     sr  i }d kr0t  fdd| jD r0d}t|| krr|rT| d| d}t||  dd} | ||< x@  D ]4\}}	y| |}
W n tk
r   Y q|X |	||
< q|W t|dkrnt|dkr|  dd}|d ||< nt|d	krZd krd
}t|d| d| d}tj	|t
dd |d || d< |d || d< nd| d}t||S )aw  
    Argument handler for mixed index, columns / axis functions

    In an attempt to handle both `.method(index, columns)`, and
    `.method(arg, axis=.)`, we have to do some bad things to argument
    parsing. This translates all arguments to `{index=., columns=.}` style.

    Parameters
    ----------
    data : DataFrame
    args : tuple
        All positional arguments from the user
    kwargs : dict
        All keyword arguments from the user
    arg_name, method_name : str
        Used for better error messages

    Returns
    -------
    kwargs : dict
        A dictionary of keyword arguments. Doesn't modify ``kwargs``
        inplace, so update them with the return value here.

    Examples
    --------
    >>> df._validate_axis_style_args((str.upper,), {'columns': id},
    ...                              'mapper', 'rename')
    {'columns': <function id>, 'index': <method 'upper' of 'str' objects>}

    This emits a warning
    >>> df._validate_axis_style_args((str.upper, id), {},
    ...                              'mapper', 'rename')
    {'columns': <function id>, 'index': <method 'upper' of 'str' objects>}
    axisc             3  s   | ]}| kV  qd S )Nr   ).0x)r   r   r   	<genexpr>'  s    z+validate_axis_style_args.<locals>.<genexpr>z;Cannot specify both 'axis' and any of 'index' or 'columns'.z# got multiple values for argument 'r   r   r      z:Cannot specify both 'axis' and any of 'index' or 'columns'zInterpreting call
	'.z(a, b)' as 
	'.z(index=a, columns=b)'.
Use named arguments to remove any ambiguity. In the future, using positional arguments for 'index' or 'columns' will raise a 'TypeError'.   )
stacklevelzCannot specify all of 'z', 'index', 'columns'.)anyZ_AXIS_TO_AXIS_NUMBERr   Z_get_axis_namegetitemsr
   r   warningswarnFutureWarning)datar   r   r-   method_nameoutmsgr1   kvZaxr   )r   r   validate_axis_style_args   s@    % 
rD   c             C  s   ddl m} | dkr&|dkr&tdnl| dkr@|dk	r@||}nR| dk	rz|dkrz|rt| ttfrtdt| j dn| dk	r|dk	rtd| |fS )a$  
    Validate the keyword arguments to 'fillna'.

    This checks that exactly one of 'value' and 'method' is specified.
    If 'method' is specified, this validates that it's a valid method.

    Parameters
    ----------
    value, method : object
        The 'value' and 'method' keyword arguments for 'fillna'.
    validate_scalar_dict_value : bool, default True
        Whether to validate that 'value' is a scalar or dict. Specifically,
        validate that it is not a list or tuple.

    Returns
    -------
    value, method : object
    r   )clean_fill_methodNz(Must specify a fill 'value' or 'method'.z>"value" parameter must be a scalar or dict, but you passed a ""z)Cannot specify both 'value' and 'method'.)	Zpandas.core.missingrE   r
   r(   r   r#   r   r*   r+   )r,   methodZvalidate_scalar_dict_valuerE   r   r   r   validate_fillna_kwargs\  s    

rH   zfloat | Iterable[float]z
np.ndarray)qreturnc             C  sj   t | }d}|jdkrBd|  kr,dksfn t||d n$tdd |D sft||d |S )a  
    Validate percentiles (used by describe and quantile).

    This function checks if the given float or iterable of floats is a valid percentile
    otherwise raises a ValueError.

    Parameters
    ----------
    q: float or iterable of floats
        A single percentile or an iterable of percentiles.

    Returns
    -------
    ndarray
        An ndarray of the percentiles if valid.

    Raises
    ------
    ValueError if percentiles are not in given interval([0, 1]).
    zApercentiles should all be in the interval [0, 1]. Try {} instead.r   r   g      Y@c             s  s&   | ]}d |  kodkn  V  qdS )r   r   Nr   )r2   qsr   r   r   r4     s    z&validate_percentile.<locals>.<genexpr>)npZasarrayndimr
   formatall)rI   Zq_arrrA   r   r   r   validate_percentile  s    

rP   z!bool | int | Sequence[bool | int])	ascendingc               s8   ddd t | ttfs&t| df S  fdd| D S )z8Validate ``ascending`` kwargs for ``sort_index`` method.FT)r.   r/   rQ   c               s   g | ]}t |d f qS )rQ   )r0   )r2   item)r   r   r   
<listcomp>  s    z&validate_ascending.<locals>.<listcomp>)r(   r   r#   r0   )rQ   r   )r   r   validate_ascending  s    
rT   )TF)T)T)__doc__
__future__r   typingr   r   r;   numpyrL   Zpandas.core.dtypes.commonr   r   r   r   r   r"   r&   r0   rD   rH   rP   rT   r   r   r   r   <module>   s    &)8
(_
'#