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 49import os as _os 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 58NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) 59TWOPI = 2.0*_pi 60LOG4 = _log(4.0) 61SG_MAGICCONST = 1.0 + _log(4.5) 62BPF = 53 # Number of bits in a float 63RECIP_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 70import _random 71 72class 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 if istart != start: 186 raise ValueError("non-integer arg 1 for randrange()") 187 if stop is None: 188 if istart > 0: 189 return self._randbelow(istart) 190 raise ValueError("empty range for randrange()") 191 192 # stop argument supplied. 193 istop = _int(stop) 194 if istop != stop: 195 raise ValueError("non-integer stop for randrange()") 196 width = istop - istart 197 if step == 1 and width > 0: 198 return istart + self._randbelow(width) 199 if step == 1: 200 raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width)) 201 202 # Non-unit step argument supplied. 203 istep = _int(step) 204 if istep != step: 205 raise ValueError("non-integer step for randrange()") 206 if istep > 0: 207 n = (width + istep - 1) // istep 208 elif istep < 0: 209 n = (width + istep + 1) // istep 210 else: 211 raise ValueError("zero step for randrange()") 212 213 if n <= 0: 214 raise ValueError("empty range for randrange()") 215 216 return istart + istep*self._randbelow(n) 217 218 def randint(self, a, b): 219 """Return random integer in range [a, b], including both end points. 220 """ 221 222 return self.randrange(a, b+1) 223 224 def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type, 225 Method=_MethodType, BuiltinMethod=_BuiltinMethodType): 226 "Return a random int in the range [0,n). Raises ValueError if n==0." 227 228 random = self.random 229 getrandbits = self.getrandbits 230 # Only call self.getrandbits if the original random() builtin method 231 # has not been overridden or if a new getrandbits() was supplied. 232 if type(random) is BuiltinMethod or type(getrandbits) is Method: 233 k = n.bit_length() # don't use (n-1) here because n can be 1 234 r = getrandbits(k) # 0 <= r < 2**k 235 while r >= n: 236 r = getrandbits(k) 237 return r 238 # There's an overridden random() method but no new getrandbits() method, 239 # so we can only use random() from here. 240 if n >= maxsize: 241 _warn("Underlying random() generator does not supply \n" 242 "enough bits to choose from a population range this large.\n" 243 "To remove the range limitation, add a getrandbits() method.") 244 return int(random() * n) 245 if n == 0: 246 raise ValueError("Boundary cannot be zero") 247 rem = maxsize % n 248 limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0 249 r = random() 250 while r >= limit: 251 r = random() 252 return int(r*maxsize) % n 253 254## -------------------- sequence methods ------------------- 255 256 def choice(self, seq): 257 """Choose a random element from a non-empty sequence.""" 258 try: 259 i = self._randbelow(len(seq)) 260 except ValueError: 261 raise IndexError('Cannot choose from an empty sequence') from None 262 return seq[i] 263 264 def shuffle(self, x, random=None): 265 """Shuffle list x in place, and return None. 266 267 Optional argument random is a 0-argument function returning a 268 random float in [0.0, 1.0); if it is the default None, the 269 standard random.random will be used. 270 271 """ 272 273 if random is None: 274 randbelow = self._randbelow 275 for i in reversed(range(1, len(x))): 276 # pick an element in x[:i+1] with which to exchange x[i] 277 j = randbelow(i+1) 278 x[i], x[j] = x[j], x[i] 279 else: 280 _int = int 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 = _int(random() * (i+1)) 284 x[i], x[j] = x[j], x[i] 285 286 def sample(self, population, k): 287 """Chooses k unique random elements from a population sequence or set. 288 289 Returns a new list containing elements from the population while 290 leaving the original population unchanged. The resulting list is 291 in selection order so that all sub-slices will also be valid random 292 samples. This allows raffle winners (the sample) to be partitioned 293 into grand prize and second place winners (the subslices). 294 295 Members of the population need not be hashable or unique. If the 296 population contains repeats, then each occurrence is a possible 297 selection in the sample. 298 299 To choose a sample in a range of integers, use range as an argument. 300 This is especially fast and space efficient for sampling from a 301 large population: sample(range(10000000), 60) 302 """ 303 304 # Sampling without replacement entails tracking either potential 305 # selections (the pool) in a list or previous selections in a set. 306 307 # When the number of selections is small compared to the 308 # population, then tracking selections is efficient, requiring 309 # only a small set and an occasional reselection. For 310 # a larger number of selections, the pool tracking method is 311 # preferred since the list takes less space than the 312 # set and it doesn't suffer from frequent reselections. 313 314 if isinstance(population, _Set): 315 population = tuple(population) 316 if not isinstance(population, _Sequence): 317 raise TypeError("Population must be a sequence or set. For dicts, use list(d).") 318 randbelow = self._randbelow 319 n = len(population) 320 if not 0 <= k <= n: 321 raise ValueError("Sample larger than population or is negative") 322 result = [None] * k 323 setsize = 21 # size of a small set minus size of an empty list 324 if k > 5: 325 setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets 326 if n <= setsize: 327 # An n-length list is smaller than a k-length set 328 pool = list(population) 329 for i in range(k): # invariant: non-selected at [0,n-i) 330 j = randbelow(n-i) 331 result[i] = pool[j] 332 pool[j] = pool[n-i-1] # move non-selected item into vacancy 333 else: 334 selected = set() 335 selected_add = selected.add 336 for i in range(k): 337 j = randbelow(n) 338 while j in selected: 339 j = randbelow(n) 340 selected_add(j) 341 result[i] = population[j] 342 return result 343 344 def choices(self, population, weights=None, *, cum_weights=None, k=1): 345 """Return a k sized list of population elements chosen with replacement. 346 347 If the relative weights or cumulative weights are not specified, 348 the selections are made with equal probability. 349 350 """ 351 random = self.random 352 if cum_weights is None: 353 if weights is None: 354 _int = int 355 total = len(population) 356 return [population[_int(random() * total)] for i in range(k)] 357 cum_weights = list(_itertools.accumulate(weights)) 358 elif weights is not None: 359 raise TypeError('Cannot specify both weights and cumulative weights') 360 if len(cum_weights) != len(population): 361 raise ValueError('The number of weights does not match the population') 362 bisect = _bisect.bisect 363 total = cum_weights[-1] 364 hi = len(cum_weights) - 1 365 return [population[bisect(cum_weights, random() * total, 0, hi)] 366 for i in range(k)] 367 368## -------------------- real-valued distributions ------------------- 369 370## -------------------- uniform distribution ------------------- 371 372 def uniform(self, a, b): 373 "Get a random number in the range [a, b) or [a, b] depending on rounding." 374 return a + (b-a) * self.random() 375 376## -------------------- triangular -------------------- 377 378 def triangular(self, low=0.0, high=1.0, mode=None): 379 """Triangular distribution. 380 381 Continuous distribution bounded by given lower and upper limits, 382 and having a given mode value in-between. 383 384 http://en.wikipedia.org/wiki/Triangular_distribution 385 386 """ 387 u = self.random() 388 try: 389 c = 0.5 if mode is None else (mode - low) / (high - low) 390 except ZeroDivisionError: 391 return low 392 if u > c: 393 u = 1.0 - u 394 c = 1.0 - c 395 low, high = high, low 396 return low + (high - low) * _sqrt(u * c) 397 398## -------------------- normal distribution -------------------- 399 400 def normalvariate(self, mu, sigma): 401 """Normal distribution. 402 403 mu is the mean, and sigma is the standard deviation. 404 405 """ 406 # mu = mean, sigma = standard deviation 407 408 # Uses Kinderman and Monahan method. Reference: Kinderman, 409 # A.J. and Monahan, J.F., "Computer generation of random 410 # variables using the ratio of uniform deviates", ACM Trans 411 # Math Software, 3, (1977), pp257-260. 412 413 random = self.random 414 while 1: 415 u1 = random() 416 u2 = 1.0 - random() 417 z = NV_MAGICCONST*(u1-0.5)/u2 418 zz = z*z/4.0 419 if zz <= -_log(u2): 420 break 421 return mu + z*sigma 422 423## -------------------- lognormal distribution -------------------- 424 425 def lognormvariate(self, mu, sigma): 426 """Log normal distribution. 427 428 If you take the natural logarithm of this distribution, you'll get a 429 normal distribution with mean mu and standard deviation sigma. 430 mu can have any value, and sigma must be greater than zero. 431 432 """ 433 return _exp(self.normalvariate(mu, sigma)) 434 435## -------------------- exponential distribution -------------------- 436 437 def expovariate(self, lambd): 438 """Exponential distribution. 439 440 lambd is 1.0 divided by the desired mean. It should be 441 nonzero. (The parameter would be called "lambda", but that is 442 a reserved word in Python.) Returned values range from 0 to 443 positive infinity if lambd is positive, and from negative 444 infinity to 0 if lambd is negative. 445 446 """ 447 # lambd: rate lambd = 1/mean 448 # ('lambda' is a Python reserved word) 449 450 # we use 1-random() instead of random() to preclude the 451 # possibility of taking the log of zero. 452 return -_log(1.0 - self.random())/lambd 453 454## -------------------- von Mises distribution -------------------- 455 456 def vonmisesvariate(self, mu, kappa): 457 """Circular data distribution. 458 459 mu is the mean angle, expressed in radians between 0 and 2*pi, and 460 kappa is the concentration parameter, which must be greater than or 461 equal to zero. If kappa is equal to zero, this distribution reduces 462 to a uniform random angle over the range 0 to 2*pi. 463 464 """ 465 # mu: mean angle (in radians between 0 and 2*pi) 466 # kappa: concentration parameter kappa (>= 0) 467 # if kappa = 0 generate uniform random angle 468 469 # Based upon an algorithm published in: Fisher, N.I., 470 # "Statistical Analysis of Circular Data", Cambridge 471 # University Press, 1993. 472 473 # Thanks to Magnus Kessler for a correction to the 474 # implementation of step 4. 475 476 random = self.random 477 if kappa <= 1e-6: 478 return TWOPI * random() 479 480 s = 0.5 / kappa 481 r = s + _sqrt(1.0 + s * s) 482 483 while 1: 484 u1 = random() 485 z = _cos(_pi * u1) 486 487 d = z / (r + z) 488 u2 = random() 489 if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d): 490 break 491 492 q = 1.0 / r 493 f = (q + z) / (1.0 + q * z) 494 u3 = random() 495 if u3 > 0.5: 496 theta = (mu + _acos(f)) % TWOPI 497 else: 498 theta = (mu - _acos(f)) % TWOPI 499 500 return theta 501 502## -------------------- gamma distribution -------------------- 503 504 def gammavariate(self, alpha, beta): 505 """Gamma distribution. Not the gamma function! 506 507 Conditions on the parameters are alpha > 0 and beta > 0. 508 509 The probability distribution function is: 510 511 x ** (alpha - 1) * math.exp(-x / beta) 512 pdf(x) = -------------------------------------- 513 math.gamma(alpha) * beta ** alpha 514 515 """ 516 517 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 518 519 # Warning: a few older sources define the gamma distribution in terms 520 # of alpha > -1.0 521 if alpha <= 0.0 or beta <= 0.0: 522 raise ValueError('gammavariate: alpha and beta must be > 0.0') 523 524 random = self.random 525 if alpha > 1.0: 526 527 # Uses R.C.H. Cheng, "The generation of Gamma 528 # variables with non-integral shape parameters", 529 # Applied Statistics, (1977), 26, No. 1, p71-74 530 531 ainv = _sqrt(2.0 * alpha - 1.0) 532 bbb = alpha - LOG4 533 ccc = alpha + ainv 534 535 while 1: 536 u1 = random() 537 if not 1e-7 < u1 < .9999999: 538 continue 539 u2 = 1.0 - random() 540 v = _log(u1/(1.0-u1))/ainv 541 x = alpha*_exp(v) 542 z = u1*u1*u2 543 r = bbb+ccc*v-x 544 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z): 545 return x * beta 546 547 elif alpha == 1.0: 548 # expovariate(1/beta) 549 u = random() 550 while u <= 1e-7: 551 u = random() 552 return -_log(u) * beta 553 554 else: # alpha is between 0 and 1 (exclusive) 555 556 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle 557 558 while 1: 559 u = random() 560 b = (_e + alpha)/_e 561 p = b*u 562 if p <= 1.0: 563 x = p ** (1.0/alpha) 564 else: 565 x = -_log((b-p)/alpha) 566 u1 = random() 567 if p > 1.0: 568 if u1 <= x ** (alpha - 1.0): 569 break 570 elif u1 <= _exp(-x): 571 break 572 return x * beta 573 574## -------------------- Gauss (faster alternative) -------------------- 575 576 def gauss(self, mu, sigma): 577 """Gaussian distribution. 578 579 mu is the mean, and sigma is the standard deviation. This is 580 slightly faster than the normalvariate() function. 581 582 Not thread-safe without a lock around calls. 583 584 """ 585 586 # When x and y are two variables from [0, 1), uniformly 587 # distributed, then 588 # 589 # cos(2*pi*x)*sqrt(-2*log(1-y)) 590 # sin(2*pi*x)*sqrt(-2*log(1-y)) 591 # 592 # are two *independent* variables with normal distribution 593 # (mu = 0, sigma = 1). 594 # (Lambert Meertens) 595 # (corrected version; bug discovered by Mike Miller, fixed by LM) 596 597 # Multithreading note: When two threads call this function 598 # simultaneously, it is possible that they will receive the 599 # same return value. The window is very small though. To 600 # avoid this, you have to use a lock around all calls. (I 601 # didn't want to slow this down in the serial case by using a 602 # lock here.) 603 604 random = self.random 605 z = self.gauss_next 606 self.gauss_next = None 607 if z is None: 608 x2pi = random() * TWOPI 609 g2rad = _sqrt(-2.0 * _log(1.0 - random())) 610 z = _cos(x2pi) * g2rad 611 self.gauss_next = _sin(x2pi) * g2rad 612 613 return mu + z*sigma 614 615## -------------------- beta -------------------- 616## See 617## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html 618## for Ivan Frohne's insightful analysis of why the original implementation: 619## 620## def betavariate(self, alpha, beta): 621## # Discrete Event Simulation in C, pp 87-88. 622## 623## y = self.expovariate(alpha) 624## z = self.expovariate(1.0/beta) 625## return z/(y+z) 626## 627## was dead wrong, and how it probably got that way. 628 629 def betavariate(self, alpha, beta): 630 """Beta distribution. 631 632 Conditions on the parameters are alpha > 0 and beta > 0. 633 Returned values range between 0 and 1. 634 635 """ 636 637 # This version due to Janne Sinkkonen, and matches all the std 638 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). 639 y = self.gammavariate(alpha, 1.0) 640 if y == 0: 641 return 0.0 642 else: 643 return y / (y + self.gammavariate(beta, 1.0)) 644 645## -------------------- Pareto -------------------- 646 647 def paretovariate(self, alpha): 648 """Pareto distribution. alpha is the shape parameter.""" 649 # Jain, pg. 495 650 651 u = 1.0 - self.random() 652 return 1.0 / u ** (1.0/alpha) 653 654## -------------------- Weibull -------------------- 655 656 def weibullvariate(self, alpha, beta): 657 """Weibull distribution. 658 659 alpha is the scale parameter and beta is the shape parameter. 660 661 """ 662 # Jain, pg. 499; bug fix courtesy Bill Arms 663 664 u = 1.0 - self.random() 665 return alpha * (-_log(u)) ** (1.0/beta) 666 667## --------------- Operating System Random Source ------------------ 668 669class SystemRandom(Random): 670 """Alternate random number generator using sources provided 671 by the operating system (such as /dev/urandom on Unix or 672 CryptGenRandom on Windows). 673 674 Not available on all systems (see os.urandom() for details). 675 """ 676 677 def random(self): 678 """Get the next random number in the range [0.0, 1.0).""" 679 return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF 680 681 def getrandbits(self, k): 682 """getrandbits(k) -> x. Generates an int with k random bits.""" 683 if k <= 0: 684 raise ValueError('number of bits must be greater than zero') 685 if k != int(k): 686 raise TypeError('number of bits should be an integer') 687 numbytes = (k + 7) // 8 # bits / 8 and rounded up 688 x = int.from_bytes(_urandom(numbytes), 'big') 689 return x >> (numbytes * 8 - k) # trim excess bits 690 691 def seed(self, *args, **kwds): 692 "Stub method. Not used for a system random number generator." 693 return None 694 695 def _notimplemented(self, *args, **kwds): 696 "Method should not be called for a system random number generator." 697 raise NotImplementedError('System entropy source does not have state.') 698 getstate = setstate = _notimplemented 699 700## -------------------- test program -------------------- 701 702def _test_generator(n, func, args): 703 import time 704 print(n, 'times', func.__name__) 705 total = 0.0 706 sqsum = 0.0 707 smallest = 1e10 708 largest = -1e10 709 t0 = time.perf_counter() 710 for i in range(n): 711 x = func(*args) 712 total += x 713 sqsum = sqsum + x*x 714 smallest = min(x, smallest) 715 largest = max(x, largest) 716 t1 = time.perf_counter() 717 print(round(t1-t0, 3), 'sec,', end=' ') 718 avg = total/n 719 stddev = _sqrt(sqsum/n - avg*avg) 720 print('avg %g, stddev %g, min %g, max %g\n' % \ 721 (avg, stddev, smallest, largest)) 722 723 724def _test(N=2000): 725 _test_generator(N, random, ()) 726 _test_generator(N, normalvariate, (0.0, 1.0)) 727 _test_generator(N, lognormvariate, (0.0, 1.0)) 728 _test_generator(N, vonmisesvariate, (0.0, 1.0)) 729 _test_generator(N, gammavariate, (0.01, 1.0)) 730 _test_generator(N, gammavariate, (0.1, 1.0)) 731 _test_generator(N, gammavariate, (0.1, 2.0)) 732 _test_generator(N, gammavariate, (0.5, 1.0)) 733 _test_generator(N, gammavariate, (0.9, 1.0)) 734 _test_generator(N, gammavariate, (1.0, 1.0)) 735 _test_generator(N, gammavariate, (2.0, 1.0)) 736 _test_generator(N, gammavariate, (20.0, 1.0)) 737 _test_generator(N, gammavariate, (200.0, 1.0)) 738 _test_generator(N, gauss, (0.0, 1.0)) 739 _test_generator(N, betavariate, (3.0, 3.0)) 740 _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0)) 741 742# Create one instance, seeded from current time, and export its methods 743# as module-level functions. The functions share state across all uses 744#(both in the user's code and in the Python libraries), but that's fine 745# for most programs and is easier for the casual user than making them 746# instantiate their own Random() instance. 747 748_inst = Random() 749seed = _inst.seed 750random = _inst.random 751uniform = _inst.uniform 752triangular = _inst.triangular 753randint = _inst.randint 754choice = _inst.choice 755randrange = _inst.randrange 756sample = _inst.sample 757shuffle = _inst.shuffle 758choices = _inst.choices 759normalvariate = _inst.normalvariate 760lognormvariate = _inst.lognormvariate 761expovariate = _inst.expovariate 762vonmisesvariate = _inst.vonmisesvariate 763gammavariate = _inst.gammavariate 764gauss = _inst.gauss 765betavariate = _inst.betavariate 766paretovariate = _inst.paretovariate 767weibullvariate = _inst.weibullvariate 768getstate = _inst.getstate 769setstate = _inst.setstate 770getrandbits = _inst.getrandbits 771 772if hasattr(_os, "fork"): 773 _os.register_at_fork(after_in_child=_inst.seed) 774 775 776if __name__ == '__main__': 777 _test() 778