# Path: diffprivlib/tools/quantiles.py
# def median(array, epsilon=1.0, bounds=None, axis=None, keepdims=False, accountant=None, **unused_args):
#     r"""
#     Compute the differentially private median of the array.
# 
#     Returns the median with differential privacy.  The median is calculated over each axis, or the flattened array
#     if an axis is not provided.  This method calls the :obj:`.quantile` method, for the 0.5 quantile.
# 
#     Parameters
#     ----------
#     array : array_like
#         Array containing numbers whose median is sought.  If `array` is not an array, a conversion is attempted.
# 
#     epsilon : float, default: 1.0
#         Privacy parameter :math:`\epsilon`.  Differential privacy is achieved over the entire output, with epsilon split
#         evenly between each output value.
# 
#     bounds : tuple, optional
#         Bounds of the values of the array, of the form (min, max).
# 
#     axis : None or int or tuple of ints, optional
#         Axis or axes along which a sum is performed.  The default, axis=None, will sum all of the elements of the input
#         array.  If axis is negative it counts from the last to the first axis.
# 
#         If axis is a tuple of ints, a sum is performed on all of the axes specified in the tuple instead of a single
#         axis or all the axes as before.
# 
#     keepdims : bool, default: False
#         If this is set to True, the axes which are reduced are left in the result as dimensions with size one.  With
#         this option, the result will broadcast correctly against the input array.
# 
#         If the default value is passed, then `keepdims` will not be passed through to the `mean` method of sub-classes
#         of `ndarray`, however any non-default value will be.  If the sub-class' method does not implement `keepdims` any
#         exceptions will be raised.
# 
#     accountant : BudgetAccountant, optional
#         Accountant to keep track of privacy budget.
# 
#     Returns
#     -------
#     m : ndarray
#         Returns a new array containing the median values.
# 
#     See Also
#     --------
#     numpy.median : Equivalent non-private method.
# 
#     quantile, percentile
# 
#     """
#     warn_unused_args(unused_args)
# 
#     return quantile(array, 0.5, epsilon=epsilon, bounds=bounds, axis=axis, keepdims=keepdims, accountant=accountant)
# 
# Path: diffprivlib/utils.py
# class PrivacyLeakWarning(RuntimeWarning):
#     """Custom warning to capture privacy leaks resulting from incorrect parameter setting.
# 
#     For example, this warning may occur when the user:
# 
#         - fails to specify the bounds or range of data to a model where required (e.g., `bounds=None` to
#           :class:`.GaussianNB`).
#         - inputs data to a model that falls outside the bounds or range originally specified.
# 
#     """
# 
# class BudgetError(ValueError):
#     """Custom exception to capture the privacy budget being exceeded, typically controlled by a
#     :class:`.BudgetAccountant`.
# 
#     For example, this exception may be raised when the user:
# 
#         - Attempts to execute a query which would exceed the privacy budget of the accountant.
#         - Attempts to change the slack of the accountant in such a way that the existing budget spends would exceed the
#           accountant's budget.
# 
#     """


from unittest import TestCase
from diffprivlib.tools.quantiles import median
from diffprivlib.utils import PrivacyLeakWarning, BudgetError
        from diffprivlib.accountant import BudgetAccountant
        from diffprivlib.accountant import BudgetAccountant
import numpy as np
        a = np.random.random((10, 5))
        out = median(a, epsilon=1, bounds=(0, 1), keepdims=True)
        self.assertEqual(a.ndim, out.ndim)

    def test_array_like(self):
        self.assertIsNotNone(median([1, 2, 3], bounds=(1, 3)))
        self.assertIsNotNone(median((1, 2, 3), bounds=(1, 3)))

    def test_clipped_output(self):
        a = np.random.random((10,))

        for i in range(100):
            self.assertTrue(0 <= median(a, epsilon=1e-5, bounds=(0, 1)) <= 1)

    def test_nan(self):
        a = np.random.random((5, 5))
        a[2, 2] = np.nan

        res = median(a, bounds=(0, 1))
        self.assertTrue(np.isnan(res))

    def test_accountant(self):
        acc = BudgetAccountant(1.5, 0)

        a = np.random.random((1000, 5))
        median(a, epsilon=1, bounds=(0, 1), accountant=acc)
        self.assertEqual((1.0, 0), acc.total())

        with acc:
            with self.assertRaises(BudgetError):

# Path: diffprivlib/tools/quantiles.py
# def median(array, epsilon=1.0, bounds=None, axis=None, keepdims=False, accountant=None, **unused_args):
#     r"""
#     Compute the differentially private median of the array.
# 
#     Returns the median with differential privacy.  The median is calculated over each axis, or the flattened array
#     if an axis is not provided.  This method calls the :obj:`.quantile` method, for the 0.5 quantile.
# 
#     Parameters
#     ----------
#     array : array_like
#         Array containing numbers whose median is sought.  If `array` is not an array, a conversion is attempted.
# 
#     epsilon : float, default: 1.0
#         Privacy parameter :math:`\epsilon`.  Differential privacy is achieved over the entire output, with epsilon split
#         evenly between each output value.
# 
#     bounds : tuple, optional
#         Bounds of the values of the array, of the form (min, max).
# 
#     axis : None or int or tuple of ints, optional
#         Axis or axes along which a sum is performed.  The default, axis=None, will sum all of the elements of the input
#         array.  If axis is negative it counts from the last to the first axis.
# 
#         If axis is a tuple of ints, a sum is performed on all of the axes specified in the tuple instead of a single
#         axis or all the axes as before.
# 
#     keepdims : bool, default: False
#         If this is set to True, the axes which are reduced are left in the result as dimensions with size one.  With
#         this option, the result will broadcast correctly against the input array.
# 
#         If the default value is passed, then `keepdims` will not be passed through to the `mean` method of sub-classes
#         of `ndarray`, however any non-default value will be.  If the sub-class' method does not implement `keepdims` any
#         exceptions will be raised.
# 
#     accountant : BudgetAccountant, optional
#         Accountant to keep track of privacy budget.
# 
#     Returns
#     -------
#     m : ndarray
#         Returns a new array containing the median values.
# 
#     See Also
#     --------
#     numpy.median : Equivalent non-private method.
# 
#     quantile, percentile
# 
#     """
#     warn_unused_args(unused_args)
# 
#     return quantile(array, 0.5, epsilon=epsilon, bounds=bounds, axis=axis, keepdims=keepdims, accountant=accountant)
# 
# Path: diffprivlib/utils.py
# class PrivacyLeakWarning(RuntimeWarning):
#     """Custom warning to capture privacy leaks resulting from incorrect parameter setting.
# 
#     For example, this warning may occur when the user:
# 
#         - fails to specify the bounds or range of data to a model where required (e.g., `bounds=None` to
#           :class:`.GaussianNB`).
#         - inputs data to a model that falls outside the bounds or range originally specified.
# 
#     """
# 
# class BudgetError(ValueError):
#     """Custom exception to capture the privacy budget being exceeded, typically controlled by a
#     :class:`.BudgetAccountant`.
# 
#     For example, this exception may be raised when the user:
# 
#         - Attempts to execute a query which would exceed the privacy budget of the accountant.
#         - Attempts to change the slack of the accountant in such a way that the existing budget spends would exceed the
#           accountant's budget.
# 
#     """


# Path: tests/tools/test_median.py
from unittest import TestCase
from diffprivlib.tools.quantiles import median
from diffprivlib.utils import PrivacyLeakWarning, BudgetError
        from diffprivlib.accountant import BudgetAccountant
        from diffprivlib.accountant import BudgetAccountant
import numpy as np

        a = np.random.random((10, 5))
        out = median(a, epsilon=1, bounds=(0, 1), keepdims=True)
        self.assertEqual(a.ndim, out.ndim)

    def test_array_like(self):
        self.assertIsNotNone(median([1, 2, 3], bounds=(1, 3)))
        self.assertIsNotNone(median((1, 2, 3), bounds=(1, 3)))

    def test_clipped_output(self):
        a = np.random.random((10,))

        for i in range(100):
            self.assertTrue(0 <= median(a, epsilon=1e-5, bounds=(0, 1)) <= 1)

    def test_nan(self):
        a = np.random.random((5, 5))
        a[2, 2] = np.nan

        res = median(a, bounds=(0, 1))
        self.assertTrue(np.isnan(res))

    def test_accountant(self):
        acc = BudgetAccountant(1.5, 0)

        a = np.random.random((1000, 5))
        median(a, epsilon=1, bounds=(0, 1), accountant=acc)
        self.assertEqual((1.0, 0), acc.total())

        with acc:
            with self.assertRaises(BudgetError):

                median(a, epsilon=1, bounds=(0, 1))