human
Complete this python program:
def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None, autorange=False):
assistant
#Here is the Python code you requested.

    """Returns list of dictionaries of statistics used to draw a series
    of box and whisker plots. The `Returns` section enumerates the
    required keys of the dictionary. Users can skip this function and
    pass a user-defined set of dictionaries to the new `axes.bxp` method
    instead of relying on MPL to do the calculations.
    Parameters
    X : array-like
    Data that will be represented in the boxplots. Should have 2 or
    fewer dimensions.
    whis : float, string, or sequence (default = 1.5)
    As a float, determines the reach of the whiskers to the beyond the
    first and third quartiles. In other words, where IQR is the
    interquartile range (`Q3-Q1`), the upper whisker will extend to last
    datum less than `Q3 + whis*IQR`). Similarly, the lower whisker will
    extend to the first datum greater than `Q1 - whis*IQR`.
    Beyond the whiskers, data are considered outliers
    and are plotted as individual points. This can be set this to an
    ascending sequence of percentile (e.g., [5, 95]) to set the
    whiskers at specific percentiles of the data. Finally, `whis`
    can be the string ``\range\`` to force the whiskers to the
    minimum and maximum of the data. In the edge case that the 25th
    and 75th percentiles are equivalent, `whis` can be automatically
    set to ``\range\`` via the `autorange` option.
    bootstrap : int, optional
    Number of times the confidence intervals around the median
    should be bootstrapped (percentile method).
    labels : array-like, optional
    Labels for each dataset. Length must be compatible with
    dimensions of `X`.
    autorange : bool, optional (False)
    When `True` and the data are distributed such that the  25th and
    75th percentiles are equal, ``whis`` is set to ``\range\`` such
    that the whisker ends are at the minimum and maximum of the
    data.
    Returns
    bxpstats : list of dict
    A list of dictionaries containing the results for each column
    of data. Keys of each dictionary are the following:
    Key        Value..."""
    def _bootstrap_median(data, N=5000):
        M = len(data)
        percentiles = [2.5, 97.5]
        bs_index = np.random.randint(M, size=(N, M))
        bsData = data[bs_index]
        estimate = np.median(bsData, axis=1, overwrite_input=True)
        CI = np.percentile(estimate, percentiles)
        return CI
    def _compute_conf_interval(data, med, iqr, bootstrap):
        if (bootstrap is not None):
            CI = _bootstrap_median(data, N=bootstrap)
            notch_min = CI[0]
            notch_max = CI[1]
        else:
            N = len(data)
            notch_min = (med - ((1.57 * iqr) / np.sqrt(N)))
            notch_max = (med + ((1.57 * iqr) / np.sqrt(N)))
        return (notch_min, notch_max)
    bxpstats = []
    X = _reshape_2D(X, u'X')
    ncols = len(X)
    if (labels is None):
        labels = repeat(None)
    elif (len(labels) != ncols):
        raise ValueError(u'Dimensions    of    labels    and    X    must    be    compatible')
    input_whis = whis
    for (ii, (x, label)) in enumerate(zip(X, labels), start=0):
        stats = {}
        if (label is not None):
            stats[u'label'] = label
        whis = input_whis
        bxpstats.append(stats)
        if (len(x) == 0):
            stats[u'fliers'] = np.array([])
            stats[u'mean'] = np.nan
            stats[u'med'] = np.nan
            stats[u'q1'] = np.nan
            stats[u'q3'] = np.nan
            stats[u'cilo'] = np.nan
            stats[u'cihi'] = np.nan
            stats[u'whislo'] = np.nan
            stats[u'whishi'] = np.nan
            stats[u'med'] = np.nan
            continue
        x = np.asarray(x)
        stats[u'mean'] = np.mean(x)
        (q1, med, q3) = np.percentile(x, [25, 50, 75])
        stats[u'iqr'] = (q3 - q1)
        if ((stats[u'iqr'] == 0) and autorange):
            whis = u'range'
        (stats[u'cilo'], stats[u'cihi']) = _compute_conf_interval(x, med, stats[u'iqr'], bootstrap)
        if np.isscalar(whis):
            if np.isreal(whis):
                loval = (q1 - (whis *...