17db96d56Sopenharmony_ci"""Random variable generators.
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci    bytes
47db96d56Sopenharmony_ci    -----
57db96d56Sopenharmony_ci           uniform bytes (values between 0 and 255)
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci    integers
87db96d56Sopenharmony_ci    --------
97db96d56Sopenharmony_ci           uniform within range
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci    sequences
127db96d56Sopenharmony_ci    ---------
137db96d56Sopenharmony_ci           pick random element
147db96d56Sopenharmony_ci           pick random sample
157db96d56Sopenharmony_ci           pick weighted random sample
167db96d56Sopenharmony_ci           generate random permutation
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci    distributions on the real line:
197db96d56Sopenharmony_ci    ------------------------------
207db96d56Sopenharmony_ci           uniform
217db96d56Sopenharmony_ci           triangular
227db96d56Sopenharmony_ci           normal (Gaussian)
237db96d56Sopenharmony_ci           lognormal
247db96d56Sopenharmony_ci           negative exponential
257db96d56Sopenharmony_ci           gamma
267db96d56Sopenharmony_ci           beta
277db96d56Sopenharmony_ci           pareto
287db96d56Sopenharmony_ci           Weibull
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci    distributions on the circle (angles 0 to 2pi)
317db96d56Sopenharmony_ci    ---------------------------------------------
327db96d56Sopenharmony_ci           circular uniform
337db96d56Sopenharmony_ci           von Mises
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ciGeneral notes on the underlying Mersenne Twister core generator:
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci* The period is 2**19937-1.
387db96d56Sopenharmony_ci* It is one of the most extensively tested generators in existence.
397db96d56Sopenharmony_ci* The random() method is implemented in C, executes in a single Python step,
407db96d56Sopenharmony_ci  and is, therefore, threadsafe.
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci"""
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci# Translated by Guido van Rossum from C source provided by
457db96d56Sopenharmony_ci# Adrian Baddeley.  Adapted by Raymond Hettinger for use with
467db96d56Sopenharmony_ci# the Mersenne Twister  and os.urandom() core generators.
477db96d56Sopenharmony_ci
487db96d56Sopenharmony_cifrom warnings import warn as _warn
497db96d56Sopenharmony_cifrom math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
507db96d56Sopenharmony_cifrom math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
517db96d56Sopenharmony_cifrom math import tau as TWOPI, floor as _floor, isfinite as _isfinite
527db96d56Sopenharmony_cifrom os import urandom as _urandom
537db96d56Sopenharmony_cifrom _collections_abc import Set as _Set, Sequence as _Sequence
547db96d56Sopenharmony_cifrom operator import index as _index
557db96d56Sopenharmony_cifrom itertools import accumulate as _accumulate, repeat as _repeat
567db96d56Sopenharmony_cifrom bisect import bisect as _bisect
577db96d56Sopenharmony_ciimport os as _os
587db96d56Sopenharmony_ciimport _random
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_citry:
617db96d56Sopenharmony_ci    # hashlib is pretty heavy to load, try lean internal module first
627db96d56Sopenharmony_ci    from _sha512 import sha512 as _sha512
637db96d56Sopenharmony_ciexcept ImportError:
647db96d56Sopenharmony_ci    # fallback to official implementation
657db96d56Sopenharmony_ci    from hashlib import sha512 as _sha512
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci__all__ = [
687db96d56Sopenharmony_ci    "Random",
697db96d56Sopenharmony_ci    "SystemRandom",
707db96d56Sopenharmony_ci    "betavariate",
717db96d56Sopenharmony_ci    "choice",
727db96d56Sopenharmony_ci    "choices",
737db96d56Sopenharmony_ci    "expovariate",
747db96d56Sopenharmony_ci    "gammavariate",
757db96d56Sopenharmony_ci    "gauss",
767db96d56Sopenharmony_ci    "getrandbits",
777db96d56Sopenharmony_ci    "getstate",
787db96d56Sopenharmony_ci    "lognormvariate",
797db96d56Sopenharmony_ci    "normalvariate",
807db96d56Sopenharmony_ci    "paretovariate",
817db96d56Sopenharmony_ci    "randbytes",
827db96d56Sopenharmony_ci    "randint",
837db96d56Sopenharmony_ci    "random",
847db96d56Sopenharmony_ci    "randrange",
857db96d56Sopenharmony_ci    "sample",
867db96d56Sopenharmony_ci    "seed",
877db96d56Sopenharmony_ci    "setstate",
887db96d56Sopenharmony_ci    "shuffle",
897db96d56Sopenharmony_ci    "triangular",
907db96d56Sopenharmony_ci    "uniform",
917db96d56Sopenharmony_ci    "vonmisesvariate",
927db96d56Sopenharmony_ci    "weibullvariate",
937db96d56Sopenharmony_ci]
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ciNV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
967db96d56Sopenharmony_ciLOG4 = _log(4.0)
977db96d56Sopenharmony_ciSG_MAGICCONST = 1.0 + _log(4.5)
987db96d56Sopenharmony_ciBPF = 53        # Number of bits in a float
997db96d56Sopenharmony_ciRECIP_BPF = 2 ** -BPF
1007db96d56Sopenharmony_ci_ONE = 1
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ciclass Random(_random.Random):
1047db96d56Sopenharmony_ci    """Random number generator base class used by bound module functions.
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci    Used to instantiate instances of Random to get generators that don't
1077db96d56Sopenharmony_ci    share state.
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci    Class Random can also be subclassed if you want to use a different basic
1107db96d56Sopenharmony_ci    generator of your own devising: in that case, override the following
1117db96d56Sopenharmony_ci    methods:  random(), seed(), getstate(), and setstate().
1127db96d56Sopenharmony_ci    Optionally, implement a getrandbits() method so that randrange()
1137db96d56Sopenharmony_ci    can cover arbitrarily large ranges.
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci    """
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ci    VERSION = 3     # used by getstate/setstate
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci    def __init__(self, x=None):
1207db96d56Sopenharmony_ci        """Initialize an instance.
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci        Optional argument x controls seeding, as for Random.seed().
1237db96d56Sopenharmony_ci        """
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci        self.seed(x)
1267db96d56Sopenharmony_ci        self.gauss_next = None
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci    def seed(self, a=None, version=2):
1297db96d56Sopenharmony_ci        """Initialize internal state from a seed.
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci        The only supported seed types are None, int, float,
1327db96d56Sopenharmony_ci        str, bytes, and bytearray.
1337db96d56Sopenharmony_ci
1347db96d56Sopenharmony_ci        None or no argument seeds from current time or from an operating
1357db96d56Sopenharmony_ci        system specific randomness source if available.
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci        If *a* is an int, all bits are used.
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci        For version 2 (the default), all of the bits are used if *a* is a str,
1407db96d56Sopenharmony_ci        bytes, or bytearray.  For version 1 (provided for reproducing random
1417db96d56Sopenharmony_ci        sequences from older versions of Python), the algorithm for str and
1427db96d56Sopenharmony_ci        bytes generates a narrower range of seeds.
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ci        """
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci        if version == 1 and isinstance(a, (str, bytes)):
1477db96d56Sopenharmony_ci            a = a.decode('latin-1') if isinstance(a, bytes) else a
1487db96d56Sopenharmony_ci            x = ord(a[0]) << 7 if a else 0
1497db96d56Sopenharmony_ci            for c in map(ord, a):
1507db96d56Sopenharmony_ci                x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF
1517db96d56Sopenharmony_ci            x ^= len(a)
1527db96d56Sopenharmony_ci            a = -2 if x == -1 else x
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ci        elif version == 2 and isinstance(a, (str, bytes, bytearray)):
1557db96d56Sopenharmony_ci            if isinstance(a, str):
1567db96d56Sopenharmony_ci                a = a.encode()
1577db96d56Sopenharmony_ci            a = int.from_bytes(a + _sha512(a).digest())
1587db96d56Sopenharmony_ci
1597db96d56Sopenharmony_ci        elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)):
1607db96d56Sopenharmony_ci            raise TypeError('The only supported seed types are: None,\n'
1617db96d56Sopenharmony_ci                            'int, float, str, bytes, and bytearray.')
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci        super().seed(a)
1647db96d56Sopenharmony_ci        self.gauss_next = None
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ci    def getstate(self):
1677db96d56Sopenharmony_ci        """Return internal state; can be passed to setstate() later."""
1687db96d56Sopenharmony_ci        return self.VERSION, super().getstate(), self.gauss_next
1697db96d56Sopenharmony_ci
1707db96d56Sopenharmony_ci    def setstate(self, state):
1717db96d56Sopenharmony_ci        """Restore internal state from object returned by getstate()."""
1727db96d56Sopenharmony_ci        version = state[0]
1737db96d56Sopenharmony_ci        if version == 3:
1747db96d56Sopenharmony_ci            version, internalstate, self.gauss_next = state
1757db96d56Sopenharmony_ci            super().setstate(internalstate)
1767db96d56Sopenharmony_ci        elif version == 2:
1777db96d56Sopenharmony_ci            version, internalstate, self.gauss_next = state
1787db96d56Sopenharmony_ci            # In version 2, the state was saved as signed ints, which causes
1797db96d56Sopenharmony_ci            #   inconsistencies between 32/64-bit systems. The state is
1807db96d56Sopenharmony_ci            #   really unsigned 32-bit ints, so we convert negative ints from
1817db96d56Sopenharmony_ci            #   version 2 to positive longs for version 3.
1827db96d56Sopenharmony_ci            try:
1837db96d56Sopenharmony_ci                internalstate = tuple(x % (2 ** 32) for x in internalstate)
1847db96d56Sopenharmony_ci            except ValueError as e:
1857db96d56Sopenharmony_ci                raise TypeError from e
1867db96d56Sopenharmony_ci            super().setstate(internalstate)
1877db96d56Sopenharmony_ci        else:
1887db96d56Sopenharmony_ci            raise ValueError("state with version %s passed to "
1897db96d56Sopenharmony_ci                             "Random.setstate() of version %s" %
1907db96d56Sopenharmony_ci                             (version, self.VERSION))
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci    ## -------------------------------------------------------
1947db96d56Sopenharmony_ci    ## ---- Methods below this point do not need to be overridden or extended
1957db96d56Sopenharmony_ci    ## ---- when subclassing for the purpose of using a different core generator.
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci    ## -------------------- pickle support  -------------------
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci    # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
2017db96d56Sopenharmony_ci    # longer called; we leave it here because it has been here since random was
2027db96d56Sopenharmony_ci    # rewritten back in 2001 and why risk breaking something.
2037db96d56Sopenharmony_ci    def __getstate__(self):  # for pickle
2047db96d56Sopenharmony_ci        return self.getstate()
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_ci    def __setstate__(self, state):  # for pickle
2077db96d56Sopenharmony_ci        self.setstate(state)
2087db96d56Sopenharmony_ci
2097db96d56Sopenharmony_ci    def __reduce__(self):
2107db96d56Sopenharmony_ci        return self.__class__, (), self.getstate()
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    ## ---- internal support method for evenly distributed integers ----
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ci    def __init_subclass__(cls, /, **kwargs):
2167db96d56Sopenharmony_ci        """Control how subclasses generate random integers.
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci        The algorithm a subclass can use depends on the random() and/or
2197db96d56Sopenharmony_ci        getrandbits() implementation available to it and determines
2207db96d56Sopenharmony_ci        whether it can generate random integers from arbitrarily large
2217db96d56Sopenharmony_ci        ranges.
2227db96d56Sopenharmony_ci        """
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci        for c in cls.__mro__:
2257db96d56Sopenharmony_ci            if '_randbelow' in c.__dict__:
2267db96d56Sopenharmony_ci                # just inherit it
2277db96d56Sopenharmony_ci                break
2287db96d56Sopenharmony_ci            if 'getrandbits' in c.__dict__:
2297db96d56Sopenharmony_ci                cls._randbelow = cls._randbelow_with_getrandbits
2307db96d56Sopenharmony_ci                break
2317db96d56Sopenharmony_ci            if 'random' in c.__dict__:
2327db96d56Sopenharmony_ci                cls._randbelow = cls._randbelow_without_getrandbits
2337db96d56Sopenharmony_ci                break
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci    def _randbelow_with_getrandbits(self, n):
2367db96d56Sopenharmony_ci        "Return a random int in the range [0,n).  Defined for n > 0."
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ci        getrandbits = self.getrandbits
2397db96d56Sopenharmony_ci        k = n.bit_length()  # don't use (n-1) here because n can be 1
2407db96d56Sopenharmony_ci        r = getrandbits(k)  # 0 <= r < 2**k
2417db96d56Sopenharmony_ci        while r >= n:
2427db96d56Sopenharmony_ci            r = getrandbits(k)
2437db96d56Sopenharmony_ci        return r
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci    def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):
2467db96d56Sopenharmony_ci        """Return a random int in the range [0,n).  Defined for n > 0.
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci        The implementation does not use getrandbits, but only random.
2497db96d56Sopenharmony_ci        """
2507db96d56Sopenharmony_ci
2517db96d56Sopenharmony_ci        random = self.random
2527db96d56Sopenharmony_ci        if n >= maxsize:
2537db96d56Sopenharmony_ci            _warn("Underlying random() generator does not supply \n"
2547db96d56Sopenharmony_ci                "enough bits to choose from a population range this large.\n"
2557db96d56Sopenharmony_ci                "To remove the range limitation, add a getrandbits() method.")
2567db96d56Sopenharmony_ci            return _floor(random() * n)
2577db96d56Sopenharmony_ci        rem = maxsize % n
2587db96d56Sopenharmony_ci        limit = (maxsize - rem) / maxsize   # int(limit * maxsize) % n == 0
2597db96d56Sopenharmony_ci        r = random()
2607db96d56Sopenharmony_ci        while r >= limit:
2617db96d56Sopenharmony_ci            r = random()
2627db96d56Sopenharmony_ci        return _floor(r * maxsize) % n
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci    _randbelow = _randbelow_with_getrandbits
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci    ## --------------------------------------------------------
2687db96d56Sopenharmony_ci    ## ---- Methods below this point generate custom distributions
2697db96d56Sopenharmony_ci    ## ---- based on the methods defined above.  They do not
2707db96d56Sopenharmony_ci    ## ---- directly touch the underlying generator and only
2717db96d56Sopenharmony_ci    ## ---- access randomness through the methods:  random(),
2727db96d56Sopenharmony_ci    ## ---- getrandbits(), or _randbelow().
2737db96d56Sopenharmony_ci
2747db96d56Sopenharmony_ci
2757db96d56Sopenharmony_ci    ## -------------------- bytes methods ---------------------
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci    def randbytes(self, n):
2787db96d56Sopenharmony_ci        """Generate n random bytes."""
2797db96d56Sopenharmony_ci        return self.getrandbits(n * 8).to_bytes(n, 'little')
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ci    ## -------------------- integer methods  -------------------
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci    def randrange(self, start, stop=None, step=_ONE):
2857db96d56Sopenharmony_ci        """Choose a random item from range(stop) or range(start, stop[, step]).
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ci        Roughly equivalent to ``choice(range(start, stop, step))`` but
2887db96d56Sopenharmony_ci        supports arbitrarily large ranges and is optimized for common cases.
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci        """
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci        # This code is a bit messy to make it fast for the
2937db96d56Sopenharmony_ci        # common case while still doing adequate error checking.
2947db96d56Sopenharmony_ci        try:
2957db96d56Sopenharmony_ci            istart = _index(start)
2967db96d56Sopenharmony_ci        except TypeError:
2977db96d56Sopenharmony_ci            istart = int(start)
2987db96d56Sopenharmony_ci            if istart != start:
2997db96d56Sopenharmony_ci                _warn('randrange() will raise TypeError in the future',
3007db96d56Sopenharmony_ci                      DeprecationWarning, 2)
3017db96d56Sopenharmony_ci                raise ValueError("non-integer arg 1 for randrange()")
3027db96d56Sopenharmony_ci            _warn('non-integer arguments to randrange() have been deprecated '
3037db96d56Sopenharmony_ci                  'since Python 3.10 and will be removed in a subsequent '
3047db96d56Sopenharmony_ci                  'version',
3057db96d56Sopenharmony_ci                  DeprecationWarning, 2)
3067db96d56Sopenharmony_ci        if stop is None:
3077db96d56Sopenharmony_ci            # We don't check for "step != 1" because it hasn't been
3087db96d56Sopenharmony_ci            # type checked and converted to an integer yet.
3097db96d56Sopenharmony_ci            if step is not _ONE:
3107db96d56Sopenharmony_ci                raise TypeError('Missing a non-None stop argument')
3117db96d56Sopenharmony_ci            if istart > 0:
3127db96d56Sopenharmony_ci                return self._randbelow(istart)
3137db96d56Sopenharmony_ci            raise ValueError("empty range for randrange()")
3147db96d56Sopenharmony_ci
3157db96d56Sopenharmony_ci        # stop argument supplied.
3167db96d56Sopenharmony_ci        try:
3177db96d56Sopenharmony_ci            istop = _index(stop)
3187db96d56Sopenharmony_ci        except TypeError:
3197db96d56Sopenharmony_ci            istop = int(stop)
3207db96d56Sopenharmony_ci            if istop != stop:
3217db96d56Sopenharmony_ci                _warn('randrange() will raise TypeError in the future',
3227db96d56Sopenharmony_ci                      DeprecationWarning, 2)
3237db96d56Sopenharmony_ci                raise ValueError("non-integer stop for randrange()")
3247db96d56Sopenharmony_ci            _warn('non-integer arguments to randrange() have been deprecated '
3257db96d56Sopenharmony_ci                  'since Python 3.10 and will be removed in a subsequent '
3267db96d56Sopenharmony_ci                  'version',
3277db96d56Sopenharmony_ci                  DeprecationWarning, 2)
3287db96d56Sopenharmony_ci        width = istop - istart
3297db96d56Sopenharmony_ci        try:
3307db96d56Sopenharmony_ci            istep = _index(step)
3317db96d56Sopenharmony_ci        except TypeError:
3327db96d56Sopenharmony_ci            istep = int(step)
3337db96d56Sopenharmony_ci            if istep != step:
3347db96d56Sopenharmony_ci                _warn('randrange() will raise TypeError in the future',
3357db96d56Sopenharmony_ci                      DeprecationWarning, 2)
3367db96d56Sopenharmony_ci                raise ValueError("non-integer step for randrange()")
3377db96d56Sopenharmony_ci            _warn('non-integer arguments to randrange() have been deprecated '
3387db96d56Sopenharmony_ci                  'since Python 3.10 and will be removed in a subsequent '
3397db96d56Sopenharmony_ci                  'version',
3407db96d56Sopenharmony_ci                  DeprecationWarning, 2)
3417db96d56Sopenharmony_ci        # Fast path.
3427db96d56Sopenharmony_ci        if istep == 1:
3437db96d56Sopenharmony_ci            if width > 0:
3447db96d56Sopenharmony_ci                return istart + self._randbelow(width)
3457db96d56Sopenharmony_ci            raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ci        # Non-unit step argument supplied.
3487db96d56Sopenharmony_ci        if istep > 0:
3497db96d56Sopenharmony_ci            n = (width + istep - 1) // istep
3507db96d56Sopenharmony_ci        elif istep < 0:
3517db96d56Sopenharmony_ci            n = (width + istep + 1) // istep
3527db96d56Sopenharmony_ci        else:
3537db96d56Sopenharmony_ci            raise ValueError("zero step for randrange()")
3547db96d56Sopenharmony_ci        if n <= 0:
3557db96d56Sopenharmony_ci            raise ValueError("empty range for randrange()")
3567db96d56Sopenharmony_ci        return istart + istep * self._randbelow(n)
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci    def randint(self, a, b):
3597db96d56Sopenharmony_ci        """Return random integer in range [a, b], including both end points.
3607db96d56Sopenharmony_ci        """
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci        return self.randrange(a, b+1)
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci    ## -------------------- sequence methods  -------------------
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci    def choice(self, seq):
3687db96d56Sopenharmony_ci        """Choose a random element from a non-empty sequence."""
3697db96d56Sopenharmony_ci
3707db96d56Sopenharmony_ci        # As an accommodation for NumPy, we don't use "if not seq"
3717db96d56Sopenharmony_ci        # because bool(numpy.array()) raises a ValueError.
3727db96d56Sopenharmony_ci        if not len(seq):
3737db96d56Sopenharmony_ci            raise IndexError('Cannot choose from an empty sequence')
3747db96d56Sopenharmony_ci        return seq[self._randbelow(len(seq))]
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ci    def shuffle(self, x):
3777db96d56Sopenharmony_ci        """Shuffle list x in place, and return None."""
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci        randbelow = self._randbelow
3807db96d56Sopenharmony_ci        for i in reversed(range(1, len(x))):
3817db96d56Sopenharmony_ci            # pick an element in x[:i+1] with which to exchange x[i]
3827db96d56Sopenharmony_ci            j = randbelow(i + 1)
3837db96d56Sopenharmony_ci            x[i], x[j] = x[j], x[i]
3847db96d56Sopenharmony_ci
3857db96d56Sopenharmony_ci    def sample(self, population, k, *, counts=None):
3867db96d56Sopenharmony_ci        """Chooses k unique random elements from a population sequence.
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci        Returns a new list containing elements from the population while
3897db96d56Sopenharmony_ci        leaving the original population unchanged.  The resulting list is
3907db96d56Sopenharmony_ci        in selection order so that all sub-slices will also be valid random
3917db96d56Sopenharmony_ci        samples.  This allows raffle winners (the sample) to be partitioned
3927db96d56Sopenharmony_ci        into grand prize and second place winners (the subslices).
3937db96d56Sopenharmony_ci
3947db96d56Sopenharmony_ci        Members of the population need not be hashable or unique.  If the
3957db96d56Sopenharmony_ci        population contains repeats, then each occurrence is a possible
3967db96d56Sopenharmony_ci        selection in the sample.
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci        Repeated elements can be specified one at a time or with the optional
3997db96d56Sopenharmony_ci        counts parameter.  For example:
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ci            sample(['red', 'blue'], counts=[4, 2], k=5)
4027db96d56Sopenharmony_ci
4037db96d56Sopenharmony_ci        is equivalent to:
4047db96d56Sopenharmony_ci
4057db96d56Sopenharmony_ci            sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)
4067db96d56Sopenharmony_ci
4077db96d56Sopenharmony_ci        To choose a sample from a range of integers, use range() for the
4087db96d56Sopenharmony_ci        population argument.  This is especially fast and space efficient
4097db96d56Sopenharmony_ci        for sampling from a large population:
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_ci            sample(range(10000000), 60)
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci        """
4147db96d56Sopenharmony_ci
4157db96d56Sopenharmony_ci        # Sampling without replacement entails tracking either potential
4167db96d56Sopenharmony_ci        # selections (the pool) in a list or previous selections in a set.
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci        # When the number of selections is small compared to the
4197db96d56Sopenharmony_ci        # population, then tracking selections is efficient, requiring
4207db96d56Sopenharmony_ci        # only a small set and an occasional reselection.  For
4217db96d56Sopenharmony_ci        # a larger number of selections, the pool tracking method is
4227db96d56Sopenharmony_ci        # preferred since the list takes less space than the
4237db96d56Sopenharmony_ci        # set and it doesn't suffer from frequent reselections.
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci        # The number of calls to _randbelow() is kept at or near k, the
4267db96d56Sopenharmony_ci        # theoretical minimum.  This is important because running time
4277db96d56Sopenharmony_ci        # is dominated by _randbelow() and because it extracts the
4287db96d56Sopenharmony_ci        # least entropy from the underlying random number generators.
4297db96d56Sopenharmony_ci
4307db96d56Sopenharmony_ci        # Memory requirements are kept to the smaller of a k-length
4317db96d56Sopenharmony_ci        # set or an n-length list.
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ci        # There are other sampling algorithms that do not require
4347db96d56Sopenharmony_ci        # auxiliary memory, but they were rejected because they made
4357db96d56Sopenharmony_ci        # too many calls to _randbelow(), making them slower and
4367db96d56Sopenharmony_ci        # causing them to eat more entropy than necessary.
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ci        if not isinstance(population, _Sequence):
4397db96d56Sopenharmony_ci            raise TypeError("Population must be a sequence.  "
4407db96d56Sopenharmony_ci                            "For dicts or sets, use sorted(d).")
4417db96d56Sopenharmony_ci        n = len(population)
4427db96d56Sopenharmony_ci        if counts is not None:
4437db96d56Sopenharmony_ci            cum_counts = list(_accumulate(counts))
4447db96d56Sopenharmony_ci            if len(cum_counts) != n:
4457db96d56Sopenharmony_ci                raise ValueError('The number of counts does not match the population')
4467db96d56Sopenharmony_ci            total = cum_counts.pop()
4477db96d56Sopenharmony_ci            if not isinstance(total, int):
4487db96d56Sopenharmony_ci                raise TypeError('Counts must be integers')
4497db96d56Sopenharmony_ci            if total <= 0:
4507db96d56Sopenharmony_ci                raise ValueError('Total of counts must be greater than zero')
4517db96d56Sopenharmony_ci            selections = self.sample(range(total), k=k)
4527db96d56Sopenharmony_ci            bisect = _bisect
4537db96d56Sopenharmony_ci            return [population[bisect(cum_counts, s)] for s in selections]
4547db96d56Sopenharmony_ci        randbelow = self._randbelow
4557db96d56Sopenharmony_ci        if not 0 <= k <= n:
4567db96d56Sopenharmony_ci            raise ValueError("Sample larger than population or is negative")
4577db96d56Sopenharmony_ci        result = [None] * k
4587db96d56Sopenharmony_ci        setsize = 21        # size of a small set minus size of an empty list
4597db96d56Sopenharmony_ci        if k > 5:
4607db96d56Sopenharmony_ci            setsize += 4 ** _ceil(_log(k * 3, 4))  # table size for big sets
4617db96d56Sopenharmony_ci        if n <= setsize:
4627db96d56Sopenharmony_ci            # An n-length list is smaller than a k-length set.
4637db96d56Sopenharmony_ci            # Invariant:  non-selected at pool[0 : n-i]
4647db96d56Sopenharmony_ci            pool = list(population)
4657db96d56Sopenharmony_ci            for i in range(k):
4667db96d56Sopenharmony_ci                j = randbelow(n - i)
4677db96d56Sopenharmony_ci                result[i] = pool[j]
4687db96d56Sopenharmony_ci                pool[j] = pool[n - i - 1]  # move non-selected item into vacancy
4697db96d56Sopenharmony_ci        else:
4707db96d56Sopenharmony_ci            selected = set()
4717db96d56Sopenharmony_ci            selected_add = selected.add
4727db96d56Sopenharmony_ci            for i in range(k):
4737db96d56Sopenharmony_ci                j = randbelow(n)
4747db96d56Sopenharmony_ci                while j in selected:
4757db96d56Sopenharmony_ci                    j = randbelow(n)
4767db96d56Sopenharmony_ci                selected_add(j)
4777db96d56Sopenharmony_ci                result[i] = population[j]
4787db96d56Sopenharmony_ci        return result
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci    def choices(self, population, weights=None, *, cum_weights=None, k=1):
4817db96d56Sopenharmony_ci        """Return a k sized list of population elements chosen with replacement.
4827db96d56Sopenharmony_ci
4837db96d56Sopenharmony_ci        If the relative weights or cumulative weights are not specified,
4847db96d56Sopenharmony_ci        the selections are made with equal probability.
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_ci        """
4877db96d56Sopenharmony_ci        random = self.random
4887db96d56Sopenharmony_ci        n = len(population)
4897db96d56Sopenharmony_ci        if cum_weights is None:
4907db96d56Sopenharmony_ci            if weights is None:
4917db96d56Sopenharmony_ci                floor = _floor
4927db96d56Sopenharmony_ci                n += 0.0    # convert to float for a small speed improvement
4937db96d56Sopenharmony_ci                return [population[floor(random() * n)] for i in _repeat(None, k)]
4947db96d56Sopenharmony_ci            try:
4957db96d56Sopenharmony_ci                cum_weights = list(_accumulate(weights))
4967db96d56Sopenharmony_ci            except TypeError:
4977db96d56Sopenharmony_ci                if not isinstance(weights, int):
4987db96d56Sopenharmony_ci                    raise
4997db96d56Sopenharmony_ci                k = weights
5007db96d56Sopenharmony_ci                raise TypeError(
5017db96d56Sopenharmony_ci                    f'The number of choices must be a keyword argument: {k=}'
5027db96d56Sopenharmony_ci                ) from None
5037db96d56Sopenharmony_ci        elif weights is not None:
5047db96d56Sopenharmony_ci            raise TypeError('Cannot specify both weights and cumulative weights')
5057db96d56Sopenharmony_ci        if len(cum_weights) != n:
5067db96d56Sopenharmony_ci            raise ValueError('The number of weights does not match the population')
5077db96d56Sopenharmony_ci        total = cum_weights[-1] + 0.0   # convert to float
5087db96d56Sopenharmony_ci        if total <= 0.0:
5097db96d56Sopenharmony_ci            raise ValueError('Total of weights must be greater than zero')
5107db96d56Sopenharmony_ci        if not _isfinite(total):
5117db96d56Sopenharmony_ci            raise ValueError('Total of weights must be finite')
5127db96d56Sopenharmony_ci        bisect = _bisect
5137db96d56Sopenharmony_ci        hi = n - 1
5147db96d56Sopenharmony_ci        return [population[bisect(cum_weights, random() * total, 0, hi)]
5157db96d56Sopenharmony_ci                for i in _repeat(None, k)]
5167db96d56Sopenharmony_ci
5177db96d56Sopenharmony_ci
5187db96d56Sopenharmony_ci    ## -------------------- real-valued distributions  -------------------
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ci    def uniform(self, a, b):
5217db96d56Sopenharmony_ci        "Get a random number in the range [a, b) or [a, b] depending on rounding."
5227db96d56Sopenharmony_ci        return a + (b - a) * self.random()
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci    def triangular(self, low=0.0, high=1.0, mode=None):
5257db96d56Sopenharmony_ci        """Triangular distribution.
5267db96d56Sopenharmony_ci
5277db96d56Sopenharmony_ci        Continuous distribution bounded by given lower and upper limits,
5287db96d56Sopenharmony_ci        and having a given mode value in-between.
5297db96d56Sopenharmony_ci
5307db96d56Sopenharmony_ci        http://en.wikipedia.org/wiki/Triangular_distribution
5317db96d56Sopenharmony_ci
5327db96d56Sopenharmony_ci        """
5337db96d56Sopenharmony_ci        u = self.random()
5347db96d56Sopenharmony_ci        try:
5357db96d56Sopenharmony_ci            c = 0.5 if mode is None else (mode - low) / (high - low)
5367db96d56Sopenharmony_ci        except ZeroDivisionError:
5377db96d56Sopenharmony_ci            return low
5387db96d56Sopenharmony_ci        if u > c:
5397db96d56Sopenharmony_ci            u = 1.0 - u
5407db96d56Sopenharmony_ci            c = 1.0 - c
5417db96d56Sopenharmony_ci            low, high = high, low
5427db96d56Sopenharmony_ci        return low + (high - low) * _sqrt(u * c)
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_ci    def normalvariate(self, mu=0.0, sigma=1.0):
5457db96d56Sopenharmony_ci        """Normal distribution.
5467db96d56Sopenharmony_ci
5477db96d56Sopenharmony_ci        mu is the mean, and sigma is the standard deviation.
5487db96d56Sopenharmony_ci
5497db96d56Sopenharmony_ci        """
5507db96d56Sopenharmony_ci        # Uses Kinderman and Monahan method. Reference: Kinderman,
5517db96d56Sopenharmony_ci        # A.J. and Monahan, J.F., "Computer generation of random
5527db96d56Sopenharmony_ci        # variables using the ratio of uniform deviates", ACM Trans
5537db96d56Sopenharmony_ci        # Math Software, 3, (1977), pp257-260.
5547db96d56Sopenharmony_ci
5557db96d56Sopenharmony_ci        random = self.random
5567db96d56Sopenharmony_ci        while True:
5577db96d56Sopenharmony_ci            u1 = random()
5587db96d56Sopenharmony_ci            u2 = 1.0 - random()
5597db96d56Sopenharmony_ci            z = NV_MAGICCONST * (u1 - 0.5) / u2
5607db96d56Sopenharmony_ci            zz = z * z / 4.0
5617db96d56Sopenharmony_ci            if zz <= -_log(u2):
5627db96d56Sopenharmony_ci                break
5637db96d56Sopenharmony_ci        return mu + z * sigma
5647db96d56Sopenharmony_ci
5657db96d56Sopenharmony_ci    def gauss(self, mu=0.0, sigma=1.0):
5667db96d56Sopenharmony_ci        """Gaussian distribution.
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci        mu is the mean, and sigma is the standard deviation.  This is
5697db96d56Sopenharmony_ci        slightly faster than the normalvariate() function.
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci        Not thread-safe without a lock around calls.
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_ci        """
5747db96d56Sopenharmony_ci        # When x and y are two variables from [0, 1), uniformly
5757db96d56Sopenharmony_ci        # distributed, then
5767db96d56Sopenharmony_ci        #
5777db96d56Sopenharmony_ci        #    cos(2*pi*x)*sqrt(-2*log(1-y))
5787db96d56Sopenharmony_ci        #    sin(2*pi*x)*sqrt(-2*log(1-y))
5797db96d56Sopenharmony_ci        #
5807db96d56Sopenharmony_ci        # are two *independent* variables with normal distribution
5817db96d56Sopenharmony_ci        # (mu = 0, sigma = 1).
5827db96d56Sopenharmony_ci        # (Lambert Meertens)
5837db96d56Sopenharmony_ci        # (corrected version; bug discovered by Mike Miller, fixed by LM)
5847db96d56Sopenharmony_ci
5857db96d56Sopenharmony_ci        # Multithreading note: When two threads call this function
5867db96d56Sopenharmony_ci        # simultaneously, it is possible that they will receive the
5877db96d56Sopenharmony_ci        # same return value.  The window is very small though.  To
5887db96d56Sopenharmony_ci        # avoid this, you have to use a lock around all calls.  (I
5897db96d56Sopenharmony_ci        # didn't want to slow this down in the serial case by using a
5907db96d56Sopenharmony_ci        # lock here.)
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci        random = self.random
5937db96d56Sopenharmony_ci        z = self.gauss_next
5947db96d56Sopenharmony_ci        self.gauss_next = None
5957db96d56Sopenharmony_ci        if z is None:
5967db96d56Sopenharmony_ci            x2pi = random() * TWOPI
5977db96d56Sopenharmony_ci            g2rad = _sqrt(-2.0 * _log(1.0 - random()))
5987db96d56Sopenharmony_ci            z = _cos(x2pi) * g2rad
5997db96d56Sopenharmony_ci            self.gauss_next = _sin(x2pi) * g2rad
6007db96d56Sopenharmony_ci
6017db96d56Sopenharmony_ci        return mu + z * sigma
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ci    def lognormvariate(self, mu, sigma):
6047db96d56Sopenharmony_ci        """Log normal distribution.
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci        If you take the natural logarithm of this distribution, you'll get a
6077db96d56Sopenharmony_ci        normal distribution with mean mu and standard deviation sigma.
6087db96d56Sopenharmony_ci        mu can have any value, and sigma must be greater than zero.
6097db96d56Sopenharmony_ci
6107db96d56Sopenharmony_ci        """
6117db96d56Sopenharmony_ci        return _exp(self.normalvariate(mu, sigma))
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_ci    def expovariate(self, lambd):
6147db96d56Sopenharmony_ci        """Exponential distribution.
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_ci        lambd is 1.0 divided by the desired mean.  It should be
6177db96d56Sopenharmony_ci        nonzero.  (The parameter would be called "lambda", but that is
6187db96d56Sopenharmony_ci        a reserved word in Python.)  Returned values range from 0 to
6197db96d56Sopenharmony_ci        positive infinity if lambd is positive, and from negative
6207db96d56Sopenharmony_ci        infinity to 0 if lambd is negative.
6217db96d56Sopenharmony_ci
6227db96d56Sopenharmony_ci        """
6237db96d56Sopenharmony_ci        # lambd: rate lambd = 1/mean
6247db96d56Sopenharmony_ci        # ('lambda' is a Python reserved word)
6257db96d56Sopenharmony_ci
6267db96d56Sopenharmony_ci        # we use 1-random() instead of random() to preclude the
6277db96d56Sopenharmony_ci        # possibility of taking the log of zero.
6287db96d56Sopenharmony_ci        return -_log(1.0 - self.random()) / lambd
6297db96d56Sopenharmony_ci
6307db96d56Sopenharmony_ci    def vonmisesvariate(self, mu, kappa):
6317db96d56Sopenharmony_ci        """Circular data distribution.
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_ci        mu is the mean angle, expressed in radians between 0 and 2*pi, and
6347db96d56Sopenharmony_ci        kappa is the concentration parameter, which must be greater than or
6357db96d56Sopenharmony_ci        equal to zero.  If kappa is equal to zero, this distribution reduces
6367db96d56Sopenharmony_ci        to a uniform random angle over the range 0 to 2*pi.
6377db96d56Sopenharmony_ci
6387db96d56Sopenharmony_ci        """
6397db96d56Sopenharmony_ci        # Based upon an algorithm published in: Fisher, N.I.,
6407db96d56Sopenharmony_ci        # "Statistical Analysis of Circular Data", Cambridge
6417db96d56Sopenharmony_ci        # University Press, 1993.
6427db96d56Sopenharmony_ci
6437db96d56Sopenharmony_ci        # Thanks to Magnus Kessler for a correction to the
6447db96d56Sopenharmony_ci        # implementation of step 4.
6457db96d56Sopenharmony_ci
6467db96d56Sopenharmony_ci        random = self.random
6477db96d56Sopenharmony_ci        if kappa <= 1e-6:
6487db96d56Sopenharmony_ci            return TWOPI * random()
6497db96d56Sopenharmony_ci
6507db96d56Sopenharmony_ci        s = 0.5 / kappa
6517db96d56Sopenharmony_ci        r = s + _sqrt(1.0 + s * s)
6527db96d56Sopenharmony_ci
6537db96d56Sopenharmony_ci        while True:
6547db96d56Sopenharmony_ci            u1 = random()
6557db96d56Sopenharmony_ci            z = _cos(_pi * u1)
6567db96d56Sopenharmony_ci
6577db96d56Sopenharmony_ci            d = z / (r + z)
6587db96d56Sopenharmony_ci            u2 = random()
6597db96d56Sopenharmony_ci            if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
6607db96d56Sopenharmony_ci                break
6617db96d56Sopenharmony_ci
6627db96d56Sopenharmony_ci        q = 1.0 / r
6637db96d56Sopenharmony_ci        f = (q + z) / (1.0 + q * z)
6647db96d56Sopenharmony_ci        u3 = random()
6657db96d56Sopenharmony_ci        if u3 > 0.5:
6667db96d56Sopenharmony_ci            theta = (mu + _acos(f)) % TWOPI
6677db96d56Sopenharmony_ci        else:
6687db96d56Sopenharmony_ci            theta = (mu - _acos(f)) % TWOPI
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_ci        return theta
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ci    def gammavariate(self, alpha, beta):
6737db96d56Sopenharmony_ci        """Gamma distribution.  Not the gamma function!
6747db96d56Sopenharmony_ci
6757db96d56Sopenharmony_ci        Conditions on the parameters are alpha > 0 and beta > 0.
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci        The probability distribution function is:
6787db96d56Sopenharmony_ci
6797db96d56Sopenharmony_ci                    x ** (alpha - 1) * math.exp(-x / beta)
6807db96d56Sopenharmony_ci          pdf(x) =  --------------------------------------
6817db96d56Sopenharmony_ci                      math.gamma(alpha) * beta ** alpha
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_ci        """
6847db96d56Sopenharmony_ci        # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
6857db96d56Sopenharmony_ci
6867db96d56Sopenharmony_ci        # Warning: a few older sources define the gamma distribution in terms
6877db96d56Sopenharmony_ci        # of alpha > -1.0
6887db96d56Sopenharmony_ci        if alpha <= 0.0 or beta <= 0.0:
6897db96d56Sopenharmony_ci            raise ValueError('gammavariate: alpha and beta must be > 0.0')
6907db96d56Sopenharmony_ci
6917db96d56Sopenharmony_ci        random = self.random
6927db96d56Sopenharmony_ci        if alpha > 1.0:
6937db96d56Sopenharmony_ci
6947db96d56Sopenharmony_ci            # Uses R.C.H. Cheng, "The generation of Gamma
6957db96d56Sopenharmony_ci            # variables with non-integral shape parameters",
6967db96d56Sopenharmony_ci            # Applied Statistics, (1977), 26, No. 1, p71-74
6977db96d56Sopenharmony_ci
6987db96d56Sopenharmony_ci            ainv = _sqrt(2.0 * alpha - 1.0)
6997db96d56Sopenharmony_ci            bbb = alpha - LOG4
7007db96d56Sopenharmony_ci            ccc = alpha + ainv
7017db96d56Sopenharmony_ci
7027db96d56Sopenharmony_ci            while True:
7037db96d56Sopenharmony_ci                u1 = random()
7047db96d56Sopenharmony_ci                if not 1e-7 < u1 < 0.9999999:
7057db96d56Sopenharmony_ci                    continue
7067db96d56Sopenharmony_ci                u2 = 1.0 - random()
7077db96d56Sopenharmony_ci                v = _log(u1 / (1.0 - u1)) / ainv
7087db96d56Sopenharmony_ci                x = alpha * _exp(v)
7097db96d56Sopenharmony_ci                z = u1 * u1 * u2
7107db96d56Sopenharmony_ci                r = bbb + ccc * v - x
7117db96d56Sopenharmony_ci                if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z):
7127db96d56Sopenharmony_ci                    return x * beta
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_ci        elif alpha == 1.0:
7157db96d56Sopenharmony_ci            # expovariate(1/beta)
7167db96d56Sopenharmony_ci            return -_log(1.0 - random()) * beta
7177db96d56Sopenharmony_ci
7187db96d56Sopenharmony_ci        else:
7197db96d56Sopenharmony_ci            # alpha is between 0 and 1 (exclusive)
7207db96d56Sopenharmony_ci            # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
7217db96d56Sopenharmony_ci            while True:
7227db96d56Sopenharmony_ci                u = random()
7237db96d56Sopenharmony_ci                b = (_e + alpha) / _e
7247db96d56Sopenharmony_ci                p = b * u
7257db96d56Sopenharmony_ci                if p <= 1.0:
7267db96d56Sopenharmony_ci                    x = p ** (1.0 / alpha)
7277db96d56Sopenharmony_ci                else:
7287db96d56Sopenharmony_ci                    x = -_log((b - p) / alpha)
7297db96d56Sopenharmony_ci                u1 = random()
7307db96d56Sopenharmony_ci                if p > 1.0:
7317db96d56Sopenharmony_ci                    if u1 <= x ** (alpha - 1.0):
7327db96d56Sopenharmony_ci                        break
7337db96d56Sopenharmony_ci                elif u1 <= _exp(-x):
7347db96d56Sopenharmony_ci                    break
7357db96d56Sopenharmony_ci            return x * beta
7367db96d56Sopenharmony_ci
7377db96d56Sopenharmony_ci    def betavariate(self, alpha, beta):
7387db96d56Sopenharmony_ci        """Beta distribution.
7397db96d56Sopenharmony_ci
7407db96d56Sopenharmony_ci        Conditions on the parameters are alpha > 0 and beta > 0.
7417db96d56Sopenharmony_ci        Returned values range between 0 and 1.
7427db96d56Sopenharmony_ci
7437db96d56Sopenharmony_ci        """
7447db96d56Sopenharmony_ci        ## See
7457db96d56Sopenharmony_ci        ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
7467db96d56Sopenharmony_ci        ## for Ivan Frohne's insightful analysis of why the original implementation:
7477db96d56Sopenharmony_ci        ##
7487db96d56Sopenharmony_ci        ##    def betavariate(self, alpha, beta):
7497db96d56Sopenharmony_ci        ##        # Discrete Event Simulation in C, pp 87-88.
7507db96d56Sopenharmony_ci        ##
7517db96d56Sopenharmony_ci        ##        y = self.expovariate(alpha)
7527db96d56Sopenharmony_ci        ##        z = self.expovariate(1.0/beta)
7537db96d56Sopenharmony_ci        ##        return z/(y+z)
7547db96d56Sopenharmony_ci        ##
7557db96d56Sopenharmony_ci        ## was dead wrong, and how it probably got that way.
7567db96d56Sopenharmony_ci
7577db96d56Sopenharmony_ci        # This version due to Janne Sinkkonen, and matches all the std
7587db96d56Sopenharmony_ci        # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
7597db96d56Sopenharmony_ci        y = self.gammavariate(alpha, 1.0)
7607db96d56Sopenharmony_ci        if y:
7617db96d56Sopenharmony_ci            return y / (y + self.gammavariate(beta, 1.0))
7627db96d56Sopenharmony_ci        return 0.0
7637db96d56Sopenharmony_ci
7647db96d56Sopenharmony_ci    def paretovariate(self, alpha):
7657db96d56Sopenharmony_ci        """Pareto distribution.  alpha is the shape parameter."""
7667db96d56Sopenharmony_ci        # Jain, pg. 495
7677db96d56Sopenharmony_ci
7687db96d56Sopenharmony_ci        u = 1.0 - self.random()
7697db96d56Sopenharmony_ci        return u ** (-1.0 / alpha)
7707db96d56Sopenharmony_ci
7717db96d56Sopenharmony_ci    def weibullvariate(self, alpha, beta):
7727db96d56Sopenharmony_ci        """Weibull distribution.
7737db96d56Sopenharmony_ci
7747db96d56Sopenharmony_ci        alpha is the scale parameter and beta is the shape parameter.
7757db96d56Sopenharmony_ci
7767db96d56Sopenharmony_ci        """
7777db96d56Sopenharmony_ci        # Jain, pg. 499; bug fix courtesy Bill Arms
7787db96d56Sopenharmony_ci
7797db96d56Sopenharmony_ci        u = 1.0 - self.random()
7807db96d56Sopenharmony_ci        return alpha * (-_log(u)) ** (1.0 / beta)
7817db96d56Sopenharmony_ci
7827db96d56Sopenharmony_ci
7837db96d56Sopenharmony_ci## ------------------------------------------------------------------
7847db96d56Sopenharmony_ci## --------------- Operating System Random Source  ------------------
7857db96d56Sopenharmony_ci
7867db96d56Sopenharmony_ci
7877db96d56Sopenharmony_ciclass SystemRandom(Random):
7887db96d56Sopenharmony_ci    """Alternate random number generator using sources provided
7897db96d56Sopenharmony_ci    by the operating system (such as /dev/urandom on Unix or
7907db96d56Sopenharmony_ci    CryptGenRandom on Windows).
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci     Not available on all systems (see os.urandom() for details).
7937db96d56Sopenharmony_ci
7947db96d56Sopenharmony_ci    """
7957db96d56Sopenharmony_ci
7967db96d56Sopenharmony_ci    def random(self):
7977db96d56Sopenharmony_ci        """Get the next random number in the range 0.0 <= X < 1.0."""
7987db96d56Sopenharmony_ci        return (int.from_bytes(_urandom(7)) >> 3) * RECIP_BPF
7997db96d56Sopenharmony_ci
8007db96d56Sopenharmony_ci    def getrandbits(self, k):
8017db96d56Sopenharmony_ci        """getrandbits(k) -> x.  Generates an int with k random bits."""
8027db96d56Sopenharmony_ci        if k < 0:
8037db96d56Sopenharmony_ci            raise ValueError('number of bits must be non-negative')
8047db96d56Sopenharmony_ci        numbytes = (k + 7) // 8                       # bits / 8 and rounded up
8057db96d56Sopenharmony_ci        x = int.from_bytes(_urandom(numbytes))
8067db96d56Sopenharmony_ci        return x >> (numbytes * 8 - k)                # trim excess bits
8077db96d56Sopenharmony_ci
8087db96d56Sopenharmony_ci    def randbytes(self, n):
8097db96d56Sopenharmony_ci        """Generate n random bytes."""
8107db96d56Sopenharmony_ci        # os.urandom(n) fails with ValueError for n < 0
8117db96d56Sopenharmony_ci        # and returns an empty bytes string for n == 0.
8127db96d56Sopenharmony_ci        return _urandom(n)
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci    def seed(self, *args, **kwds):
8157db96d56Sopenharmony_ci        "Stub method.  Not used for a system random number generator."
8167db96d56Sopenharmony_ci        return None
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ci    def _notimplemented(self, *args, **kwds):
8197db96d56Sopenharmony_ci        "Method should not be called for a system random number generator."
8207db96d56Sopenharmony_ci        raise NotImplementedError('System entropy source does not have state.')
8217db96d56Sopenharmony_ci    getstate = setstate = _notimplemented
8227db96d56Sopenharmony_ci
8237db96d56Sopenharmony_ci
8247db96d56Sopenharmony_ci# ----------------------------------------------------------------------
8257db96d56Sopenharmony_ci# Create one instance, seeded from current time, and export its methods
8267db96d56Sopenharmony_ci# as module-level functions.  The functions share state across all uses
8277db96d56Sopenharmony_ci# (both in the user's code and in the Python libraries), but that's fine
8287db96d56Sopenharmony_ci# for most programs and is easier for the casual user than making them
8297db96d56Sopenharmony_ci# instantiate their own Random() instance.
8307db96d56Sopenharmony_ci
8317db96d56Sopenharmony_ci_inst = Random()
8327db96d56Sopenharmony_ciseed = _inst.seed
8337db96d56Sopenharmony_cirandom = _inst.random
8347db96d56Sopenharmony_ciuniform = _inst.uniform
8357db96d56Sopenharmony_citriangular = _inst.triangular
8367db96d56Sopenharmony_cirandint = _inst.randint
8377db96d56Sopenharmony_cichoice = _inst.choice
8387db96d56Sopenharmony_cirandrange = _inst.randrange
8397db96d56Sopenharmony_cisample = _inst.sample
8407db96d56Sopenharmony_cishuffle = _inst.shuffle
8417db96d56Sopenharmony_cichoices = _inst.choices
8427db96d56Sopenharmony_cinormalvariate = _inst.normalvariate
8437db96d56Sopenharmony_cilognormvariate = _inst.lognormvariate
8447db96d56Sopenharmony_ciexpovariate = _inst.expovariate
8457db96d56Sopenharmony_civonmisesvariate = _inst.vonmisesvariate
8467db96d56Sopenharmony_cigammavariate = _inst.gammavariate
8477db96d56Sopenharmony_cigauss = _inst.gauss
8487db96d56Sopenharmony_cibetavariate = _inst.betavariate
8497db96d56Sopenharmony_ciparetovariate = _inst.paretovariate
8507db96d56Sopenharmony_ciweibullvariate = _inst.weibullvariate
8517db96d56Sopenharmony_cigetstate = _inst.getstate
8527db96d56Sopenharmony_cisetstate = _inst.setstate
8537db96d56Sopenharmony_cigetrandbits = _inst.getrandbits
8547db96d56Sopenharmony_cirandbytes = _inst.randbytes
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_ci
8577db96d56Sopenharmony_ci## ------------------------------------------------------
8587db96d56Sopenharmony_ci## ----------------- test program -----------------------
8597db96d56Sopenharmony_ci
8607db96d56Sopenharmony_cidef _test_generator(n, func, args):
8617db96d56Sopenharmony_ci    from statistics import stdev, fmean as mean
8627db96d56Sopenharmony_ci    from time import perf_counter
8637db96d56Sopenharmony_ci
8647db96d56Sopenharmony_ci    t0 = perf_counter()
8657db96d56Sopenharmony_ci    data = [func(*args) for i in _repeat(None, n)]
8667db96d56Sopenharmony_ci    t1 = perf_counter()
8677db96d56Sopenharmony_ci
8687db96d56Sopenharmony_ci    xbar = mean(data)
8697db96d56Sopenharmony_ci    sigma = stdev(data, xbar)
8707db96d56Sopenharmony_ci    low = min(data)
8717db96d56Sopenharmony_ci    high = max(data)
8727db96d56Sopenharmony_ci
8737db96d56Sopenharmony_ci    print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}')
8747db96d56Sopenharmony_ci    print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high))
8757db96d56Sopenharmony_ci
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_cidef _test(N=2000):
8787db96d56Sopenharmony_ci    _test_generator(N, random, ())
8797db96d56Sopenharmony_ci    _test_generator(N, normalvariate, (0.0, 1.0))
8807db96d56Sopenharmony_ci    _test_generator(N, lognormvariate, (0.0, 1.0))
8817db96d56Sopenharmony_ci    _test_generator(N, vonmisesvariate, (0.0, 1.0))
8827db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (0.01, 1.0))
8837db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (0.1, 1.0))
8847db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (0.1, 2.0))
8857db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (0.5, 1.0))
8867db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (0.9, 1.0))
8877db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (1.0, 1.0))
8887db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (2.0, 1.0))
8897db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (20.0, 1.0))
8907db96d56Sopenharmony_ci    _test_generator(N, gammavariate, (200.0, 1.0))
8917db96d56Sopenharmony_ci    _test_generator(N, gauss, (0.0, 1.0))
8927db96d56Sopenharmony_ci    _test_generator(N, betavariate, (3.0, 3.0))
8937db96d56Sopenharmony_ci    _test_generator(N, triangular, (0.0, 1.0, 1.0 / 3.0))
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci
8967db96d56Sopenharmony_ci## ------------------------------------------------------
8977db96d56Sopenharmony_ci## ------------------ fork support  ---------------------
8987db96d56Sopenharmony_ci
8997db96d56Sopenharmony_ciif hasattr(_os, "fork"):
9007db96d56Sopenharmony_ci    _os.register_at_fork(after_in_child=_inst.seed)
9017db96d56Sopenharmony_ci
9027db96d56Sopenharmony_ci
9037db96d56Sopenharmony_ciif __name__ == '__main__':
9047db96d56Sopenharmony_ci    _test()
905