1"""Random variable generators.
2
3    integers
4    --------
5           uniform within range
6
7    sequences
8    ---------
9           pick random element
10           pick random sample
11           pick weighted random sample
12           generate random permutation
13
14    distributions on the real line:
15    ------------------------------
16           uniform
17           triangular
18           normal (Gaussian)
19           lognormal
20           negative exponential
21           gamma
22           beta
23           pareto
24           Weibull
25
26    distributions on the circle (angles 0 to 2pi)
27    ---------------------------------------------
28           circular uniform
29           von Mises
30
31General notes on the underlying Mersenne Twister core generator:
32
33* The period is 2**19937-1.
34* It is one of the most extensively tested generators in existence.
35* The random() method is implemented in C, executes in a single Python step,
36  and is, therefore, threadsafe.
37
38"""
39
40from warnings import warn as _warn
41from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
42from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
43from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
44from os import urandom as _urandom
45from _collections_abc import Set as _Set, Sequence as _Sequence
46from hashlib import sha512 as _sha512
47import itertools as _itertools
48import bisect as _bisect
49
50__all__ = ["Random","seed","random","uniform","randint","choice","sample",
51           "randrange","shuffle","normalvariate","lognormvariate",
52           "expovariate","vonmisesvariate","gammavariate","triangular",
53           "gauss","betavariate","paretovariate","weibullvariate",
54           "getstate","setstate", "getrandbits", "choices",
55           "SystemRandom"]
56
57NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
58TWOPI = 2.0*_pi
59LOG4 = _log(4.0)
60SG_MAGICCONST = 1.0 + _log(4.5)
61BPF = 53        # Number of bits in a float
62RECIP_BPF = 2**-BPF
63
64
65# Translated by Guido van Rossum from C source provided by
66# Adrian Baddeley.  Adapted by Raymond Hettinger for use with
67# the Mersenne Twister  and os.urandom() core generators.
68
69import _random
70
71class Random(_random.Random):
72    """Random number generator base class used by bound module functions.
73
74    Used to instantiate instances of Random to get generators that don't
75    share state.
76
77    Class Random can also be subclassed if you want to use a different basic
78    generator of your own devising: in that case, override the following
79    methods:  random(), seed(), getstate(), and setstate().
80    Optionally, implement a getrandbits() method so that randrange()
81    can cover arbitrarily large ranges.
82
83    """
84
85    VERSION = 3     # used by getstate/setstate
86
87    def __init__(self, x=None):
88        """Initialize an instance.
89
90        Optional argument x controls seeding, as for Random.seed().
91        """
92
93        self.seed(x)
94        self.gauss_next = None
95
96    def seed(self, a=None, version=2):
97        """Initialize internal state from hashable object.
98
99        None or no argument seeds from current time or from an operating
100        system specific randomness source if available.
101
102        If *a* is an int, all bits are used.
103
104        For version 2 (the default), all of the bits are used if *a* is a str,
105        bytes, or bytearray.  For version 1 (provided for reproducing random
106        sequences from older versions of Python), the algorithm for str and
107        bytes generates a narrower range of seeds.
108
109        """
110
111        if version == 1 and isinstance(a, (str, bytes)):
112            x = ord(a[0]) << 7 if a else 0
113            for c in a:
114                x = ((1000003 * x) ^ ord(c)) & 0xFFFFFFFFFFFFFFFF
115            x ^= len(a)
116            a = -2 if x == -1 else x
117
118        if version == 2 and isinstance(a, (str, bytes, bytearray)):
119            if isinstance(a, str):
120                a = a.encode()
121            a += _sha512(a).digest()
122            a = int.from_bytes(a, 'big')
123
124        super().seed(a)
125        self.gauss_next = None
126
127    def getstate(self):
128        """Return internal state; can be passed to setstate() later."""
129        return self.VERSION, super().getstate(), self.gauss_next
130
131    def setstate(self, state):
132        """Restore internal state from object returned by getstate()."""
133        version = state[0]
134        if version == 3:
135            version, internalstate, self.gauss_next = state
136            super().setstate(internalstate)
137        elif version == 2:
138            version, internalstate, self.gauss_next = state
139            # In version 2, the state was saved as signed ints, which causes
140            #   inconsistencies between 32/64-bit systems. The state is
141            #   really unsigned 32-bit ints, so we convert negative ints from
142            #   version 2 to positive longs for version 3.
143            try:
144                internalstate = tuple(x % (2**32) for x in internalstate)
145            except ValueError as e:
146                raise TypeError from e
147            super().setstate(internalstate)
148        else:
149            raise ValueError("state with version %s passed to "
150                             "Random.setstate() of version %s" %
151                             (version, self.VERSION))
152
153## ---- Methods below this point do not need to be overridden when
154## ---- subclassing for the purpose of using a different core generator.
155
156## -------------------- pickle support  -------------------
157
158    # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
159    # longer called; we leave it here because it has been here since random was
160    # rewritten back in 2001 and why risk breaking something.
161    def __getstate__(self): # for pickle
162        return self.getstate()
163
164    def __setstate__(self, state):  # for pickle
165        self.setstate(state)
166
167    def __reduce__(self):
168        return self.__class__, (), self.getstate()
169
170## -------------------- integer methods  -------------------
171
172    def randrange(self, start, stop=None, step=1, _int=int):
173        """Choose a random item from range(start, stop[, step]).
174
175        This fixes the problem with randint() which includes the
176        endpoint; in Python this is usually not what you want.
177
178        """
179
180        # This code is a bit messy to make it fast for the
181        # common case while still doing adequate error checking.
182        istart = _int(start)
183        if istart != start:
184            raise ValueError("non-integer arg 1 for randrange()")
185        if stop is None:
186            if istart > 0:
187                return self._randbelow(istart)
188            raise ValueError("empty range for randrange()")
189
190        # stop argument supplied.
191        istop = _int(stop)
192        if istop != stop:
193            raise ValueError("non-integer stop for randrange()")
194        width = istop - istart
195        if step == 1 and width > 0:
196            return istart + self._randbelow(width)
197        if step == 1:
198            raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
199
200        # Non-unit step argument supplied.
201        istep = _int(step)
202        if istep != step:
203            raise ValueError("non-integer step for randrange()")
204        if istep > 0:
205            n = (width + istep - 1) // istep
206        elif istep < 0:
207            n = (width + istep + 1) // istep
208        else:
209            raise ValueError("zero step for randrange()")
210
211        if n <= 0:
212            raise ValueError("empty range for randrange()")
213
214        return istart + istep*self._randbelow(n)
215
216    def randint(self, a, b):
217        """Return random integer in range [a, b], including both end points.
218        """
219
220        return self.randrange(a, b+1)
221
222    def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type,
223                   Method=_MethodType, BuiltinMethod=_BuiltinMethodType):
224        "Return a random int in the range [0,n).  Raises ValueError if n==0."
225
226        random = self.random
227        getrandbits = self.getrandbits
228        # Only call self.getrandbits if the original random() builtin method
229        # has not been overridden or if a new getrandbits() was supplied.
230        if type(random) is BuiltinMethod or type(getrandbits) is Method:
231            k = n.bit_length()  # don't use (n-1) here because n can be 1
232            r = getrandbits(k)          # 0 <= r < 2**k
233            while r >= n:
234                r = getrandbits(k)
235            return r
236        # There's an overridden random() method but no new getrandbits() method,
237        # so we can only use random() from here.
238        if n >= maxsize:
239            _warn("Underlying random() generator does not supply \n"
240                "enough bits to choose from a population range this large.\n"
241                "To remove the range limitation, add a getrandbits() method.")
242            return int(random() * n)
243        rem = maxsize % n
244        limit = (maxsize - rem) / maxsize   # int(limit * maxsize) % n == 0
245        r = random()
246        while r >= limit:
247            r = random()
248        return int(r*maxsize) % n
249
250## -------------------- sequence methods  -------------------
251
252    def choice(self, seq):
253        """Choose a random element from a non-empty sequence."""
254        try:
255            i = self._randbelow(len(seq))
256        except ValueError:
257            raise IndexError('Cannot choose from an empty sequence') from None
258        return seq[i]
259
260    def shuffle(self, x, random=None):
261        """Shuffle list x in place, and return None.
262
263        Optional argument random is a 0-argument function returning a
264        random float in [0.0, 1.0); if it is the default None, the
265        standard random.random will be used.
266
267        """
268
269        if random is None:
270            randbelow = self._randbelow
271            for i in reversed(range(1, len(x))):
272                # pick an element in x[:i+1] with which to exchange x[i]
273                j = randbelow(i+1)
274                x[i], x[j] = x[j], x[i]
275        else:
276            _int = int
277            for i in reversed(range(1, len(x))):
278                # pick an element in x[:i+1] with which to exchange x[i]
279                j = _int(random() * (i+1))
280                x[i], x[j] = x[j], x[i]
281
282    def sample(self, population, k):
283        """Chooses k unique random elements from a population sequence or set.
284
285        Returns a new list containing elements from the population while
286        leaving the original population unchanged.  The resulting list is
287        in selection order so that all sub-slices will also be valid random
288        samples.  This allows raffle winners (the sample) to be partitioned
289        into grand prize and second place winners (the subslices).
290
291        Members of the population need not be hashable or unique.  If the
292        population contains repeats, then each occurrence is a possible
293        selection in the sample.
294
295        To choose a sample in a range of integers, use range as an argument.
296        This is especially fast and space efficient for sampling from a
297        large population:   sample(range(10000000), 60)
298        """
299
300        # Sampling without replacement entails tracking either potential
301        # selections (the pool) in a list or previous selections in a set.
302
303        # When the number of selections is small compared to the
304        # population, then tracking selections is efficient, requiring
305        # only a small set and an occasional reselection.  For
306        # a larger number of selections, the pool tracking method is
307        # preferred since the list takes less space than the
308        # set and it doesn't suffer from frequent reselections.
309
310        if isinstance(population, _Set):
311            population = tuple(population)
312        if not isinstance(population, _Sequence):
313            raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")
314        randbelow = self._randbelow
315        n = len(population)
316        if not 0 <= k <= n:
317            raise ValueError("Sample larger than population or is negative")
318        result = [None] * k
319        setsize = 21        # size of a small set minus size of an empty list
320        if k > 5:
321            setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
322        if n <= setsize:
323            # An n-length list is smaller than a k-length set
324            pool = list(population)
325            for i in range(k):         # invariant:  non-selected at [0,n-i)
326                j = randbelow(n-i)
327                result[i] = pool[j]
328                pool[j] = pool[n-i-1]   # move non-selected item into vacancy
329        else:
330            selected = set()
331            selected_add = selected.add
332            for i in range(k):
333                j = randbelow(n)
334                while j in selected:
335                    j = randbelow(n)
336                selected_add(j)
337                result[i] = population[j]
338        return result
339
340    def choices(self, population, weights=None, *, cum_weights=None, k=1):
341        """Return a k sized list of population elements chosen with replacement.
342
343        If the relative weights or cumulative weights are not specified,
344        the selections are made with equal probability.
345
346        """
347        random = self.random
348        if cum_weights is None:
349            if weights is None:
350                _int = int
351                total = len(population)
352                return [population[_int(random() * total)] for i in range(k)]
353            cum_weights = list(_itertools.accumulate(weights))
354        elif weights is not None:
355            raise TypeError('Cannot specify both weights and cumulative weights')
356        if len(cum_weights) != len(population):
357            raise ValueError('The number of weights does not match the population')
358        bisect = _bisect.bisect
359        total = cum_weights[-1]
360        return [population[bisect(cum_weights, random() * total)] for i in range(k)]
361
362## -------------------- real-valued distributions  -------------------
363
364## -------------------- uniform distribution -------------------
365
366    def uniform(self, a, b):
367        "Get a random number in the range [a, b) or [a, b] depending on rounding."
368        return a + (b-a) * self.random()
369
370## -------------------- triangular --------------------
371
372    def triangular(self, low=0.0, high=1.0, mode=None):
373        """Triangular distribution.
374
375        Continuous distribution bounded by given lower and upper limits,
376        and having a given mode value in-between.
377
378        http://en.wikipedia.org/wiki/Triangular_distribution
379
380        """
381        u = self.random()
382        try:
383            c = 0.5 if mode is None else (mode - low) / (high - low)
384        except ZeroDivisionError:
385            return low
386        if u > c:
387            u = 1.0 - u
388            c = 1.0 - c
389            low, high = high, low
390        return low + (high - low) * (u * c) ** 0.5
391
392## -------------------- normal distribution --------------------
393
394    def normalvariate(self, mu, sigma):
395        """Normal distribution.
396
397        mu is the mean, and sigma is the standard deviation.
398
399        """
400        # mu = mean, sigma = standard deviation
401
402        # Uses Kinderman and Monahan method. Reference: Kinderman,
403        # A.J. and Monahan, J.F., "Computer generation of random
404        # variables using the ratio of uniform deviates", ACM Trans
405        # Math Software, 3, (1977), pp257-260.
406
407        random = self.random
408        while 1:
409            u1 = random()
410            u2 = 1.0 - random()
411            z = NV_MAGICCONST*(u1-0.5)/u2
412            zz = z*z/4.0
413            if zz <= -_log(u2):
414                break
415        return mu + z*sigma
416
417## -------------------- lognormal distribution --------------------
418
419    def lognormvariate(self, mu, sigma):
420        """Log normal distribution.
421
422        If you take the natural logarithm of this distribution, you'll get a
423        normal distribution with mean mu and standard deviation sigma.
424        mu can have any value, and sigma must be greater than zero.
425
426        """
427        return _exp(self.normalvariate(mu, sigma))
428
429## -------------------- exponential distribution --------------------
430
431    def expovariate(self, lambd):
432        """Exponential distribution.
433
434        lambd is 1.0 divided by the desired mean.  It should be
435        nonzero.  (The parameter would be called "lambda", but that is
436        a reserved word in Python.)  Returned values range from 0 to
437        positive infinity if lambd is positive, and from negative
438        infinity to 0 if lambd is negative.
439
440        """
441        # lambd: rate lambd = 1/mean
442        # ('lambda' is a Python reserved word)
443
444        # we use 1-random() instead of random() to preclude the
445        # possibility of taking the log of zero.
446        return -_log(1.0 - self.random())/lambd
447
448## -------------------- von Mises distribution --------------------
449
450    def vonmisesvariate(self, mu, kappa):
451        """Circular data distribution.
452
453        mu is the mean angle, expressed in radians between 0 and 2*pi, and
454        kappa is the concentration parameter, which must be greater than or
455        equal to zero.  If kappa is equal to zero, this distribution reduces
456        to a uniform random angle over the range 0 to 2*pi.
457
458        """
459        # mu:    mean angle (in radians between 0 and 2*pi)
460        # kappa: concentration parameter kappa (>= 0)
461        # if kappa = 0 generate uniform random angle
462
463        # Based upon an algorithm published in: Fisher, N.I.,
464        # "Statistical Analysis of Circular Data", Cambridge
465        # University Press, 1993.
466
467        # Thanks to Magnus Kessler for a correction to the
468        # implementation of step 4.
469
470        random = self.random
471        if kappa <= 1e-6:
472            return TWOPI * random()
473
474        s = 0.5 / kappa
475        r = s + _sqrt(1.0 + s * s)
476
477        while 1:
478            u1 = random()
479            z = _cos(_pi * u1)
480
481            d = z / (r + z)
482            u2 = random()
483            if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
484                break
485
486        q = 1.0 / r
487        f = (q + z) / (1.0 + q * z)
488        u3 = random()
489        if u3 > 0.5:
490            theta = (mu + _acos(f)) % TWOPI
491        else:
492            theta = (mu - _acos(f)) % TWOPI
493
494        return theta
495
496## -------------------- gamma distribution --------------------
497
498    def gammavariate(self, alpha, beta):
499        """Gamma distribution.  Not the gamma function!
500
501        Conditions on the parameters are alpha > 0 and beta > 0.
502
503        The probability distribution function is:
504
505                    x ** (alpha - 1) * math.exp(-x / beta)
506          pdf(x) =  --------------------------------------
507                      math.gamma(alpha) * beta ** alpha
508
509        """
510
511        # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
512
513        # Warning: a few older sources define the gamma distribution in terms
514        # of alpha > -1.0
515        if alpha <= 0.0 or beta <= 0.0:
516            raise ValueError('gammavariate: alpha and beta must be > 0.0')
517
518        random = self.random
519        if alpha > 1.0:
520
521            # Uses R.C.H. Cheng, "The generation of Gamma
522            # variables with non-integral shape parameters",
523            # Applied Statistics, (1977), 26, No. 1, p71-74
524
525            ainv = _sqrt(2.0 * alpha - 1.0)
526            bbb = alpha - LOG4
527            ccc = alpha + ainv
528
529            while 1:
530                u1 = random()
531                if not 1e-7 < u1 < .9999999:
532                    continue
533                u2 = 1.0 - random()
534                v = _log(u1/(1.0-u1))/ainv
535                x = alpha*_exp(v)
536                z = u1*u1*u2
537                r = bbb+ccc*v-x
538                if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
539                    return x * beta
540
541        elif alpha == 1.0:
542            # expovariate(1)
543            u = random()
544            while u <= 1e-7:
545                u = random()
546            return -_log(u) * beta
547
548        else:   # alpha is between 0 and 1 (exclusive)
549
550            # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
551
552            while 1:
553                u = random()
554                b = (_e + alpha)/_e
555                p = b*u
556                if p <= 1.0:
557                    x = p ** (1.0/alpha)
558                else:
559                    x = -_log((b-p)/alpha)
560                u1 = random()
561                if p > 1.0:
562                    if u1 <= x ** (alpha - 1.0):
563                        break
564                elif u1 <= _exp(-x):
565                    break
566            return x * beta
567
568## -------------------- Gauss (faster alternative) --------------------
569
570    def gauss(self, mu, sigma):
571        """Gaussian distribution.
572
573        mu is the mean, and sigma is the standard deviation.  This is
574        slightly faster than the normalvariate() function.
575
576        Not thread-safe without a lock around calls.
577
578        """
579
580        # When x and y are two variables from [0, 1), uniformly
581        # distributed, then
582        #
583        #    cos(2*pi*x)*sqrt(-2*log(1-y))
584        #    sin(2*pi*x)*sqrt(-2*log(1-y))
585        #
586        # are two *independent* variables with normal distribution
587        # (mu = 0, sigma = 1).
588        # (Lambert Meertens)
589        # (corrected version; bug discovered by Mike Miller, fixed by LM)
590
591        # Multithreading note: When two threads call this function
592        # simultaneously, it is possible that they will receive the
593        # same return value.  The window is very small though.  To
594        # avoid this, you have to use a lock around all calls.  (I
595        # didn't want to slow this down in the serial case by using a
596        # lock here.)
597
598        random = self.random
599        z = self.gauss_next
600        self.gauss_next = None
601        if z is None:
602            x2pi = random() * TWOPI
603            g2rad = _sqrt(-2.0 * _log(1.0 - random()))
604            z = _cos(x2pi) * g2rad
605            self.gauss_next = _sin(x2pi) * g2rad
606
607        return mu + z*sigma
608
609## -------------------- beta --------------------
610## See
611## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
612## for Ivan Frohne's insightful analysis of why the original implementation:
613##
614##    def betavariate(self, alpha, beta):
615##        # Discrete Event Simulation in C, pp 87-88.
616##
617##        y = self.expovariate(alpha)
618##        z = self.expovariate(1.0/beta)
619##        return z/(y+z)
620##
621## was dead wrong, and how it probably got that way.
622
623    def betavariate(self, alpha, beta):
624        """Beta distribution.
625
626        Conditions on the parameters are alpha > 0 and beta > 0.
627        Returned values range between 0 and 1.
628
629        """
630
631        # This version due to Janne Sinkkonen, and matches all the std
632        # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
633        y = self.gammavariate(alpha, 1.0)
634        if y == 0:
635            return 0.0
636        else:
637            return y / (y + self.gammavariate(beta, 1.0))
638
639## -------------------- Pareto --------------------
640
641    def paretovariate(self, alpha):
642        """Pareto distribution.  alpha is the shape parameter."""
643        # Jain, pg. 495
644
645        u = 1.0 - self.random()
646        return 1.0 / u ** (1.0/alpha)
647
648## -------------------- Weibull --------------------
649
650    def weibullvariate(self, alpha, beta):
651        """Weibull distribution.
652
653        alpha is the scale parameter and beta is the shape parameter.
654
655        """
656        # Jain, pg. 499; bug fix courtesy Bill Arms
657
658        u = 1.0 - self.random()
659        return alpha * (-_log(u)) ** (1.0/beta)
660
661## --------------- Operating System Random Source  ------------------
662
663class SystemRandom(Random):
664    """Alternate random number generator using sources provided
665    by the operating system (such as /dev/urandom on Unix or
666    CryptGenRandom on Windows).
667
668     Not available on all systems (see os.urandom() for details).
669    """
670
671    def random(self):
672        """Get the next random number in the range [0.0, 1.0)."""
673        return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
674
675    def getrandbits(self, k):
676        """getrandbits(k) -> x.  Generates an int with k random bits."""
677        if k <= 0:
678            raise ValueError('number of bits must be greater than zero')
679        if k != int(k):
680            raise TypeError('number of bits should be an integer')
681        numbytes = (k + 7) // 8                       # bits / 8 and rounded up
682        x = int.from_bytes(_urandom(numbytes), 'big')
683        return x >> (numbytes * 8 - k)                # trim excess bits
684
685    def seed(self, *args, **kwds):
686        "Stub method.  Not used for a system random number generator."
687        return None
688
689    def _notimplemented(self, *args, **kwds):
690        "Method should not be called for a system random number generator."
691        raise NotImplementedError('System entropy source does not have state.')
692    getstate = setstate = _notimplemented
693
694## -------------------- test program --------------------
695
696def _test_generator(n, func, args):
697    import time
698    print(n, 'times', func.__name__)
699    total = 0.0
700    sqsum = 0.0
701    smallest = 1e10
702    largest = -1e10
703    t0 = time.time()
704    for i in range(n):
705        x = func(*args)
706        total += x
707        sqsum = sqsum + x*x
708        smallest = min(x, smallest)
709        largest = max(x, largest)
710    t1 = time.time()
711    print(round(t1-t0, 3), 'sec,', end=' ')
712    avg = total/n
713    stddev = _sqrt(sqsum/n - avg*avg)
714    print('avg %g, stddev %g, min %g, max %g\n' % \
715              (avg, stddev, smallest, largest))
716
717
718def _test(N=2000):
719    _test_generator(N, random, ())
720    _test_generator(N, normalvariate, (0.0, 1.0))
721    _test_generator(N, lognormvariate, (0.0, 1.0))
722    _test_generator(N, vonmisesvariate, (0.0, 1.0))
723    _test_generator(N, gammavariate, (0.01, 1.0))
724    _test_generator(N, gammavariate, (0.1, 1.0))
725    _test_generator(N, gammavariate, (0.1, 2.0))
726    _test_generator(N, gammavariate, (0.5, 1.0))
727    _test_generator(N, gammavariate, (0.9, 1.0))
728    _test_generator(N, gammavariate, (1.0, 1.0))
729    _test_generator(N, gammavariate, (2.0, 1.0))
730    _test_generator(N, gammavariate, (20.0, 1.0))
731    _test_generator(N, gammavariate, (200.0, 1.0))
732    _test_generator(N, gauss, (0.0, 1.0))
733    _test_generator(N, betavariate, (3.0, 3.0))
734    _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
735
736# Create one instance, seeded from current time, and export its methods
737# as module-level functions.  The functions share state across all uses
738#(both in the user's code and in the Python libraries), but that's fine
739# for most programs and is easier for the casual user than making them
740# instantiate their own Random() instance.
741
742_inst = Random()
743seed = _inst.seed
744random = _inst.random
745uniform = _inst.uniform
746triangular = _inst.triangular
747randint = _inst.randint
748choice = _inst.choice
749randrange = _inst.randrange
750sample = _inst.sample
751shuffle = _inst.shuffle
752choices = _inst.choices
753normalvariate = _inst.normalvariate
754lognormvariate = _inst.lognormvariate
755expovariate = _inst.expovariate
756vonmisesvariate = _inst.vonmisesvariate
757gammavariate = _inst.gammavariate
758gauss = _inst.gauss
759betavariate = _inst.betavariate
760paretovariate = _inst.paretovariate
761weibullvariate = _inst.weibullvariate
762getstate = _inst.getstate
763setstate = _inst.setstate
764getrandbits = _inst.getrandbits
765
766if __name__ == '__main__':
767    _test()
768