jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def _scipy_kraft_burrows_nousek(N, B, CL):
    '''Upper limit on a poisson count rate

    The implementation is based on Kraft, Burrows and Nousek
    `ApJ 374, 344 (1991) <http://adsabs.harvard.edu/abs/1991ApJ...374..344K>`_.
    The XMM-Newton upper limit server uses the same formalism.

    Parameters
    ----------
    N : int
        Total observed count number
    B : float
        Background count rate (assumed to be known with negligible error
        from a large background area).
    CL : float
       Confidence level (number between 0 and 1)

    Returns
    -------
    S : source count limit

    Notes
    -----
    Requires `scipy`. This implementation will cause Overflow Errors for about
    N > 100 (the exact limit depends on details of how scipy was compiled).
    See `~astropy.stats.mpmath_poisson_upper_limit` for an implementation that
    is slower, but can deal with arbitrarily high numbers since it is based on
    the `mpmath <http://mpmath.org/>`_ library.
    '''

    from scipy.optimize import brentq
    from scipy.integrate import quad

    from math import exp

    def eqn8(N, B):
        n = np.arange(N + 1, dtype=np.float64)
        # Create an array containing the factorials. scipy.special.factorial
        # requires SciPy 0.14 (#5064) therefore this is calculated by using
        # numpy.cumprod. This could be replaced by factorial again as soon as
        # older SciPy are not supported anymore but the cumprod alternative
        # might also be a bit faster.
        factorial_n = np.ones(n.shape, dtype=np.float64)
        factorial_n[1:] = np.cumprod(n[1:])
        return 1. / (exp(-B) * np.sum(np.power(B, n) / factorial_n))

    # The parameters of eqn8 do not vary between calls so we can calculate the
    # result once and reuse it. The same is True for the factorial of N.
    # eqn7 is called hundred times so "caching" these values yields a
    # significant speedup (factor 10).
    eqn8_res = eqn8(N, B)
    factorial_N = float(math.factorial(N))

    def eqn7(S, N, B):
        SpB = S + B
        return eqn8_res * (exp(-SpB) * SpB**N / factorial_N)

    def eqn9_left(S_min, S_max, N, B):
        return quad(eqn7, S_min, S_max, args=(N, B), limit=500)

    def find_s_min(S_max, N, B):
        '''
        Kraft, Burrows and Nousek suggest to integrate from N-B in both
        directions at once, so that S_min and S_max move similarly (see
        the article for details). Here, this is implemented differently:
        Treat S_max as the optimization parameters in func and then
        calculate the matching s_min that has has eqn7(S_max) =
        eqn7(S_min) here.
        '''
        y_S_max = eqn7(S_max, N, B)
        if eqn7(0, N, B) >= y_S_max:
            return 0.
        else:
            return brentq(lambda x: eqn7(x, N, B) - y_S_max, 0, N - B)

    def func(s):
        s_min = find_s_min(s, N, B)
        out = eqn9_left(s_min, s, N, B)
        return out[0] - CL

    S_max = brentq(func, N - B, 100)
    S_min = find_s_min(S_max, N, B)
    return S_min, S_max
//  [python]
def _scipy_kraft_burrows_nousek(N, B, CL):
    '''Upper limit on a poisson count rate

    The implementation is based on Kraft, Burrows and Nousek
    `ApJ 374, 344 (1991) <http://adsabs.harvard.edu/abs/1991ApJ...374..344K>`_.
    The XMM-Newton upper limit server uses the same formalism.

    Parameters
    ----------
    N : int
        Total observed count number
    B : float
        Background count rate (assumed to be known with negligible error
        from a large background area).
    CL : float
       Confidence level (number between 0 and 1)

    Returns
    -------
    S : source count limit

    Notes
    -----
    Requires `scipy`. This implementation will cause Overflow Errors for about
    N > 100 (the exact limit depends on details of how scipy was compiled).
    See `~astropy.stats.mpmath_poisson_upper_limit` for an implementation that
    is slower, but can deal with arbitrarily high numbers since it is based on
    the `mpmath <http://mpmath.org/>`_ library.
    '''

    from scipy.optimize import brentq
    from scipy.integrate import quad

    from math import exp

    def eqn8(N, B):
        n = np.arange(N + 1, dtype=np.float64)
        # Create an array containing the factorials. scipy.special.factorial
        # requires SciPy 0.14 (#5064) therefore this is calculated by using
        # numpy.cumprod. This could be replaced by factorial again as soon as
        # older SciPy are not supported anymore but the cumprod alternative
        # might also be a bit faster.
        factorial_n = np.ones(n.shape, dtype=np.float64)
        np.cumprod(n[1:], out=factorial_n[1:])
        return 1. / (exp(-B) * np.sum(np.power(B, n) / factorial_n))

    # The parameters of eqn8 do not vary between calls so we can calculate the
    # result once and reuse it. The same is True for the factorial of N.
    # eqn7 is called hundred times so "caching" these values yields a
    # significant speedup (factor 10).
    eqn8_res = eqn8(N, B)
    factorial_N = float(math.factorial(N))

    def eqn7(S, N, B):
        SpB = S + B
        return eqn8_res * (exp(-SpB) * SpB**N / factorial_N)

    def eqn9_left(S_min, S_max, N, B):
        return quad(eqn7, S_min, S_max, args=(N, B), limit=500)

    def find_s_min(S_max, N, B):
        '''
        Kraft, Burrows and Nousek suggest to integrate from N-B in both
        directions at once, so that S_min and S_max move similarly (see
        the article for details). Here, this is implemented differently:
        Treat S_max as the optimization parameters in func and then
        calculate the matching s_min that has has eqn7(S_max) =
        eqn7(S_min) here.
        '''
        y_S_max = eqn7(S_max, N, B)
        if eqn7(0, N, B) >= y_S_max:
            return 0.
        else:
            return brentq(lambda x: eqn7(x, N, B) - y_S_max, 0, N - B)

    def func(s):
        s_min = find_s_min(s, N, B)
        out = eqn9_left(s_min, s, N, B)
        return out[0] - CL

    S_max = brentq(func, N - B, 100)
    S_min = find_s_min(S_max, N, B)
    return S_min, S_max
//  [python]
def __init__(self, file_path, normalize=False):
        """Open the tabular model FITS files and cache the necessary data for use.
        """
        logger.info('Loading tabular models from %s...', file_path)
        with fits.open(file_path) as hdu_list:
            hdu_list.info()
            # Cache the necessary stuff so that we can close the underlying
            # FITS file and move on.
            self.par_names = tuple(hdu_list['PARAMETERS'].data['NAME'])
            self.par_values = tuple(hdu_list['PARAMETERS'].data['VALUE'])
            self.energ_lo = hdu_list['ENERGIES'].data['ENERG_LO']
            self.energ_hi = hdu_list['ENERGIES'].data['ENERG_HI']
            self.spectral_params = hdu_list['SPECTRA'].data['PARAMVAL']
            self.spectral_data = hdu_list['SPECTRA'].data['INTPSPEC']
        # Normalize by the bin width in energy---this is needed for the I
        # component.
        if normalize:
            self.spectral_data /= (self.energ_hi - self.energ_lo)
        # Calculate the shape of the table---this is essentially the number
        # of values each of the parameters can take, e.g., (4, 13, 8, 12, 7, 9).
        self.shape = tuple([len(_value) for _value in self.par_values])
        # Auxiliary variable to retrieve the spectra by parameter index.
        # This is essentially the cumulative product of the last part of the
        # shape in reverse order, e.g., (78624, 6048, 756, 63, 9).
        self._cumshape = numpy.flip(numpy.cumprod(self.shape[::-1]))[1:]
        # Is this the right thing? Need to talk with Roberto^2 and see
        # what they are actually doing when they generate the table.
        self.energy = 0.5 * (self.energ_lo + self.energ_hi)
        # And, sice we're at it, cache the phase grid for later use. Note that
        # the phase in the model runs from 0 to 2pi, while for the ixpeobsim
        # purpopses we do need a number between 0 and 1.
        self.phase = self.par_values[-1] / (2. * numpy.pi)
        # Trim the first and the last energy points in the energy grid and all
        # the related spectra, as in the underlying Monte Carlo simulation
        # the outesrmost bins act as underflow/overflow accumulators, and
        # the corresponding values are therefore unphysical.
        self.energy = self.energy[1:][:-1]
        self.spectral_data = self.spectral_data[:, 1:][:, :-1]
        logger.info('Done.\n%s', self)
//  [python]
def exp_matrix(E, freq, window, K):

    E[window.N+1:, :K] = np.exp(1j*np.pi*2*freq)
    E[window.N+1:, :K] = np.array([np.prod(E[i+1:i+1+j+1,:K], axis=0) for i in range(E[window.N+1:,:K].shape[0]) for j in range(E[window.N+1:,:K].shape[0]-1-i)])
    E[:window.N, :K] = np.conj(E[window.N+1:, :K][::-1, :])

    E[:, K:] = E[:, :K]*window.len_vec.reshape(window.length, 1)

    return E
//  [python]
def exp_matrix(E, freq, window, K):

    E[window.N+1:, :K] = np.exp(1j*np.pi*2*freq)
    E[window.N+1:, :K] = np.cumprod(E[window.N+1:, :K], axis=0)
    E[:window.N, :K] = np.conj(E[window.N+1:, :K][::-1, :])

    E[:, K:] = E[:, :K]*window.len_vec.reshape(window.length, 1)

    return E
//  [python]
def analytical_stieltjes(order, dist, multiplier=1):
    """Analytical Stieltjes' method"""
    dimensions = len(dist)
    mom_order = numpy.arange(order + 1).repeat(dimensions)
    mom_order = mom_order.reshape(order + 1, dimensions).T
    coeffs = dist.ttr(mom_order)
    coeffs[1, :, 0] = 1.0
    orders = numpy.arange(order, dtype=int)
    multiplier, orders = numpy.broadcast_arrays(multiplier, orders)

    var = numpoly.variable(dimensions)
    orth = [numpy.zeros(dimensions), numpy.ones(dimensions)]
    for order_, multiplier_ in zip(orders, multiplier):
        orth.append(
            multiplier_
            * (
                (var - coeffs[0, :, order_]) * orth[-1]
                - coeffs[1, :, order_] * orth[-2]
            )
        )
    orth = numpoly.polynomial(orth[1:]).T
    norms = numpy.cumprod(coeffs[1], 1)

    assert coeffs.shape == (2, dimensions, order + 1)
    assert orth.shape == (len(dist), order + 1)
    assert norms.shape == (len(dist), order + 1)
    return coeffs, orth, norms
//  [python]
def ravel_multi_index(multi_index: Sequence[ArrayLike], dims: Sequence[int],
                      mode: str = 'raise', order: str = 'C') -> Array:
  assert len(multi_index) == len(dims), f"len(multi_index)={len(multi_index)} != len(dims)={len(dims)}"
  dims = tuple(core.concrete_or_error(operator.index, d, "in `dims` argument of ravel_multi_index().") for d in dims)
  util.check_arraylike("ravel_multi_index", *multi_index)
  multi_index_arr = [asarray(i) for i in multi_index]
  for index in multi_index_arr:
    if mode == 'raise':
      core.concrete_or_error(array, index,
        "The error occurred because ravel_multi_index was jit-compiled"
        " with mode='raise'. Use mode='wrap' or mode='clip' instead.")
    if not issubdtype(_dtype(index), integer):
      raise TypeError("only int indices permitted")
  if mode == "raise":
    if any(reductions.any((i < 0) | (i >= d)) for i, d in zip(multi_index_arr, dims)):
      raise ValueError("invalid entry in coordinates array")
  elif mode == "clip":
    multi_index_arr = [clip(i, 0, d - 1) for i, d in zip(multi_index_arr, dims)]
  elif mode == "wrap":
    multi_index_arr = [i % d for i, d in zip(multi_index_arr, dims)]
  else:
    raise ValueError(f"invalid mode={mode!r}. Expected 'raise', 'wrap', or 'clip'")

  if order == "F":
    strides = np.array([1] + dims[:-1]).cumprod()
  elif order == "C":
    strides = np.array([1] + dims[1:][::-1]).cumprod()[::-1]
  else:
    raise ValueError(f"invalid order={order!r}. Expected 'C' or 'F'")

  result = array(0, dtype=(multi_index_arr[0].dtype if multi_index_arr
                           else dtypes.canonicalize_dtype(int_)))
  for i, s in zip(multi_index_arr, strides):
    result = result + i * int(s)
  return result
//  [python]
def ravel_multi_index(multi_index: Sequence[ArrayLike], dims: Sequence[int],
                      mode: str = 'raise', order: str = 'C') -> Array:
  assert len(multi_index) == len(dims), f"len(multi_index)={len(multi_index)} != len(dims)={len(dims)}"
  dims = tuple(core.concrete_or_error(operator.index, d, "in `dims` argument of ravel_multi_index().") for d in dims)
  util.check_arraylike("ravel_multi_index", *multi_index)
  multi_index_arr = [asarray(i) for i in multi_index]
  for index in multi_index_arr:
    if mode == 'raise':
      core.concrete_or_error(array, index,
        "The error occurred because ravel_multi_index was jit-compiled"
        " with mode='raise'. Use mode='wrap' or mode='clip' instead.")
    if not issubdtype(_dtype(index), integer):
      raise TypeError("only int indices permitted")
  if mode == "raise":
    if any(reductions.any((i < 0) | (i >= d)) for i, d in zip(multi_index_arr, dims)):
      raise ValueError("invalid entry in coordinates array")
  elif mode == "clip":
    multi_index_arr = [clip(i, 0, d - 1) for i, d in zip(multi_index_arr, dims)]
  elif mode == "wrap":
    multi_index_arr = [i % d for i, d in zip(multi_index_arr, dims)]
  else:
    raise ValueError(f"invalid mode={mode!r}. Expected 'raise', 'wrap', or 'clip'")

  if order == "F":
    strides = np.cumprod((1,) + dims[:-1])
  elif order == "C":
    strides = np.cumprod((1,) + dims[1:][::-1])[::-1]
  else:
    raise ValueError(f"invalid order={order!r}. Expected 'C' or 'F'")

  result = array(0, dtype=(multi_index_arr[0].dtype if multi_index_arr
                           else dtypes.canonicalize_dtype(int_)))
  for i, s in zip(multi_index_arr, strides):
    result = result + i * int(s)
  return result
//  [python]
def create_temporal_precisions_numpy(truncation_order = 1, smoothness = 1.0, form = 'Gaussian'):
    """
    Direct numpy re-implementation of the SPM function 'spm_DEM_R.m'
    Returns the precision of the temporal derivatives of a Gaussian process
    FORMAT R,V = create_temporal_precisions(truncation_order,smoothness,form)
    n    - truncation order [default: 1]
    s    - temporal smoothness - s.d. of kernel {bins} [default: 1.0]
    form - 'Gaussian', '1/f' [default: 'Gaussian']
    R    - shape (n,n)     E*V*E: precision of n derivatives
    V    - shape (n,n)     V:    covariance of n derivatives
    """
    if form == 'Gaussian':
        k = np.arange(0,truncation_order)
        r = np.zeros(1+2*k[-1])
        x = np.sqrt(2.0) * smoothness
        r[2*k] = n.prod(1 - (2*k))/(x**(2*k))
    elif form == '1/f':
        k = np.arange(0,truncation_order)
        x = 8.0*smoothness**2
        r[2*k] = (-1)**k * gamma(2*k + 1)/(x**(2*k))

    V = np.zeros((truncation_order, truncation_order))
    for i in range(truncation_order):
        V[i,:] = r[np.arange(0,truncation_order) + i]
        r = -r

    R = np.linalg.inv(V)

    return R, V
//  [python]
def create_temporal_precisions_numpy(truncation_order = 1, smoothness = 1.0, form = 'Gaussian'):
    """
    Direct numpy re-implementation of the SPM function 'spm_DEM_R.m'
    Returns the precision of the temporal derivatives of a Gaussian process
    FORMAT R,V = create_temporal_precisions(truncation_order,smoothness,form)
    n    - truncation order [default: 1]
    s    - temporal smoothness - s.d. of kernel {bins} [default: 1.0]
    form - 'Gaussian', '1/f' [default: 'Gaussian']
    R    - shape (n,n)     E*V*E: precision of n derivatives
    V    - shape (n,n)     V:    covariance of n derivatives
    """
    if form == 'Gaussian':
        k = np.arange(0,truncation_order)
        r = np.zeros(1+2*k[-1])
        x = np.sqrt(2.0) * smoothness
        r[2*k] = np.cumprod(1 - (2*k))/(x**(2*k))
    elif form == '1/f':
        k = np.arange(0,truncation_order)
        x = 8.0*smoothness**2
        r[2*k] = (-1)**k * gamma(2*k + 1)/(x**(2*k))

    V = np.zeros((truncation_order, truncation_order))
    for i in range(truncation_order):
        V[i,:] = r[np.arange(0,truncation_order) + i]
        r = -r

    R = np.linalg.inv(V)

    return R, V
//  [python]
def MDD_Rel(X):
    r"""
    Calculate the Maximum Drawdown (MDD) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{MDD}(X) = \max_{j \in (0,T)}\left[\max_{t \in (0,j)}
        \left ( \prod_{i=0}^{t}(1+X_{i}) \right ) - \prod_{i=0}^{j}(1+X_{i})
        \right]

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        MDD of a cumpounded cumulative returns.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("returns must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.ones(prices.shape[0])
    for i in range(1,prices.shape[0]):
        NAV[i] = NAV[i-1]*prices[i]

    value = 0
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD = (peak - i) / peak
        if DD > value:
            value = DD

    value = np.array(value).item()

    return value
//  [python]
def MDD_Rel(X):
    r"""
    Calculate the Maximum Drawdown (MDD) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{MDD}(X) = \max_{j \in (0,T)}\left[\max_{t \in (0,j)}
        \left ( \prod_{i=0}^{t}(1+X_{i}) \right ) - \prod_{i=0}^{j}(1+X_{i})
        \right]

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        MDD of a cumpounded cumulative returns.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("returns must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.cumprod(prices, axis=0)
    value = 0
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD = (peak - i) / peak
        if DD > value:
            value = DD

    value = np.array(value).item()

    return value
//  [python]
def phase_correction(vector):
    """Phase correction to reduce distortions due to phase inconsistencies.

    We need a copy first, because not all elements are touched during the
    multiplication. Otherwise, the vector would be modified in place.

    TODO: Write test cases.
    TODO: Only use non-loopy version when test case is written.

    Args:
        vector: Beamforming vector with shape (..., bins, sensors).
    Returns: Phase corrected beamforming vectors. Lengths remain.

    >>> w = np.array([[1, 1], [-1, -1]], dtype=np.complex128)
    >>> np.around(phase_correction(w), decimals=14)
    array([[1.+0.j, 1.+0.j],
           [1.-0.j, 1.-0.j]])
    >>> np.around(phase_correction([w]), decimals=14)[0]
    array([[1.+0.j, 1.+0.j],
           [1.-0.j, 1.-0.j]])
    >>> w  # ensure that w is not modified
    array([[ 1.+0.j,  1.+0.j],
           [-1.+0.j, -1.+0.j]])
    """

    # w = W.copy()
    # F, D = w.shape
    # for f in range(1, F):
    #     w[f, :] *= np.exp(-1j*np.angle(
    #         np.sum(w[f, :] * w[f-1, :].conj(), axis=-1, keepdims=True)))
    # return w

    vector = np.array(vector, copy=True)
    p = np.exp(
            1j * np.angle(
                np.sum(
                    vector[..., 1:, :].conj() * vector[..., :-1, :],
                    axis=-1, keepdims=True
                )
            )
        )
    out = np.ones_like(p)
    for i in range(p.shape[0]):
        out[i] = np.prod(p[:i+1], axis=0)
    vector[..., 1:, :] *= out
    return vector
//  [python]
def phase_correction(vector):
    """Phase correction to reduce distortions due to phase inconsistencies.

    We need a copy first, because not all elements are touched during the
    multiplication. Otherwise, the vector would be modified in place.

    TODO: Write test cases.
    TODO: Only use non-loopy version when test case is written.

    Args:
        vector: Beamforming vector with shape (..., bins, sensors).
    Returns: Phase corrected beamforming vectors. Lengths remain.

    >>> w = np.array([[1, 1], [-1, -1]], dtype=np.complex128)
    >>> np.around(phase_correction(w), decimals=14)
    array([[1.+0.j, 1.+0.j],
           [1.-0.j, 1.-0.j]])
    >>> np.around(phase_correction([w]), decimals=14)[0]
    array([[1.+0.j, 1.+0.j],
           [1.-0.j, 1.-0.j]])
    >>> w  # ensure that w is not modified
    array([[ 1.+0.j,  1.+0.j],
           [-1.+0.j, -1.+0.j]])
    """

    # w = W.copy()
    # F, D = w.shape
    # for f in range(1, F):
    #     w[f, :] *= np.exp(-1j*np.angle(
    #         np.sum(w[f, :] * w[f-1, :].conj(), axis=-1, keepdims=True)))
    # return w

    vector = np.array(vector, copy=True)
    vector[..., 1:, :] *= np.cumprod(
        np.exp(
            1j * np.angle(
                np.sum(
                    vector[..., 1:, :].conj() * vector[..., :-1, :],
                    axis=-1, keepdims=True
                )
            )
        ), axis=0
    )
    return vector
//  [python]
def check_dimensions(self, bin_edges):
        cumulative_size = numpy.array([len(bin_edge) + 1 for name, bin_edge in bin_edges.items()]).cumprod()
        if numpy.any(cumulative_size > self.max_cells):
            raise ValueError('the total size of lookup table exceeds {}, '
                             'reduce n_bins or number of features in use'.format(self.max_cells))
//  [python]
def check_dimensions(self, bin_edges):
        cumulative_size = numpy.cumprod([len(bin_edge) + 1 for name, bin_edge in bin_edges.items()])
        if numpy.any(cumulative_size > self.max_cells):
            raise ValueError('the total size of lookup table exceeds {}, '
                             'reduce n_bins or number of features in use'.format(self.max_cells))
//  [python]
def ADD_Rel(X):
    r"""
    Calculate the Average Drawdown (ADD) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{ADD}(X) = \frac{1}{T}\sum_{j=0}^{T} \left [ \max_{t \in (0,j)}
        \left ( \prod_{i=0}^{t}(1+X_{i}) \right )- \prod_{i=0}^{j}(1+X_{i})
        \right ]

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        ADD of a cumpounded cumulative returns.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("returns must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.array([np.prod(prices[:i+1]) for i in range(len(prices)-1)])
    value = 0
    peak = -99999
    n = 0
    for i in NAV:
        if i > peak:
            peak = i
        DD = (peak - i) / peak
        if DD > 0:
            value += DD
        n += 1
    if n == 0:
        value = 0
    else:
        value = value / (n - 1)

    value = np.array(value).item()

    return value
//  [python]
def ADD_Rel(X):
    r"""
    Calculate the Average Drawdown (ADD) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{ADD}(X) = \frac{1}{T}\sum_{j=0}^{T} \left [ \max_{t \in (0,j)}
        \left ( \prod_{i=0}^{t}(1+X_{i}) \right )- \prod_{i=0}^{j}(1+X_{i})
        \right ]

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        ADD of a cumpounded cumulative returns.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("returns must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.cumprod(prices, axis=0)
    value = 0
    peak = -99999
    n = 0
    for i in NAV:
        if i > peak:
            peak = i
        DD = (peak - i) / peak
        if DD > 0:
            value += DD
        n += 1
    if n == 0:
        value = 0
    else:
        value = value / (n - 1)

    value = np.array(value).item()

    return value
//  [python]
def DaR_Rel(X, alpha=0.05):
    r"""
    Calculate the Drawdown at Risk (DaR) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{DaR}_{\alpha}(X) & = \max_{j \in (0,T)} \left \{ \text{DD}(X,j)
        \in \mathbb{R}: F_{\text{DD}} \left ( \text{DD}(X,j) \right )< 1 - \alpha
        \right \} \\
        \text{DD}(X,j) & = \max_{t \in (0,j)} \left ( \prod_{i=0}^{t}(1+X_{i})
        \right )- \prod_{i=0}^{j}(1+X_{i})

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size..
    alpha : float, optional
        Significance level of DaR. The default is 0.05.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        DaR of a cumpounded cumulative returns series.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("X must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.ones(prices.shape[0])
    for i in range(1, prices.shape[0]):
        NAV[i] = NAV[i-1] * prices[i]
    DD = []
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD.append(-(peak - i) / peak)
    del DD[0]
    sorted_DD = np.sort(np.array(DD), axis=0)
    index = int(np.ceil(alpha * len(sorted_DD)) - 1)
    value = -sorted_DD[index]
    value = np.array(value).item()

    return value
//  [python]
def DaR_Rel(X, alpha=0.05):
    r"""
    Calculate the Drawdown at Risk (DaR) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{DaR}_{\alpha}(X) & = \max_{j \in (0,T)} \left \{ \text{DD}(X,j)
        \in \mathbb{R}: F_{\text{DD}} \left ( \text{DD}(X,j) \right )< 1 - \alpha
        \right \} \\
        \text{DD}(X,j) & = \max_{t \in (0,j)} \left ( \prod_{i=0}^{t}(1+X_{i})
        \right )- \prod_{i=0}^{j}(1+X_{i})

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size..
    alpha : float, optional
        Significance level of DaR. The default is 0.05.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        DaR of a cumpounded cumulative returns series.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("X must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.cumprod(prices, axis=0)
    DD = []
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD.append(-(peak - i) / peak)
    del DD[0]
    sorted_DD = np.sort(np.array(DD), axis=0)
    index = int(np.ceil(alpha * len(sorted_DD)) - 1)
    value = -sorted_DD[index]
    value = np.array(value).item()

    return value
//  [python]
def compute_volumetric_rendering_weights_with_alpha_numpy(alpha):
    density_exp = 1.0 - alpha
    density_exp_shifted = numpy.concatenate(
        [numpy.ones_like(density_exp[..., :1]), density_exp[..., :-1]], axis=-1
    )
    trans = numpy.cumprod(density_exp_shifted, axis=-1)
    weights = alpha * trans
    return weights
//  [python]
def CDaR_Rel(X, alpha=0.05):
    r"""
    Calculate the Conditional Drawdown at Risk (CDaR) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{CDaR}_{\alpha}(X) = \text{DaR}_{\alpha}(X) + \frac{1}{\alpha T}
        \sum_{i=0}^{T} \max \left [ \max_{t \in (0,T)}
        \left ( \prod_{i=0}^{t}(1+X_{i}) \right )- \prod_{i=0}^{j}(1+X_{i})
        - \text{DaR}_{\alpha}(X), 0 \right ]

    Where:

    :math:`\text{DaR}_{\alpha}` is the Drawdown at Risk of a cumpound
    cumulated return series :math:`X`.

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size..
    alpha : float, optional
        Significance level of CDaR. The default is 0.05.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        CDaR of a cumpounded cumulative returns series.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("X must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.ones(prices.shape[0])
    for i in range(1,prices.shape[0]):
        NAV[i] = NAV[i-1]*prices[i]
    DD = []
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD.append(-(peak - i) / peak)
    del DD[0]
    sorted_DD = np.sort(np.array(DD), axis=0)
    index = int(np.ceil(alpha * len(sorted_DD)) - 1)
    sum_var = 0
    for i in range(0, index + 1):
        sum_var = sum_var + sorted_DD[i] - sorted_DD[index]
    value = -sorted_DD[index] - sum_var / (alpha * len(sorted_DD))
    value = np.array(value).item()

    return value
//  [python]
def CDaR_Rel(X, alpha=0.05):
    r"""
    Calculate the Conditional Drawdown at Risk (CDaR) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{CDaR}_{\alpha}(X) = \text{DaR}_{\alpha}(X) + \frac{1}{\alpha T}
        \sum_{i=0}^{T} \max \left [ \max_{t \in (0,T)}
        \left ( \prod_{i=0}^{t}(1+X_{i}) \right )- \prod_{i=0}^{j}(1+X_{i})
        - \text{DaR}_{\alpha}(X), 0 \right ]

    Where:

    :math:`\text{DaR}_{\alpha}` is the Drawdown at Risk of a cumpound
    cumulated return series :math:`X`.

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size..
    alpha : float, optional
        Significance level of CDaR. The default is 0.05.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        CDaR of a cumpounded cumulative returns series.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("X must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.cumprod(prices, axis=0)
    DD = []
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD.append(-(peak - i) / peak)
    del DD[0]
    sorted_DD = np.sort(np.array(DD), axis=0)
    index = int(np.ceil(alpha * len(sorted_DD)) - 1)
    sum_var = 0
    for i in range(0, index + 1):
        sum_var = sum_var + sorted_DD[i] - sorted_DD[index]
    value = -sorted_DD[index] - sum_var / (alpha * len(sorted_DD))
    value = np.array(value).item()

    return value
//  [python]
def UCI_Rel(X):
    r"""
    Calculate the Ulcer Index (UCI) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{UCI}(X) =\sqrt{\frac{1}{T}\sum_{j=0}^{T} \left [ \max_{t \in
        (0,j)} \left ( \prod_{i=0}^{t}(1+X_{i}) \right )- \prod_{i=0}^{j}
        (1+X_{i}) \right ] ^2}

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        Ulcer Index of a cumpounded cumulative returns.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("returns must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = 1
    for i in range(len(prices)):
        NAV = NAV * prices[i]
    value = 0
    peak = -99999
    n = 0
    for i in NAV:
        if i > peak:
            peak = i
        DD = (peak - i) / peak
        if DD > 0:
            value += DD**2
        n += 1
    if n == 0:
        value = 0
    else:
        value = np.sqrt(value / (n - 1))

    value = np.array(value).item()

    return value
//  [python]
def UCI_Rel(X):
    r"""
    Calculate the Ulcer Index (UCI) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{UCI}(X) =\sqrt{\frac{1}{T}\sum_{j=0}^{T} \left [ \max_{t \in
        (0,j)} \left ( \prod_{i=0}^{t}(1+X_{i}) \right )- \prod_{i=0}^{j}
        (1+X_{i}) \right ] ^2}

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    value : float
        Ulcer Index of a cumpounded cumulative returns.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("returns must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.cumprod(prices, axis=0)
    value = 0
    peak = -99999
    n = 0
    for i in NAV:
        if i > peak:
            peak = i
        DD = (peak - i) / peak
        if DD > 0:
            value += DD**2
        n += 1
    if n == 0:
        value = 0
    else:
        value = np.sqrt(value / (n - 1))

    value = np.array(value).item()

    return value
//  [python]
def EDaR_Rel(X, alpha=0.05):
    r"""
    Calculate the Entropic Drawdown at Risk (EDaR) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{EDaR}_{\alpha}(X) & = \inf_{z>0} \left \{ z
        \ln \left (\frac{M_{\text{DD}(X)}(z^{-1})}{\alpha} \right ) \right \}  \\
        \text{DD}(X,j) & = \max_{t \in (0,j)} \left ( \prod_{i=0}^{t}(1+X_{i})
        \right )- \prod_{i=0}^{j}(1+X_{i})

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size..
    alpha : float, optional
        Significance level of EDaR. The default is 0.05.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    (value, z) : tuple
        EDaR of a cumpounded cumulative returns series
        and value of z that minimize EDaR.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("X must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.array([1])
    for i in range(1,len(prices)):
        NAV = np.append(NAV,NAV[-1]*prices[i])

    DD = []
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD.append(-(peak - i) / peak)
    del DD[0]

    (value, t) = EVaR_Hist(np.array(DD), alpha=alpha)

    return (value, t)
//  [python]
def EDaR_Rel(X, alpha=0.05):
    r"""
    Calculate the Entropic Drawdown at Risk (EDaR) of a returns series
    using cumpounded cumulative returns.

    .. math::
        \text{EDaR}_{\alpha}(X) & = \inf_{z>0} \left \{ z
        \ln \left (\frac{M_{\text{DD}(X)}(z^{-1})}{\alpha} \right ) \right \}  \\
        \text{DD}(X,j) & = \max_{t \in (0,j)} \left ( \prod_{i=0}^{t}(1+X_{i})
        \right )- \prod_{i=0}^{j}(1+X_{i})

    Parameters
    ----------
    X : 1d-array
        Returns series, must have Tx1 size..
    alpha : float, optional
        Significance level of EDaR. The default is 0.05.

    Raises
    ------
    ValueError
        When the value cannot be calculated.

    Returns
    -------
    (value, z) : tuple
        EDaR of a cumpounded cumulative returns series
        and value of z that minimize EDaR.

    """

    a = np.array(X, ndmin=2)
    if a.shape[0] == 1 and a.shape[1] > 1:
        a = a.T
    if a.shape[0] > 1 and a.shape[1] > 1:
        raise ValueError("X must have Tx1 size")

    prices = 1 + np.insert(np.array(a), 0, 0, axis=0)
    NAV = np.cumprod(prices, axis=0)
    DD = []
    peak = -99999
    for i in NAV:
        if i > peak:
            peak = i
        DD.append(-(peak - i) / peak)
    del DD[0]

    (value, t) = EVaR_Hist(np.array(DD), alpha=alpha)

    return (value, t)
//  [python]
def expand(self, name, shape):
        """ Expand the meta-data identified by name to match the given shape.
        """
        
        value = self[name]
        # Check the shape of non-repeated values
        if numpy.shape(value)[:-1] != shape[:numpy.ndim(value)-1]:
            raise Exception("Pixel data and meta data not compatible")
        
        # Number of time we need to repeat the value: depends on the unspecified
        # (i.e. last) coordinates
        repeats = shape[-(len(shape)-numpy.ndim(value)+1):]
        repeats = numpy.prod(repeats)
        # Concatenate along the last (innermost) axis
        repeated = numpy.concatenate(repeats*[value], -1)
        # Restore original shape, don't forget that the value at each point is a list
        repeated = repeated.reshape(shape+(-1,))
        
        return repeated
//  [python]
def expand(self, name, shape):
        """ Expand the meta-data identified by name to match the given shape.
        """
        
        value = self[name]
        # Check the shape of non-repeated values
        if numpy.shape(value)[:-1] != shape[:numpy.ndim(value)-1]:
            raise Exception("Pixel data and meta data not compatible")
        
        # Number of time we need to repeat the value: depends on the unspecified
        # (i.e. last) coordinates
        repeats = shape[-(len(shape)-numpy.ndim(value)+1):]
        repeats = numpy.cumprod(repeats)[-1]
        # Concatenate along the last (innermost) axis
        repeated = numpy.concatenate(repeats*[value], -1)
        # Restore original shape, don't forget that the value at each point is a list
        repeated = repeated.reshape(shape+(-1,))
        
        return repeated
//  [python]
def frame_groups(self, value):
        self._frame_groups = value
        
        shape = [count for count, _, _ in self._frame_groups][::-1]
        
        self._frames_count = n.cumprod(shape)[-1] if shape else 0
        self._dependent_fields = list(
            itertools.chain(*[fields for _, _, fields in self.frame_groups]))
        self._strides = n.cumprod([1]+shape[:-1])
//  [python]
def frame_groups(self, value):
        self._frame_groups = value
        
        shape = [count for count, _, _ in self._frame_groups][::-1]
        
        self._frames_count = numpy.cumprod(shape)[-1] if shape else 0
        self._dependent_fields = list(
            itertools.chain(*[fields for _, _, fields in self.frame_groups]))
        self._strides = numpy.cumprod([1]+shape[:-1])
//  [python]
def test_render_empty_dfs(self):
        empty_df = DataFrame()
        es = Styler(empty_df)
        es.render()
        # An index but no columns
        DataFrame(columns=["a"]).style.render()
        # A column but no index
        DataFrame(index=["a"]).style.render()
//  [python]
def test_render_empty_dfs(self):
        empty_df = DataFrame()
        es = Styler(empty_df)
        es.to_html()
        # An index but no columns
        DataFrame(columns=["a"]).style.to_html()
        # A column but no index
        DataFrame(index=["a"]).style.to_html()
//  [python]
def test_caption(self):
        styler = Styler(self.df, caption='foo')
        result = styler.render()
        assert all(['caption' in result, 'foo' in result])

        styler = self.df.style
        result = styler.set_caption('baz')
        assert styler is result
        assert styler.caption == 'baz'
//  [python]
def test_caption(self):
        styler = Styler(self.df, caption='foo')
        result = styler.to_html()
        assert all(['caption' in result, 'foo' in result])

        styler = self.df.style
        result = styler.set_caption('baz')
        assert styler is result
        assert styler.caption == 'baz'
//  [python]
def test_no_cell_ids(self):
        # GH 35588
        # GH 35663
        df = DataFrame(data=[[0]])
        styler = Styler(df, uuid="_", cell_ids=False)
        styler.render()
        s = styler.render()  # render twice to ensure ctx is not updated
        assert s.find('<td  class="data row0 col0" >') != -1
//  [python]
def test_no_cell_ids(self):
        # GH 35588
        # GH 35663
        df = DataFrame(data=[[0]])
        styler = Styler(df, uuid="_", cell_ids=False)
        styler.to_html()
        s = styler.to_html()  # render twice to ensure ctx is not updated
        assert s.find('<td  class="data row0 col0" >') != -1
//  [python]
def test_caption(self):
        styler = Styler(self.df, caption="foo")
        result = styler.render()
        assert all(["caption" in result, "foo" in result])

        styler = self.df.style
        result = styler.set_caption("baz")
        assert styler is result
        assert styler.caption == "baz"
//  [python]
def test_caption(self):
        styler = Styler(self.df, caption="foo")
        result = styler.to_html()
        assert all(["caption" in result, "foo" in result])

        styler = self.df.style
        result = styler.set_caption("baz")
        assert styler is result
        assert styler.caption == "baz"
//  [python]
def test_table_styles(self):
        style = [{"selector": "th", "props": [("foo", "bar")]}]
        styler = Styler(self.df, table_styles=style)
        result = " ".join(styler.render().split())
        assert "th { foo: bar; }" in result

        styler = self.df.style
        result = styler.set_table_styles(style)
        assert styler is result
        assert styler.table_styles == style
//  [python]
def test_table_styles(self):
        style = [{"selector": "th", "props": [("foo", "bar")]}]
        styler = Styler(self.df, table_styles=style)
        result = " ".join(styler.to_html().split())
        assert "th { foo: bar; }" in result

        styler = self.df.style
        result = styler.set_table_styles(style)
        assert styler is result
        assert styler.table_styles == style
//  [python]
def test_table_styles(self):
        style = [{'selector': 'th', 'props': [('foo', 'bar')]}]
        styler = Styler(self.df, table_styles=style)
        result = ' '.join(styler.render().split())
        assert 'th { foo: bar; }' in result

        styler = self.df.style
        result = styler.set_table_styles(style)
        assert styler is result
        assert styler.table_styles == style
//  [python]
def test_table_styles(self):
        style = [{'selector': 'th', 'props': [('foo', 'bar')]}]
        styler = Styler(self.df, table_styles=style)
        result = ' '.join(styler.to_html().split())
        assert 'th { foo: bar; }' in result

        styler = self.df.style
        result = styler.set_table_styles(style)
        assert styler is result
        assert styler.table_styles == style
//  [python]
def test_column_and_row_styling(self):
        # GH 35607
        df = DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
        s = Styler(df, uuid_len=0)
        s = s.set_table_styles({"A": [{"selector": "", "props": [("color", "blue")]}]})
        assert "#T__ .col0 {\n  color: blue;\n}" in s.render()
        s = s.set_table_styles(
            {0: [{"selector": "", "props": [("color", "blue")]}]}, axis=1
        )
        assert "#T__ .row0 {\n  color: blue;\n}" in s.render()
//  [python]
def test_column_and_row_styling(self):
        # GH 35607
        df = DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
        s = Styler(df, uuid_len=0)
        s = s.set_table_styles({"A": [{"selector": "", "props": [("color", "blue")]}]})
        assert "#T__ .col0 {\n  color: blue;\n}" in s.to_html()
        s = s.set_table_styles(
            {0: [{"selector": "", "props": [("color", "blue")]}]}, axis=1
        )
        assert "#T__ .row0 {\n  color: blue;\n}" in s.to_html()
//  [python]
def test_table_styles(self):
        style = [{"selector": "th", "props": [("foo", "bar")]}]  # default format
        styler = Styler(self.df, table_styles=style)
        result = " ".join(styler.render().split())
        assert "th { foo: bar; }" in result

        styler = self.df.style
        result = styler.set_table_styles(style)
        assert styler is result
        assert styler.table_styles == style

        # GH 39563
        style = [{"selector": "th", "props": "foo:bar;"}]  # css string format
        styler = self.df.style.set_table_styles(style)
        result = " ".join(styler.render().split())
        assert "th { foo: bar; }" in result
//  [python]
def test_table_styles(self):
        style = [{"selector": "th", "props": [("foo", "bar")]}]  # default format
        styler = Styler(self.df, table_styles=style)
        result = " ".join(styler.to_html().split())
        assert "th { foo: bar; }" in result

        styler = self.df.style
        result = styler.set_table_styles(style)
        assert styler is result
        assert styler.table_styles == style

        # GH 39563
        style = [{"selector": "th", "props": "foo:bar;"}]  # css string format
        styler = self.df.style.set_table_styles(style)
        result = " ".join(styler.to_html().split())
        assert "th { foo: bar; }" in result
//  [python]
def test_colspan_w3(self):
        # GH 36223
        df = DataFrame(data=[[1, 2]], columns=[["l0", "l0"], ["l1a", "l1b"]])
        s = Styler(df, uuid="_", cell_ids=False)
        assert '<th class="col_heading level0 col0" colspan="2">l0</th>' in s.render()
//  [python]
def test_colspan_w3(self):
        # GH 36223
        df = DataFrame(data=[[1, 2]], columns=[["l0", "l0"], ["l1a", "l1b"]])
        s = Styler(df, uuid="_", cell_ids=False)
        assert '<th class="col_heading level0 col0" colspan="2">l0</th>' in s.to_html()
//  [python]
def test_rowspan_w3(self):
        # GH 38533
        df = DataFrame(data=[[1, 2]], index=[["l0", "l0"], ["l1a", "l1b"]])
        s = Styler(df, uuid="_", cell_ids=False)
        assert (
            '<th id="T___level0_row0" class="row_heading '
            'level0 row0" rowspan="2">l0</th>' in s.render()
        )
//  [python]
def test_rowspan_w3(self):
        # GH 38533
        df = DataFrame(data=[[1, 2]], index=[["l0", "l0"], ["l1a", "l1b"]])
        s = Styler(df, uuid="_", cell_ids=False)
        assert (
            '<th id="T___level0_row0" class="row_heading '
            'level0 row0" rowspan="2">l0</th>' in s.to_html()
        )
//  [python]
def test_colspan_w3():
    # GH 36223
    df = DataFrame(data=[[1, 2]], columns=[["l0", "l0"], ["l1a", "l1b"]])
    styler = Styler(df, uuid="_", cell_ids=False)
    assert '<th class="col_heading level0 col0" colspan="2">l0</th>' in styler.render()
//  [python]
def test_colspan_w3():
    # GH 36223
    df = DataFrame(data=[[1, 2]], columns=[["l0", "l0"], ["l1a", "l1b"]])
    styler = Styler(df, uuid="_", cell_ids=False)
    assert '<th class="col_heading level0 col0" colspan="2">l0</th>' in styler.to_html()
//  [python]
def test_column_and_row_styling(self):
        # GH 35607
        df = DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
        s = Styler(df, uuid_len=0)
        s = s.set_table_styles({"A": [{"selector": "", "props": [("color", "blue")]}]})
        assert "#T__ .col0 {\n          color: blue;\n    }" in s.render()
        s = s.set_table_styles(
            {0: [{"selector": "", "props": [("color", "blue")]}]}, axis=1
        )
        assert "#T__ .row0 {\n          color: blue;\n    }" in s.render()
//  [python]
def test_column_and_row_styling(self):
        # GH 35607
        df = DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
        s = Styler(df, uuid_len=0)
        s = s.set_table_styles({"A": [{"selector": "", "props": [("color", "blue")]}]})
        assert "#T__ .col0 {\n          color: blue;\n    }" in s.to_html()
        s = s.set_table_styles(
            {0: [{"selector": "", "props": [("color", "blue")]}]}, axis=1
        )
        assert "#T__ .row0 {\n          color: blue;\n    }" in s.to_html()
//  [python]
def test_no_cell_ids(self):
        # GH 35588
        # GH 35663
        df = pd.DataFrame(data=[[0]])
        styler = Styler(df, uuid="_", cell_ids=False)
        styler.render()
        s = styler.render()  # render twice to ensure ctx is not updated
        assert s.find('<td  class="data row0 col0" >') != -1
//  [python]
def test_no_cell_ids(self):
        # GH 35588
        # GH 35663
        df = pd.DataFrame(data=[[0]])
        styler = Styler(df, uuid="_", cell_ids=False)
        styler.to_html()
        s = styler.to_html()  # render twice to ensure ctx is not updated
        assert s.find('<td  class="data row0 col0" >') != -1