:mod:`!random` --- Generate pseudo-random numbers
=================================================

.. module:: random
   :synopsis: Generate pseudo-random numbers with various common distributions.

**Source code:** :source:`Lib/random.py`

--------------

This module implements pseudo-random number generators for various
distributions.

For integers, there is uniform selection from a range. For sequences, there is
uniform selection of a random element, a function to generate a random
permutation of a list in-place, and a function for random sampling without
replacement.

On the real line, there are functions to compute uniform, normal (Gaussian),
lognormal, negative exponential, gamma, and beta distributions. For generating
distributions of angles, the von Mises distribution is available.

Almost all module functions depend on the basic function :func:`.random`, which
generates a random float uniformly in the half-open range ``0.0 <= X < 1.0``.
Python uses the Mersenne Twister as the core generator.  It produces 53-bit precision
floats and has a period of 2\*\*19937-1.  The underlying implementation in C is
both fast and threadsafe.  The Mersenne Twister is one of the most extensively
tested random number generators in existence.  However, being completely
deterministic, it is not suitable for all purposes, and is completely unsuitable
for cryptographic purposes.

The functions supplied by this module are actually bound methods of a hidden
instance of the :class:`random.Random` class.  You can instantiate your own
instances of :class:`Random` to get generators that don't share state.

Class :class:`Random` can also be subclassed if you want to use a different
basic generator of your own devising: see the documentation on that class for
more details.

The :mod:`!random` module also provides the :class:`SystemRandom` class which
uses the system function :func:`os.urandom` to generate random numbers
from sources provided by the operating system.

.. warning::

   The pseudo-random generators of this module should not be used for
   security purposes.  For security or cryptographic uses, see the
   :mod:`secrets` module.

.. seealso::

   M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-dimensionally
   equidistributed uniform pseudorandom number generator", ACM Transactions on
   Modeling and Computer Simulation Vol. 8, No. 1, January pp.3--30 1998.


   `Complementary-Multiply-with-Carry recipe
   <https://code.activestate.com/recipes/576707-long-period-random-number-generator/>`_ for a compatible alternative
   random number generator with a long period and comparatively simple update
   operations.

.. note::
   The global random number generator and instances of :class:`Random` are thread-safe.
   However, in the free-threaded build, concurrent calls to the global generator or
   to the same instance of :class:`Random` may encounter contention and poor performance.
   Consider using separate instances of :class:`Random` per thread instead.


Bookkeeping functions
---------------------

.. function:: seed(a=None, version=2)

   Initialize the random number generator.

   If *a* is omitted or ``None``, the current system time is used.  If
   randomness sources are provided by the operating system, they are used
   instead of the system time (see the :func:`os.urandom` function for details
   on availability).

   If *a* is an int, its absolute value is used directly.

   With version 2 (the default), a :class:`str`, :class:`bytes`, or :class:`bytearray`
   object gets converted to an :class:`int` and all of its bits are used.

   With version 1 (provided for reproducing random sequences from older versions
   of Python), the algorithm for :class:`str` and :class:`bytes` generates a
   narrower range of seeds.

   .. versionchanged:: 3.2
      Moved to the version 2 scheme which uses all of the bits in a string seed.

   .. versionchanged:: 3.11
      The *seed* must be one of the following types:
      ``None``, :class:`int`, :class:`float`, :class:`str`,
      :class:`bytes`, or :class:`bytearray`.

.. function:: getstate()

   Return an object capturing the current internal state of the generator.  This
   object can be passed to :func:`setstate` to restore the state.


.. function:: setstate(state)

   *state* should have been obtained from a previous call to :func:`getstate`, and
   :func:`setstate` restores the internal state of the generator to what it was at
   the time :func:`getstate` was called.


Functions for bytes
-------------------

.. function:: randbytes(n)

   Generate *n* random bytes.

   This method should not be used for generating security tokens.
   Use :func:`secrets.token_bytes` instead.

   .. versionadded:: 3.9


Functions for integers
----------------------

.. function:: randrange(stop)
              randrange(start, stop[, step])

   Return a randomly selected element from ``range(start, stop, step)``.

   This is roughly equivalent to ``choice(range(start, stop, step))`` but
   supports arbitrarily large ranges and is optimized for common cases.

   The positional argument pattern matches the :func:`range` function.

   Keyword arguments should not be used because they can be interpreted
   in unexpected ways. For example ``randrange(start=100)`` is interpreted
   as ``randrange(0, 100, 1)``.

   .. versionchanged:: 3.2
      :meth:`randrange` is more sophisticated about producing equally distributed
      values.  Formerly it used a style like ``int(random()*n)`` which could produce
      slightly uneven distributions.

   .. versionchanged:: 3.12
      Automatic conversion of non-integer types is no longer supported.
      Calls such as ``randrange(10.0)`` and ``randrange(Fraction(10, 1))``
      now raise a :exc:`TypeError`.

.. function:: randint(a, b)

   Return a random integer *N* such that ``a <= N <= b``.  Alias for
   ``randrange(a, b+1)``.

.. function:: getrandbits(k)

   Returns a non-negative Python integer with *k* random bits. This method
   is supplied with the Mersenne Twister generator and some other generators
   may also provide it as an optional part of the API. When available,
   :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large
   ranges.

   .. versionchanged:: 3.9
      This method now accepts zero for *k*.


Functions for sequences
-----------------------

.. function:: choice(seq)

   Return a random element from the non-empty sequence *seq*. If *seq* is empty,
   raises :exc:`IndexError`.

.. function:: choices(population, weights=None, *, cum_weights=None, k=1)

   Return a *k* sized list of elements chosen from the *population* with replacement.
   If the *population* is empty, raises :exc:`IndexError`.

   If a *weights* sequence is specified, selections are made according to the
   relative weights.  Alternatively, if a *cum_weights* sequence is given, the
   selections are made according to the cumulative weights (perhaps computed
   using :func:`itertools.accumulate`).  For example, the relative weights
   ``[10, 5, 30, 5]`` are equivalent to the cumulative weights
   ``[10, 15, 45, 50]``.  Internally, the relative weights are converted to
   cumulative weights before making selections, so supplying the cumulative
   weights saves work.

   If neither *weights* nor *cum_weights* are specified, selections are made
   with equal probability.  If a weights sequence is supplied, it must be
   the same length as the *population* sequence.  It is a :exc:`TypeError`
   to specify both *weights* and *cum_weights*.

   The *weights* or *cum_weights* can use any numeric type that interoperates
   with the :class:`float` values returned by :func:`random` (that includes
   integers, floats, and fractions but excludes decimals).  Weights are assumed
   to be non-negative and finite.  A :exc:`ValueError` is raised if all
   weights are zero.

   For a given seed, the :func:`choices` function with equal weighting
   typically produces a different sequence than repeated calls to
   :func:`choice`.  The algorithm used by :func:`choices` uses floating-point
   arithmetic for internal consistency and speed.  The algorithm used
   by :func:`choice` defaults to integer arithmetic with repeated selections
   to avoid small biases from round-off error.

   .. versionadded:: 3.6

   .. versionchanged:: 3.9
      Raises a :exc:`ValueError` if all weights are zero.


.. function:: shuffle(x)

   Shuffle the sequence *x* in place.

   To shuffle an immutable sequence and return a new shuffled list, use
   ``sample(x, k=len(x))`` instead.

   Note that even for small ``len(x)``, the total number of permutations of *x*
   can quickly grow larger than the period of most random number generators.
   This implies that most permutations of a long sequence can never be
   generated.  For example, a sequence of length 2080 is the largest that
   can fit within the period of the Mersenne Twister random number generator.

   .. versionchanged:: 3.11
      Removed the optional parameter *random*.


.. function:: sample(population, k, *, counts=None)

   Return a *k* length list of unique elements chosen from the population
   sequence.  Used for random sampling without replacement.

   Returns a new list containing elements from the population while leaving the
   original population unchanged.  The resulting list is in selection order so that
   all sub-slices will also be valid random samples.  This allows raffle winners
   (the sample) to be partitioned into grand prize and second place winners (the
   subslices).

   Members of the population need not be :term:`hashable` or unique.  If the population
   contains repeats, then each occurrence is a possible selection in the sample.

   Repeated elements can be specified one at a time or with the optional
   keyword-only *counts* parameter.  For example, ``sample(['red', 'blue'],
   counts=[4, 2], k=5)`` is equivalent to ``sample(['red', 'red', 'red', 'red',
   'blue', 'blue'], k=5)``.

   To choose a sample from a range of integers, use a :func:`range` object as an
   argument.  This is especially fast and space efficient for sampling from a large
   population:  ``sample(range(10000000), k=60)``.

   If the sample size is larger than the population size, a :exc:`ValueError`
   is raised.

   .. versionchanged:: 3.9
      Added the *counts* parameter.

   .. versionchanged:: 3.11

      The *population* must be a sequence.  Automatic conversion of sets
      to lists is no longer supported.

Discrete distributions
----------------------

The following function generates a discrete distribution.

.. function:: binomialvariate(n=1, p=0.5)

   `Binomial distribution
   <https://mathworld.wolfram.com/BinomialDistribution.html>`_.
   Return the number of successes for *n* independent trials with the
   probability of success in each trial being *p*:

   Mathematically equivalent to::

       sum(random() < p for i in range(n))

   The number of trials *n* should be a non-negative integer.
   The probability of success *p* should be between ``0.0 <= p <= 1.0``.
   The result is an integer in the range ``0 <= X <= n``.

   .. versionadded:: 3.12


.. _real-valued-distributions:

Real-valued distributions
-------------------------

The following functions generate specific real-valued distributions. Function
parameters are named after the corresponding variables in the distribution's
equation, as used in common mathematical practice; most of these equations can
be found in any statistics text.


.. function:: random()

   Return the next random floating-point number in the range ``0.0 <= X < 1.0``


.. function:: uniform(a, b)

   Return a random floating-point number *N* such that ``a <= N <= b`` for
   ``a <= b`` and ``b <= N <= a`` for ``b < a``.

   The end-point value ``b`` may or may not be included in the range
   depending on floating-point rounding in the expression
   ``a + (b-a) * random()``.


.. function:: triangular(low, high, mode)

   Return a random floating-point number *N* such that ``low <= N <= high`` and
   with the specified *mode* between those bounds.  The *low* and *high* bounds
   default to zero and one.  The *mode* argument defaults to the midpoint
   between the bounds, giving a symmetric distribution.


.. function:: betavariate(alpha, beta)

   Beta distribution.  Conditions on the parameters are ``alpha > 0`` and
   ``beta > 0``. Returned values range between 0 and 1.


.. function:: expovariate(lambd = 1.0)

   Exponential distribution.  *lambd* is 1.0 divided by the desired
   mean.  It should be nonzero.  (The parameter would be called
   "lambda", but that is a reserved word in Python.)  Returned values
   range from 0 to positive infinity if *lambd* is positive, and from
   negative infinity to 0 if *lambd* is negative.

   .. versionchanged:: 3.12
      Added the default value for ``lambd``.


.. function:: gammavariate(alpha, beta)

   Gamma distribution.  (*Not* the gamma function!)  The shape and
   scale parameters, *alpha* and *beta*, must have positive values.
   (Calling conventions vary and some sources define 'beta'
   as the inverse of the scale).

   The probability distribution function is::

                 x ** (alpha - 1) * math.exp(-x / beta)
       pdf(x) =  --------------------------------------
                   math.gamma(alpha) * beta ** alpha


.. function:: gauss(mu=0.0, sigma=1.0)

   Normal distribution, also called the Gaussian distribution.
   *mu* is the mean,
   and *sigma* is the standard deviation.  This is slightly faster than
   the :func:`normalvariate` function defined below.

   Multithreading note:  When two threads call this function
   simultaneously, it is possible that they will receive the
   same return value.  This can be avoided in three ways.
   1) Have each thread use a different instance of the random
   number generator. 2) Put locks around all calls. 3) Use the
   slower, but thread-safe :func:`normalvariate` function instead.

   .. versionchanged:: 3.11
      *mu* and *sigma* now have default arguments.


.. function:: lognormvariate(mu, sigma)

   Log normal distribution.  If you take the natural logarithm of this
   distribution, you'll get a normal distribution with mean *mu* and standard
   deviation *sigma*.  *mu* can have any value, and *sigma* must be greater than
   zero.


.. function:: normalvariate(mu=0.0, sigma=1.0)

   Normal distribution.  *mu* is the mean, and *sigma* is the standard deviation.

   .. versionchanged:: 3.11
      *mu* and *sigma* now have default arguments.


.. function:: vonmisesvariate(mu, kappa)

   *mu* is the mean angle, expressed in radians between 0 and 2\*\ *pi*, and *kappa*
   is the concentration parameter, which must be greater than or equal to zero.  If
   *kappa* is equal to zero, this distribution reduces to a uniform random angle
   over the range 0 to 2\*\ *pi*.


.. function:: paretovariate(alpha)

   Pareto distribution.  *alpha* is the shape parameter.


.. function:: weibullvariate(alpha, beta)

   Weibull distribution.  *alpha* is the scale parameter and *beta* is the shape
   parameter.


Alternative Generator
---------------------

.. class:: Random([seed])

   Class that implements the default pseudo-random number generator used by the
   :mod:`!random` module.

   .. versionchanged:: 3.11
      Formerly the *seed* could be any hashable object.  Now it is limited to:
      ``None``, :class:`int`, :class:`float`, :class:`str`,
      :class:`bytes`, or :class:`bytearray`.

   Subclasses of :class:`!Random` should override the following methods if they
   wish to make use of a different basic generator:

   .. method:: Random.seed(a=None, version=2)

      Override this method in subclasses to customise the :meth:`~random.seed`
      behaviour of :class:`!Random` instances.

   .. method:: Random.getstate()

      Override this method in subclasses to customise the :meth:`~random.getstate`
      behaviour of :class:`!Random` instances.

   .. method:: Random.setstate(state)

      Override this method in subclasses to customise the :meth:`~random.setstate`
      behaviour of :class:`!Random` instances.

   .. method:: Random.random()

      Override this method in subclasses to customise the :meth:`~random.random`
      behaviour of :class:`!Random` instances.

   Optionally, a custom generator subclass can also supply the following method:

   .. method:: Random.getrandbits(k)

      Override this method in subclasses to customise the
      :meth:`~random.getrandbits` behaviour of :class:`!Random` instances.

   .. method:: Random.randbytes(n)

      Override this method in subclasses to customise the
      :meth:`~random.randbytes` behaviour of :class:`!Random` instances.


.. class:: SystemRandom([seed])

   Class that uses the :func:`os.urandom` function for generating random numbers
   from sources provided by the operating system. Not available on all systems.
   Does not rely on software state, and sequences are not reproducible. Accordingly,
   the :meth:`seed` method has no effect and is ignored.
   The :meth:`getstate` and :meth:`setstate` methods raise
   :exc:`NotImplementedError` if called.


Notes on Reproducibility
------------------------

Sometimes it is useful to be able to reproduce the sequences given by a
pseudo-random number generator.  By reusing a seed value, the same sequence should be
reproducible from run to run as long as multiple threads are not running.

Most of the random module's algorithms and seeding functions are subject to
change across Python versions, but two aspects are guaranteed not to change:

* If a new seeding method is added, then a backward compatible seeder will be
  offered.

* The generator's :meth:`~Random.random` method will continue to produce the same
  sequence when the compatible seeder is given the same seed.

.. _random-examples:

Examples
--------

Basic examples::

   >>> random()                          # Random float:  0.0 <= x < 1.0
   0.37444887175646646

   >>> uniform(2.5, 10.0)                # Random float:  2.5 <= x <= 10.0
   3.1800146073117523

   >>> expovariate(1 / 5)                # Interval between arrivals averaging 5 seconds
   5.148957571865031

   >>> randrange(10)                     # Integer from 0 to 9 inclusive
   7

   >>> randrange(0, 101, 2)              # Even integer from 0 to 100 inclusive
   26

   >>> choice(['win', 'lose', 'draw'])   # Single random element from a sequence
   'draw'

   >>> deck = 'ace two three four'.split()
   >>> shuffle(deck)                     # Shuffle a list
   >>> deck
   ['four', 'two', 'ace', 'three']

   >>> sample([10, 20, 30, 40, 50], k=4) # Four samples without replacement
   [40, 10, 50, 30]

Simulations::

   >>> # Six roulette wheel spins (weighted sampling with replacement)
   >>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
   ['red', 'green', 'black', 'black', 'red', 'black']

   >>> # Deal 20 cards without replacement from a deck
   >>> # of 52 playing cards, and determine the proportion of cards
   >>> # with a ten-value:  ten, jack, queen, or king.
   >>> deal = sample(['tens', 'low cards'], counts=[16, 36], k=20)
   >>> deal.count('tens') / 20
   0.15

   >>> # Estimate the probability of getting 5 or more heads from 7 spins
   >>> # of a biased coin that settles on heads 60% of the time.
   >>> sum(binomialvariate(n=7, p=0.6) >= 5 for i in range(10_000)) / 10_000
   0.4169

   >>> # Probability of the median of 5 samples being in middle two quartiles
   >>> def trial():
   ...     return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500
   ...
   >>> sum(trial() for i in range(10_000)) / 10_000
   0.7958

Example of `statistical bootstrapping
<https://en.wikipedia.org/wiki/Bootstrapping_(statistics)>`_ using resampling
with replacement to estimate a confidence interval for the mean of a sample::

   # https://www.thoughtco.com/example-of-bootstrapping-3126155
   from statistics import fmean as mean
   from random import choices

   data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95]
   means = sorted(mean(choices(data, k=len(data))) for i in range(100))
   print(f'The sample mean of {mean(data):.1f} has a 90% confidence '
         f'interval from {means[5]:.1f} to {means[94]:.1f}')

Example of a `resampling permutation test
<https://en.wikipedia.org/wiki/Resampling_(statistics)#Permutation_tests>`_
to determine the statistical significance or `p-value
<https://en.wikipedia.org/wiki/P-value>`_ of an observed difference
between the effects of a drug versus a placebo::

    # Example from "Statistics is Easy" by Dennis Shasha and Manda Wilson
    from statistics import fmean as mean
    from random import shuffle

    drug = [54, 73, 53, 70, 73, 68, 52, 65, 65]
    placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46]
    observed_diff = mean(drug) - mean(placebo)

    n = 10_000
    count = 0
    combined = drug + placebo
    for i in range(n):
        shuffle(combined)
        new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):])
        count += (new_diff >= observed_diff)

    print(f'{n} label reshufflings produced only {count} instances with a difference')
    print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')
    print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')
    print(f'hypothesis that there is no difference between the drug and the placebo.')

Simulation of arrival times and service deliveries for a multiserver queue::

    from heapq import heapify, heapreplace
    from random import expovariate, gauss
    from statistics import mean, quantiles

    average_arrival_interval = 5.6
    average_service_time = 15.0
    stdev_service_time = 3.5
    num_servers = 3

    waits = []
    arrival_time = 0.0
    servers = [0.0] * num_servers  # time when each server becomes available
    heapify(servers)
    for i in range(1_000_000):
        arrival_time += expovariate(1.0 / average_arrival_interval)
        next_server_available = servers[0]
        wait = max(0.0, next_server_available - arrival_time)
        waits.append(wait)
        service_duration = max(0.0, gauss(average_service_time, stdev_service_time))
        service_completed = arrival_time + wait + service_duration
        heapreplace(servers, service_completed)

    print(f'Mean wait: {mean(waits):.1f}   Max wait: {max(waits):.1f}')
    print('Quartiles:', [round(q, 1) for q in quantiles(waits)])

.. seealso::

   `Statistics for Hackers <https://www.youtube.com/watch?v=Iq9DzN6mvYA>`_
   a video tutorial by
   `Jake Vanderplas <https://us.pycon.org/2016/speaker/profile/295/>`_
   on statistical analysis using just a few fundamental concepts
   including simulation, sampling, shuffling, and cross-validation.

   `Economics Simulation
   <https://nbviewer.org/url/norvig.com/ipython/Economics.ipynb>`_
   a simulation of a marketplace by
   `Peter Norvig <https://norvig.com/bio.html>`_ that shows effective
   use of many of the tools and distributions provided by this module
   (gauss, uniform, sample, betavariate, choice, triangular, and randrange).

   `A Concrete Introduction to Probability (using Python)
   <https://nbviewer.org/url/norvig.com/ipython/Probability.ipynb>`_
   a tutorial by `Peter Norvig <https://norvig.com/bio.html>`_ covering
   the basics of probability theory, how to write simulations, and
   how to perform data analysis using Python.


Recipes
-------

These recipes show how to efficiently make random selections
from the combinatoric iterators in the :mod:`itertools` module
or the :pypi:`more-itertools` project:

.. testcode::

   import random

   def random_product(*iterables, repeat=1):
       "Random selection from itertools.product(*iterables, repeat=repeat)"
       pools = tuple(map(tuple, iterables)) * repeat
       return tuple(map(random.choice, pools))

   def random_permutation(iterable, r=None):
       "Random selection from itertools.permutations(iterable, r)"
       pool = tuple(iterable)
       r = len(pool) if r is None else r
       return tuple(random.sample(pool, r))

   def random_combination(iterable, r):
       "Random selection from itertools.combinations(iterable, r)"
       pool = tuple(iterable)
       n = len(pool)
       indices = sorted(random.sample(range(n), r))
       return tuple(pool[i] for i in indices)

   def random_combination_with_replacement(iterable, r):
       "Choose r elements with replacement.  Order the result to match the iterable."
       # Result will be in set(itertools.combinations_with_replacement(iterable, r)).
       pool = tuple(iterable)
       n = len(pool)
       indices = sorted(random.choices(range(n), k=r))
       return tuple(pool[i] for i in indices)

   def random_derangement(iterable):
       "Choose a permutation where no element stays in its original position."
       seq = tuple(iterable)
       if len(seq) < 2:
           if not seq:
               return ()
           raise IndexError('No derangments to choose from')
       perm = list(range(len(seq)))
       start = tuple(perm)
       while True:
           random.shuffle(perm)
           if all(p != q for p, q in zip(start, perm)):
               return tuple([seq[i] for i in perm])

.. doctest::
    :hide:

    >>> import random


    >>> random.seed(8675309)
    >>> random_product('ABCDEFG', repeat=5)
    ('D', 'B', 'E', 'F', 'E')


    >>> random.seed(8675309)
    >>> random_permutation('ABCDEFG')
    ('D', 'B', 'E', 'C', 'G', 'A', 'F')
    >>> random_permutation('ABCDEFG', 5)
    ('A', 'G', 'D', 'C', 'B')


    >>> random.seed(8675309)
    >>> random_combination('ABCDEFG', 7)
    ('A', 'B', 'C', 'D', 'E', 'F', 'G')
    >>> random_combination('ABCDEFG', 6)
    ('A', 'B', 'C', 'D', 'F', 'G')
    >>> random_combination('ABCDEFG', 5)
    ('A', 'B', 'C', 'E', 'F')
    >>> random_combination('ABCDEFG', 4)
    ('B', 'C', 'D', 'G')
    >>> random_combination('ABCDEFG', 3)
    ('B', 'E', 'G')
    >>> random_combination('ABCDEFG', 2)
    ('E', 'G')
    >>> random_combination('ABCDEFG', 1)
    ('C',)
    >>> random_combination('ABCDEFG', 0)
    ()


    >>> random.seed(8675309)
    >>> random_combination_with_replacement('ABCDEFG', 7)
    ('B', 'C', 'D', 'E', 'E', 'E', 'G')
    >>> random_combination_with_replacement('ABCDEFG', 3)
    ('A', 'B', 'E')
    >>> random_combination_with_replacement('ABCDEFG', 2)
    ('A', 'G')
    >>> random_combination_with_replacement('ABCDEFG', 1)
    ('E',)
    >>> random_combination_with_replacement('ABCDEFG', 0)
    ()


    >>> random.seed(8675309)
    >>> random_derangement('')
    ()
    >>> random_derangement('A')
    Traceback (most recent call last):
    ...
    IndexError: No derangments to choose from
    >>> random_derangement('AB')
    ('B', 'A')
    >>> random_derangement('ABC')
    ('C', 'A', 'B')
    >>> random_derangement('ABCD')
    ('B', 'A', 'D', 'C')
    >>> random_derangement('ABCDE')
    ('B', 'C', 'A', 'E', 'D')
    >>> # Identical inputs treated as distinct
    >>> identical = 20
    >>> random_derangement((10, identical, 30, identical))
    (20, 30, 10, 20)


The default :func:`.random` returns multiples of 2⁻⁵³ in the range
*0.0 ≤ x < 1.0*.  All such numbers are evenly spaced and are exactly
representable as Python floats.  However, many other representable
floats in that interval are not possible selections.  For example,
``0.05954861408025609`` isn't an integer multiple of 2⁻⁵³.

The following recipe takes a different approach.  All floats in the
interval are possible selections.  The mantissa comes from a uniform
distribution of integers in the range *2⁵² ≤ mantissa < 2⁵³*.  The
exponent comes from a geometric distribution where exponents smaller
than *-53* occur half as often as the next larger exponent.

::

    from random import Random
    from math import ldexp

    class FullRandom(Random):

        def random(self):
            mantissa = 0x10_0000_0000_0000 | self.getrandbits(52)
            exponent = -53
            x = 0
            while not x:
                x = self.getrandbits(32)
                exponent += x.bit_length() - 32
            return ldexp(mantissa, exponent)

All :ref:`real valued distributions <real-valued-distributions>`
in the class will use the new method::

    >>> fr = FullRandom()
    >>> fr.random()
    0.05954861408025609
    >>> fr.expovariate(0.25)
    8.87925541791544

The recipe is conceptually equivalent to an algorithm that chooses from
all the multiples of 2⁻¹⁰⁷⁴ in the range *0.0 ≤ x < 1.0*.  All such
numbers are evenly spaced, but most have to be rounded down to the
nearest representable Python float.  (The value 2⁻¹⁰⁷⁴ is the smallest
positive unnormalized float and is equal to ``math.ulp(0.0)``.)


.. seealso::

   `Generating Pseudo-random Floating-Point Values
   <https://allendowney.com/research/rand/downey07randfloat.pdf>`_ a
   paper by Allen B. Downey describing ways to generate more
   fine-grained floats than normally generated by :func:`.random`.

.. _random-cli:

Command-line usage
------------------

.. versionadded:: 3.13

The :mod:`!random` module can be executed from the command line.

.. code-block:: sh

   python -m random [-h] [-c CHOICE [CHOICE ...] | -i N | -f N] [input ...]

The following options are accepted:

.. program:: random

.. option:: -h, --help

   Show the help message and exit.

.. option:: -c CHOICE [CHOICE ...]
            --choice CHOICE [CHOICE ...]

   Print a random choice, using :meth:`choice`.

.. option:: -i <N>
            --integer <N>

   Print a random integer between 1 and N inclusive, using :meth:`randint`.

.. option:: -f <N>
            --float <N>

   Print a random floating-point number between 0 and N inclusive,
   using :meth:`uniform`.

If no options are given, the output depends on the input:

* String or multiple: same as :option:`--choice`.
* Integer: same as :option:`--integer`.
* Float: same as :option:`--float`.

.. _random-cli-example:

Command-line example
--------------------

Here are some examples of the :mod:`!random` command-line interface:

.. code-block:: console

   $ # Choose one at random
   $ python -m random egg bacon sausage spam "Lobster Thermidor aux crevettes with a Mornay sauce"
   Lobster Thermidor aux crevettes with a Mornay sauce

   $ # Random integer
   $ python -m random 6
   6

   $ # Random floating-point number
   $ python -m random 1.8
   1.7080016272295635

   $ # With explicit arguments
   $ python  -m random --choice egg bacon sausage spam "Lobster Thermidor aux crevettes with a Mornay sauce"
   egg

   $ python -m random --integer 6
   3

   $ python -m random --float 1.8
   1.5666339105010318

   $ python -m random --integer 6
   5

   $ python -m random --float 6
   3.1942323316565915
