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