def generate_bins(bins, values=None):
    """Compute bin edges for numpy.histogram based on values and a requested bin parameters

    Unlike `range`, the largest value is included within the range of the last, largest value,
    so generate_bins(N) with produce a sequence with length N+1

    Arguments:
        bins (int or 2-tuple of floats or sequence of floats) s or the first pair of bin edges

    >>> generate_bins(0, [])
    [0]
    >>> generate_bins(3, [])
    [0, 1, 2, 3]
    >>> generate_bins(0)
    [0]
    >>> generate_bins(10)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> generate_bins(10, range(21))
    [0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0]
    >>> generate_bins((0, 3), range(21))
    [0, 3, 6, 9, 12, 15, 18, 21]
    """
    if isinstance(bins, int):
        bins = (bins,)
    if isinstance(bins, float):
        bins = (0, bins)

    if not len(bins) in (1, 2):
        return bins

    if values is None or not hasattr(values, '__iter__') or not any(values) or not hasattr(values, '__len__') or len(values) < 1:
        values = [0]
    value_min, value_max = pd.np.min(values), pd.np.max(values)
    value_range = value_max - value_min

    if len(bins) == 1:
        if not value_range:
            return range(int(bins[0]) + 1)
        bins = (0, value_range / float(bins[0]))
    if len(bins) == 2:
        if not value_range:
            return bins
        binwidth = ((bins[1] - bins[0]) or 1)
        bin0 = bins[0] or pd.np.min(values)
        if (bin0 / value_range) <= .3:
            bin0 = 0
        numbins = int(value_range / float(binwidth))
        bins = list(pd.np.arange(numbins + 1) * binwidth + bin0)
    else:
        binwidth = pd.np.min(pd.np.diff(bins)) or pd.np.mean(pd.np.diff(bins)) or 1.
    bins = list(bins)
    while bins[-1] < value_max:
        bins.append(bins[-1] + binwidth)
    return bins
Compute bin edges for numpy.histogram based on values and a requested bin parameters

    Unlike `range`, the largest value is included within the range of the last, largest value,
    so generate_bins(N) with produce a sequence with length N+1

    Arguments:
        bins (int or 2-tuple of floats or sequence of floats) s or the first pair of bin edges

    >>> generate_bins(0, [])
    [0]
    >>> generate_bins(3, [])
    [0, 1, 2, 3]
    >>> generate_bins(0)
    [0]
    >>> generate_bins(10)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> generate_bins(10, range(21))
    [0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0]
    >>> generate_bins((0, 3), range(21))
    [0, 3, 6, 9, 12, 15, 18, 21]