Repository: scipy/scipy
File: scipy/stats/tests/test_stats.py (Python)

Code before:
    # by Herve Abdi.
    values = range(5, 11)
    reps = np.array([5, 11, 9, 3, 2, 2])
    data = np.repeat(values, reps)
    transformed_values = np.array([3.1828, 0.5591, 0.0344,
                                   1.6086, 5.2817, 11.0538])
    expected = np.repeat(transformed_values, reps)
    result = stats.obrientransform(data)
    assert_array_almost_equal(result[0], expected, decimal=4)


def check_equal_xmean(*args, xp, mean_fun, axis=None, dtype=None,
                      rtol=1e-7, weights=None):
    # Note this doesn't test when axis is not specified
    dtype = dtype or xp.float64
    if len(args) == 2:
        array_like, desired = args
    else:
        array_like, p, desired = args
    array_like = xp.asarray(array_like, dtype=dtype)
    desired = xp.asarray(desired, dtype=dtype)
    weights = xp.asarray(weights, dtype=dtype) if weights is not None else weights
    args = (array_like,) if len(args) == 2 else (array_like, p)
    x = mean_fun(*args, axis=axis, dtype=dtype, weights=weights)
    xp_assert_close(x, desired, rtol=rtol)


def check_equal_gmean(*args, **kwargs):
    return check_equal_xmean(*args, mean_fun=stats.gmean, **kwargs)


def check_equal_hmean(*args, **kwargs):
    return check_equal_xmean(*args, mean_fun=stats.hmean, **kwargs)


def check_equal_pmean(*args, **kwargs):
    return check_equal_xmean(*args, mean_fun=stats.pmean, **kwargs)


@make_xp_test_case(stats.hmean)
class TestHMean:
    @pytest.mark.filterwarnings("ignore:divide by zero encountered:RuntimeWarning:dask")
    def test_0(self, xp):
        a = [1, 0, 2]
        desired = 0
        check_equal_hmean(a, desired, xp=xp)

    def test_1d(self, xp):
        #  Test a 1d case
        a = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
        desired = 34.1417152147

Review comment (suggestion):
Pretty much all tests of the functions use `check_equal_xmean`. We shouldn't be passing `dtype` into every call of the function; we want to see that `dtype` is preserved when no `dtype` is specified. I assume there is some other test that explicitly uses the `dtype` parameter of the function; if not, feel free to push the addition or open a new PR.

Code after:
    # by Herve Abdi.
    values = range(5, 11)
    reps = np.array([5, 11, 9, 3, 2, 2])
    data = np.repeat(values, reps)
    transformed_values = np.array([3.1828, 0.5591, 0.0344,
                                   1.6086, 5.2817, 11.0538])
    expected = np.repeat(transformed_values, reps)
    result = stats.obrientransform(data)
    assert_array_almost_equal(result[0], expected, decimal=4)


def check_equal_xmean(*args, xp, mean_fun, axis=None, dtype=None,
                      rtol=None, weights=None):
    # Note this doesn't test when axis is not specified
    dtype = dtype or xp.float64
    if len(args) == 2:
        array_like, desired = args
    else:
        array_like, p, desired = args
    array_like = xp.asarray(array_like, dtype=dtype)
    dtype_reference = (xp_result_type(array_like, force_floating=True, xp=xp)
                       if xp != np.ma else None)
    desired = xp.asarray(desired, dtype=dtype_reference)
    weights = xp.asarray(weights, dtype=dtype) if weights is not None else weights
    args = (array_like,) if len(args) == 2 else (array_like, p)
    x = mean_fun(*args, axis=axis, weights=weights)
    xp_assert_close(x, desired, rtol=rtol)


def check_equal_gmean(*args, **kwargs):
    return check_equal_xmean(*args, mean_fun=stats.gmean, **kwargs)


def check_equal_hmean(*args, **kwargs):
    return check_equal_xmean(*args, mean_fun=stats.hmean, **kwargs)


def check_equal_pmean(*args, **kwargs):
    return check_equal_xmean(*args, mean_fun=stats.pmean, **kwargs)


@make_xp_test_case(stats.hmean)
class TestHMean:
    @pytest.mark.filterwarnings("ignore:divide by zero encountered:RuntimeWarning:dask")
    def test_0(self, xp):
        a = [1, 0, 2]
        desired = 0
        check_equal_hmean(a, desired, xp=xp)

    @pytest.mark.parametrize('dtype', [None, 'int64', 'float32', 'float64'])
    def test_1d(self, dtype, xp):