Back to index

python3.2  3.2.2
random.py
Go to the documentation of this file.
00001 """Random variable generators.
00002 
00003     integers
00004     --------
00005            uniform within range
00006 
00007     sequences
00008     ---------
00009            pick random element
00010            pick random sample
00011            generate random permutation
00012 
00013     distributions on the real line:
00014     ------------------------------
00015            uniform
00016            triangular
00017            normal (Gaussian)
00018            lognormal
00019            negative exponential
00020            gamma
00021            beta
00022            pareto
00023            Weibull
00024 
00025     distributions on the circle (angles 0 to 2pi)
00026     ---------------------------------------------
00027            circular uniform
00028            von Mises
00029 
00030 General notes on the underlying Mersenne Twister core generator:
00031 
00032 * The period is 2**19937-1.
00033 * It is one of the most extensively tested generators in existence.
00034 * The random() method is implemented in C, executes in a single Python step,
00035   and is, therefore, threadsafe.
00036 
00037 """
00038 
00039 from __future__ import division
00040 from warnings import warn as _warn
00041 from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
00042 from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
00043 from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
00044 from os import urandom as _urandom
00045 from collections import Set as _Set, Sequence as _Sequence
00046 from hashlib import sha512 as _sha512
00047 
00048 __all__ = ["Random","seed","random","uniform","randint","choice","sample",
00049            "randrange","shuffle","normalvariate","lognormvariate",
00050            "expovariate","vonmisesvariate","gammavariate","triangular",
00051            "gauss","betavariate","paretovariate","weibullvariate",
00052            "getstate","setstate", "getrandbits",
00053            "SystemRandom"]
00054 
00055 NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
00056 TWOPI = 2.0*_pi
00057 LOG4 = _log(4.0)
00058 SG_MAGICCONST = 1.0 + _log(4.5)
00059 BPF = 53        # Number of bits in a float
00060 RECIP_BPF = 2**-BPF
00061 
00062 
00063 # Translated by Guido van Rossum from C source provided by
00064 # Adrian Baddeley.  Adapted by Raymond Hettinger for use with
00065 # the Mersenne Twister  and os.urandom() core generators.
00066 
00067 import _random
00068 
00069 class Random(_random.Random):
00070     """Random number generator base class used by bound module functions.
00071 
00072     Used to instantiate instances of Random to get generators that don't
00073     share state.
00074 
00075     Class Random can also be subclassed if you want to use a different basic
00076     generator of your own devising: in that case, override the following
00077     methods:  random(), seed(), getstate(), and setstate().
00078     Optionally, implement a getrandbits() method so that randrange()
00079     can cover arbitrarily large ranges.
00080 
00081     """
00082 
00083     VERSION = 3     # used by getstate/setstate
00084 
00085     def __init__(self, x=None):
00086         """Initialize an instance.
00087 
00088         Optional argument x controls seeding, as for Random.seed().
00089         """
00090 
00091         self.seed(x)
00092         self.gauss_next = None
00093 
00094     def seed(self, a=None, version=2):
00095         """Initialize internal state from hashable object.
00096 
00097         None or no argument seeds from current time or from an operating
00098         system specific randomness source if available.
00099 
00100         For version 2 (the default), all of the bits are used if *a *is a str,
00101         bytes, or bytearray.  For version 1, the hash() of *a* is used instead.
00102 
00103         If *a* is an int, all bits are used.
00104 
00105         """
00106 
00107         if a is None:
00108             try:
00109                 a = int.from_bytes(_urandom(32), 'big')
00110             except NotImplementedError:
00111                 import time
00112                 a = int(time.time() * 256) # use fractional seconds
00113 
00114         if version == 2:
00115             if isinstance(a, (str, bytes, bytearray)):
00116                 if isinstance(a, str):
00117                     a = a.encode()
00118                 a += _sha512(a).digest()
00119                 a = int.from_bytes(a, 'big')
00120 
00121         super().seed(a)
00122         self.gauss_next = None
00123 
00124     def getstate(self):
00125         """Return internal state; can be passed to setstate() later."""
00126         return self.VERSION, super().getstate(), self.gauss_next
00127 
00128     def setstate(self, state):
00129         """Restore internal state from object returned by getstate()."""
00130         version = state[0]
00131         if version == 3:
00132             version, internalstate, self.gauss_next = state
00133             super().setstate(internalstate)
00134         elif version == 2:
00135             version, internalstate, self.gauss_next = state
00136             # In version 2, the state was saved as signed ints, which causes
00137             #   inconsistencies between 32/64-bit systems. The state is
00138             #   really unsigned 32-bit ints, so we convert negative ints from
00139             #   version 2 to positive longs for version 3.
00140             try:
00141                 internalstate = tuple(x % (2**32) for x in internalstate)
00142             except ValueError as e:
00143                 raise TypeError from e
00144             super().setstate(internalstate)
00145         else:
00146             raise ValueError("state with version %s passed to "
00147                              "Random.setstate() of version %s" %
00148                              (version, self.VERSION))
00149 
00150 ## ---- Methods below this point do not need to be overridden when
00151 ## ---- subclassing for the purpose of using a different core generator.
00152 
00153 ## -------------------- pickle support  -------------------
00154 
00155     def __getstate__(self): # for pickle
00156         return self.getstate()
00157 
00158     def __setstate__(self, state):  # for pickle
00159         self.setstate(state)
00160 
00161     def __reduce__(self):
00162         return self.__class__, (), self.getstate()
00163 
00164 ## -------------------- integer methods  -------------------
00165 
00166     def randrange(self, start, stop=None, step=1, int=int):
00167         """Choose a random item from range(start, stop[, step]).
00168 
00169         This fixes the problem with randint() which includes the
00170         endpoint; in Python this is usually not what you want.
00171 
00172         Do not supply the 'int' argument.
00173         """
00174 
00175         # This code is a bit messy to make it fast for the
00176         # common case while still doing adequate error checking.
00177         istart = int(start)
00178         if istart != start:
00179             raise ValueError("non-integer arg 1 for randrange()")
00180         if stop is None:
00181             if istart > 0:
00182                 return self._randbelow(istart)
00183             raise ValueError("empty range for randrange()")
00184 
00185         # stop argument supplied.
00186         istop = int(stop)
00187         if istop != stop:
00188             raise ValueError("non-integer stop for randrange()")
00189         width = istop - istart
00190         if step == 1 and width > 0:
00191             return istart + self._randbelow(width)
00192         if step == 1:
00193             raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
00194 
00195         # Non-unit step argument supplied.
00196         istep = int(step)
00197         if istep != step:
00198             raise ValueError("non-integer step for randrange()")
00199         if istep > 0:
00200             n = (width + istep - 1) // istep
00201         elif istep < 0:
00202             n = (width + istep + 1) // istep
00203         else:
00204             raise ValueError("zero step for randrange()")
00205 
00206         if n <= 0:
00207             raise ValueError("empty range for randrange()")
00208 
00209         return istart + istep*self._randbelow(n)
00210 
00211     def randint(self, a, b):
00212         """Return random integer in range [a, b], including both end points.
00213         """
00214 
00215         return self.randrange(a, b+1)
00216 
00217     def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type,
00218                    Method=_MethodType, BuiltinMethod=_BuiltinMethodType):
00219         "Return a random int in the range [0,n).  Raises ValueError if n==0."
00220 
00221         getrandbits = self.getrandbits
00222         # Only call self.getrandbits if the original random() builtin method
00223         # has not been overridden or if a new getrandbits() was supplied.
00224         if type(self.random) is BuiltinMethod or type(getrandbits) is Method:
00225             k = n.bit_length()  # don't use (n-1) here because n can be 1
00226             r = getrandbits(k)          # 0 <= r < 2**k
00227             while r >= n:
00228                 r = getrandbits(k)
00229             return r
00230         # There's an overriden random() method but no new getrandbits() method,
00231         # so we can only use random() from here.
00232         random = self.random
00233         if n >= maxsize:
00234             _warn("Underlying random() generator does not supply \n"
00235                 "enough bits to choose from a population range this large.\n"
00236                 "To remove the range limitation, add a getrandbits() method.")
00237             return int(random() * n)
00238         rem = maxsize % n
00239         limit = (maxsize - rem) / maxsize   # int(limit * maxsize) % n == 0
00240         r = random()
00241         while r >= limit:
00242             r = random()
00243         return int(r*maxsize) % n
00244 
00245 ## -------------------- sequence methods  -------------------
00246 
00247     def choice(self, seq):
00248         """Choose a random element from a non-empty sequence."""
00249         try:
00250             i = self._randbelow(len(seq))
00251         except ValueError:
00252             raise IndexError('Cannot choose from an empty sequence')
00253         return seq[i]
00254 
00255     def shuffle(self, x, random=None, int=int):
00256         """x, random=random.random -> shuffle list x in place; return None.
00257 
00258         Optional arg random is a 0-argument function returning a random
00259         float in [0.0, 1.0); by default, the standard random.random.
00260         """
00261 
00262         randbelow = self._randbelow
00263         for i in reversed(range(1, len(x))):
00264             # pick an element in x[:i+1] with which to exchange x[i]
00265             j = randbelow(i+1) if random is None else int(random() * (i+1))
00266             x[i], x[j] = x[j], x[i]
00267 
00268     def sample(self, population, k):
00269         """Chooses k unique random elements from a population sequence or set.
00270 
00271         Returns a new list containing elements from the population while
00272         leaving the original population unchanged.  The resulting list is
00273         in selection order so that all sub-slices will also be valid random
00274         samples.  This allows raffle winners (the sample) to be partitioned
00275         into grand prize and second place winners (the subslices).
00276 
00277         Members of the population need not be hashable or unique.  If the
00278         population contains repeats, then each occurrence is a possible
00279         selection in the sample.
00280 
00281         To choose a sample in a range of integers, use range as an argument.
00282         This is especially fast and space efficient for sampling from a
00283         large population:   sample(range(10000000), 60)
00284         """
00285 
00286         # Sampling without replacement entails tracking either potential
00287         # selections (the pool) in a list or previous selections in a set.
00288 
00289         # When the number of selections is small compared to the
00290         # population, then tracking selections is efficient, requiring
00291         # only a small set and an occasional reselection.  For
00292         # a larger number of selections, the pool tracking method is
00293         # preferred since the list takes less space than the
00294         # set and it doesn't suffer from frequent reselections.
00295 
00296         if isinstance(population, _Set):
00297             population = tuple(population)
00298         if not isinstance(population, _Sequence):
00299             raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")
00300         randbelow = self._randbelow
00301         n = len(population)
00302         if not 0 <= k <= n:
00303             raise ValueError("Sample larger than population")
00304         result = [None] * k
00305         setsize = 21        # size of a small set minus size of an empty list
00306         if k > 5:
00307             setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
00308         if n <= setsize:
00309             # An n-length list is smaller than a k-length set
00310             pool = list(population)
00311             for i in range(k):         # invariant:  non-selected at [0,n-i)
00312                 j = randbelow(n-i)
00313                 result[i] = pool[j]
00314                 pool[j] = pool[n-i-1]   # move non-selected item into vacancy
00315         else:
00316             selected = set()
00317             selected_add = selected.add
00318             for i in range(k):
00319                 j = randbelow(n)
00320                 while j in selected:
00321                     j = randbelow(n)
00322                 selected_add(j)
00323                 result[i] = population[j]
00324         return result
00325 
00326 ## -------------------- real-valued distributions  -------------------
00327 
00328 ## -------------------- uniform distribution -------------------
00329 
00330     def uniform(self, a, b):
00331         "Get a random number in the range [a, b) or [a, b] depending on rounding."
00332         return a + (b-a) * self.random()
00333 
00334 ## -------------------- triangular --------------------
00335 
00336     def triangular(self, low=0.0, high=1.0, mode=None):
00337         """Triangular distribution.
00338 
00339         Continuous distribution bounded by given lower and upper limits,
00340         and having a given mode value in-between.
00341 
00342         http://en.wikipedia.org/wiki/Triangular_distribution
00343 
00344         """
00345         u = self.random()
00346         c = 0.5 if mode is None else (mode - low) / (high - low)
00347         if u > c:
00348             u = 1.0 - u
00349             c = 1.0 - c
00350             low, high = high, low
00351         return low + (high - low) * (u * c) ** 0.5
00352 
00353 ## -------------------- normal distribution --------------------
00354 
00355     def normalvariate(self, mu, sigma):
00356         """Normal distribution.
00357 
00358         mu is the mean, and sigma is the standard deviation.
00359 
00360         """
00361         # mu = mean, sigma = standard deviation
00362 
00363         # Uses Kinderman and Monahan method. Reference: Kinderman,
00364         # A.J. and Monahan, J.F., "Computer generation of random
00365         # variables using the ratio of uniform deviates", ACM Trans
00366         # Math Software, 3, (1977), pp257-260.
00367 
00368         random = self.random
00369         while 1:
00370             u1 = random()
00371             u2 = 1.0 - random()
00372             z = NV_MAGICCONST*(u1-0.5)/u2
00373             zz = z*z/4.0
00374             if zz <= -_log(u2):
00375                 break
00376         return mu + z*sigma
00377 
00378 ## -------------------- lognormal distribution --------------------
00379 
00380     def lognormvariate(self, mu, sigma):
00381         """Log normal distribution.
00382 
00383         If you take the natural logarithm of this distribution, you'll get a
00384         normal distribution with mean mu and standard deviation sigma.
00385         mu can have any value, and sigma must be greater than zero.
00386 
00387         """
00388         return _exp(self.normalvariate(mu, sigma))
00389 
00390 ## -------------------- exponential distribution --------------------
00391 
00392     def expovariate(self, lambd):
00393         """Exponential distribution.
00394 
00395         lambd is 1.0 divided by the desired mean.  It should be
00396         nonzero.  (The parameter would be called "lambda", but that is
00397         a reserved word in Python.)  Returned values range from 0 to
00398         positive infinity if lambd is positive, and from negative
00399         infinity to 0 if lambd is negative.
00400 
00401         """
00402         # lambd: rate lambd = 1/mean
00403         # ('lambda' is a Python reserved word)
00404 
00405         # we use 1-random() instead of random() to preclude the
00406         # possibility of taking the log of zero.
00407         return -_log(1.0 - self.random())/lambd
00408 
00409 ## -------------------- von Mises distribution --------------------
00410 
00411     def vonmisesvariate(self, mu, kappa):
00412         """Circular data distribution.
00413 
00414         mu is the mean angle, expressed in radians between 0 and 2*pi, and
00415         kappa is the concentration parameter, which must be greater than or
00416         equal to zero.  If kappa is equal to zero, this distribution reduces
00417         to a uniform random angle over the range 0 to 2*pi.
00418 
00419         """
00420         # mu:    mean angle (in radians between 0 and 2*pi)
00421         # kappa: concentration parameter kappa (>= 0)
00422         # if kappa = 0 generate uniform random angle
00423 
00424         # Based upon an algorithm published in: Fisher, N.I.,
00425         # "Statistical Analysis of Circular Data", Cambridge
00426         # University Press, 1993.
00427 
00428         # Thanks to Magnus Kessler for a correction to the
00429         # implementation of step 4.
00430 
00431         random = self.random
00432         if kappa <= 1e-6:
00433             return TWOPI * random()
00434 
00435         a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
00436         b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
00437         r = (1.0 + b * b)/(2.0 * b)
00438 
00439         while 1:
00440             u1 = random()
00441 
00442             z = _cos(_pi * u1)
00443             f = (1.0 + r * z)/(r + z)
00444             c = kappa * (r - f)
00445 
00446             u2 = random()
00447 
00448             if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c):
00449                 break
00450 
00451         u3 = random()
00452         if u3 > 0.5:
00453             theta = (mu % TWOPI) + _acos(f)
00454         else:
00455             theta = (mu % TWOPI) - _acos(f)
00456 
00457         return theta
00458 
00459 ## -------------------- gamma distribution --------------------
00460 
00461     def gammavariate(self, alpha, beta):
00462         """Gamma distribution.  Not the gamma function!
00463 
00464         Conditions on the parameters are alpha > 0 and beta > 0.
00465 
00466         The probability distribution function is:
00467 
00468                     x ** (alpha - 1) * math.exp(-x / beta)
00469           pdf(x) =  --------------------------------------
00470                       math.gamma(alpha) * beta ** alpha
00471 
00472         """
00473 
00474         # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
00475 
00476         # Warning: a few older sources define the gamma distribution in terms
00477         # of alpha > -1.0
00478         if alpha <= 0.0 or beta <= 0.0:
00479             raise ValueError('gammavariate: alpha and beta must be > 0.0')
00480 
00481         random = self.random
00482         if alpha > 1.0:
00483 
00484             # Uses R.C.H. Cheng, "The generation of Gamma
00485             # variables with non-integral shape parameters",
00486             # Applied Statistics, (1977), 26, No. 1, p71-74
00487 
00488             ainv = _sqrt(2.0 * alpha - 1.0)
00489             bbb = alpha - LOG4
00490             ccc = alpha + ainv
00491 
00492             while 1:
00493                 u1 = random()
00494                 if not 1e-7 < u1 < .9999999:
00495                     continue
00496                 u2 = 1.0 - random()
00497                 v = _log(u1/(1.0-u1))/ainv
00498                 x = alpha*_exp(v)
00499                 z = u1*u1*u2
00500                 r = bbb+ccc*v-x
00501                 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
00502                     return x * beta
00503 
00504         elif alpha == 1.0:
00505             # expovariate(1)
00506             u = random()
00507             while u <= 1e-7:
00508                 u = random()
00509             return -_log(u) * beta
00510 
00511         else:   # alpha is between 0 and 1 (exclusive)
00512 
00513             # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
00514 
00515             while 1:
00516                 u = random()
00517                 b = (_e + alpha)/_e
00518                 p = b*u
00519                 if p <= 1.0:
00520                     x = p ** (1.0/alpha)
00521                 else:
00522                     x = -_log((b-p)/alpha)
00523                 u1 = random()
00524                 if p > 1.0:
00525                     if u1 <= x ** (alpha - 1.0):
00526                         break
00527                 elif u1 <= _exp(-x):
00528                     break
00529             return x * beta
00530 
00531 ## -------------------- Gauss (faster alternative) --------------------
00532 
00533     def gauss(self, mu, sigma):
00534         """Gaussian distribution.
00535 
00536         mu is the mean, and sigma is the standard deviation.  This is
00537         slightly faster than the normalvariate() function.
00538 
00539         Not thread-safe without a lock around calls.
00540 
00541         """
00542 
00543         # When x and y are two variables from [0, 1), uniformly
00544         # distributed, then
00545         #
00546         #    cos(2*pi*x)*sqrt(-2*log(1-y))
00547         #    sin(2*pi*x)*sqrt(-2*log(1-y))
00548         #
00549         # are two *independent* variables with normal distribution
00550         # (mu = 0, sigma = 1).
00551         # (Lambert Meertens)
00552         # (corrected version; bug discovered by Mike Miller, fixed by LM)
00553 
00554         # Multithreading note: When two threads call this function
00555         # simultaneously, it is possible that they will receive the
00556         # same return value.  The window is very small though.  To
00557         # avoid this, you have to use a lock around all calls.  (I
00558         # didn't want to slow this down in the serial case by using a
00559         # lock here.)
00560 
00561         random = self.random
00562         z = self.gauss_next
00563         self.gauss_next = None
00564         if z is None:
00565             x2pi = random() * TWOPI
00566             g2rad = _sqrt(-2.0 * _log(1.0 - random()))
00567             z = _cos(x2pi) * g2rad
00568             self.gauss_next = _sin(x2pi) * g2rad
00569 
00570         return mu + z*sigma
00571 
00572 ## -------------------- beta --------------------
00573 ## See
00574 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
00575 ## for Ivan Frohne's insightful analysis of why the original implementation:
00576 ##
00577 ##    def betavariate(self, alpha, beta):
00578 ##        # Discrete Event Simulation in C, pp 87-88.
00579 ##
00580 ##        y = self.expovariate(alpha)
00581 ##        z = self.expovariate(1.0/beta)
00582 ##        return z/(y+z)
00583 ##
00584 ## was dead wrong, and how it probably got that way.
00585 
00586     def betavariate(self, alpha, beta):
00587         """Beta distribution.
00588 
00589         Conditions on the parameters are alpha > 0 and beta > 0.
00590         Returned values range between 0 and 1.
00591 
00592         """
00593 
00594         # This version due to Janne Sinkkonen, and matches all the std
00595         # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
00596         y = self.gammavariate(alpha, 1.)
00597         if y == 0:
00598             return 0.0
00599         else:
00600             return y / (y + self.gammavariate(beta, 1.))
00601 
00602 ## -------------------- Pareto --------------------
00603 
00604     def paretovariate(self, alpha):
00605         """Pareto distribution.  alpha is the shape parameter."""
00606         # Jain, pg. 495
00607 
00608         u = 1.0 - self.random()
00609         return 1.0 / u ** (1.0/alpha)
00610 
00611 ## -------------------- Weibull --------------------
00612 
00613     def weibullvariate(self, alpha, beta):
00614         """Weibull distribution.
00615 
00616         alpha is the scale parameter and beta is the shape parameter.
00617 
00618         """
00619         # Jain, pg. 499; bug fix courtesy Bill Arms
00620 
00621         u = 1.0 - self.random()
00622         return alpha * (-_log(u)) ** (1.0/beta)
00623 
00624 ## --------------- Operating System Random Source  ------------------
00625 
00626 class SystemRandom(Random):
00627     """Alternate random number generator using sources provided
00628     by the operating system (such as /dev/urandom on Unix or
00629     CryptGenRandom on Windows).
00630 
00631      Not available on all systems (see os.urandom() for details).
00632     """
00633 
00634     def random(self):
00635         """Get the next random number in the range [0.0, 1.0)."""
00636         return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
00637 
00638     def getrandbits(self, k):
00639         """getrandbits(k) -> x.  Generates a long int with k random bits."""
00640         if k <= 0:
00641             raise ValueError('number of bits must be greater than zero')
00642         if k != int(k):
00643             raise TypeError('number of bits should be an integer')
00644         numbytes = (k + 7) // 8                       # bits / 8 and rounded up
00645         x = int.from_bytes(_urandom(numbytes), 'big')
00646         return x >> (numbytes * 8 - k)                # trim excess bits
00647 
00648     def seed(self, *args, **kwds):
00649         "Stub method.  Not used for a system random number generator."
00650         return None
00651 
00652     def _notimplemented(self, *args, **kwds):
00653         "Method should not be called for a system random number generator."
00654         raise NotImplementedError('System entropy source does not have state.')
00655     getstate = setstate = _notimplemented
00656 
00657 ## -------------------- test program --------------------
00658 
00659 def _test_generator(n, func, args):
00660     import time
00661     print(n, 'times', func.__name__)
00662     total = 0.0
00663     sqsum = 0.0
00664     smallest = 1e10
00665     largest = -1e10
00666     t0 = time.time()
00667     for i in range(n):
00668         x = func(*args)
00669         total += x
00670         sqsum = sqsum + x*x
00671         smallest = min(x, smallest)
00672         largest = max(x, largest)
00673     t1 = time.time()
00674     print(round(t1-t0, 3), 'sec,', end=' ')
00675     avg = total/n
00676     stddev = _sqrt(sqsum/n - avg*avg)
00677     print('avg %g, stddev %g, min %g, max %g' % \
00678               (avg, stddev, smallest, largest))
00679 
00680 
00681 def _test(N=2000):
00682     _test_generator(N, random, ())
00683     _test_generator(N, normalvariate, (0.0, 1.0))
00684     _test_generator(N, lognormvariate, (0.0, 1.0))
00685     _test_generator(N, vonmisesvariate, (0.0, 1.0))
00686     _test_generator(N, gammavariate, (0.01, 1.0))
00687     _test_generator(N, gammavariate, (0.1, 1.0))
00688     _test_generator(N, gammavariate, (0.1, 2.0))
00689     _test_generator(N, gammavariate, (0.5, 1.0))
00690     _test_generator(N, gammavariate, (0.9, 1.0))
00691     _test_generator(N, gammavariate, (1.0, 1.0))
00692     _test_generator(N, gammavariate, (2.0, 1.0))
00693     _test_generator(N, gammavariate, (20.0, 1.0))
00694     _test_generator(N, gammavariate, (200.0, 1.0))
00695     _test_generator(N, gauss, (0.0, 1.0))
00696     _test_generator(N, betavariate, (3.0, 3.0))
00697     _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
00698 
00699 # Create one instance, seeded from current time, and export its methods
00700 # as module-level functions.  The functions share state across all uses
00701 #(both in the user's code and in the Python libraries), but that's fine
00702 # for most programs and is easier for the casual user than making them
00703 # instantiate their own Random() instance.
00704 
00705 _inst = Random()
00706 seed = _inst.seed
00707 random = _inst.random
00708 uniform = _inst.uniform
00709 triangular = _inst.triangular
00710 randint = _inst.randint
00711 choice = _inst.choice
00712 randrange = _inst.randrange
00713 sample = _inst.sample
00714 shuffle = _inst.shuffle
00715 normalvariate = _inst.normalvariate
00716 lognormvariate = _inst.lognormvariate
00717 expovariate = _inst.expovariate
00718 vonmisesvariate = _inst.vonmisesvariate
00719 gammavariate = _inst.gammavariate
00720 gauss = _inst.gauss
00721 betavariate = _inst.betavariate
00722 paretovariate = _inst.paretovariate
00723 weibullvariate = _inst.weibullvariate
00724 getstate = _inst.getstate
00725 setstate = _inst.setstate
00726 getrandbits = _inst.getrandbits
00727 
00728 if __name__ == '__main__':
00729     _test()