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