[Python-checkins] Minor code clean-ups (GH-20838)

Raymond Hettinger webhook-mailer at python.org
Sat Jun 13 12:46:52 EDT 2020


https://github.com/python/cpython/commit/9db5b8d44858d134b0b225df481b784d7511dbd4
commit: 9db5b8d44858d134b0b225df481b784d7511dbd4
branch: master
author: Raymond Hettinger <rhettinger at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-06-13T09:46:47-07:00
summary:

Minor code clean-ups (GH-20838)

files:
M Lib/random.py

diff --git a/Lib/random.py b/Lib/random.py
index 75f70d5d699ed..02a56c6935b89 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -39,7 +39,7 @@
 
 from warnings import warn as _warn
 from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
-from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
+from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin, tau as TWOPI
 from os import urandom as _urandom
 from _collections_abc import Set as _Set, Sequence as _Sequence
 from itertools import accumulate as _accumulate, repeat as _repeat
@@ -54,19 +54,38 @@
     from hashlib import sha512 as _sha512
 
 
-__all__ = ["Random","seed","random","uniform","randint","choice","sample",
-           "randrange","shuffle","normalvariate","lognormvariate",
-           "expovariate","vonmisesvariate","gammavariate","triangular",
-           "gauss","betavariate","paretovariate","weibullvariate",
-           "getstate","setstate", "getrandbits", "choices",
-           "SystemRandom"]
-
-NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
-TWOPI = 2.0*_pi
+__all__ = [
+    "Random",
+    "SystemRandom",
+    "betavariate",
+    "choice",
+    "choices",
+    "expovariate",
+    "gammavariate",
+    "gauss",
+    "getrandbits",
+    "getstate",
+    "lognormvariate",
+    "normalvariate",
+    "paretovariate",
+    "randint",
+    "random",
+    "randrange",
+    "sample",
+    "seed",
+    "setstate",
+    "shuffle",
+    "triangular",
+    "uniform",
+    "vonmisesvariate",
+    "weibullvariate",
+]
+
+NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
 LOG4 = _log(4.0)
 SG_MAGICCONST = 1.0 + _log(4.5)
 BPF = 53        # Number of bits in a float
-RECIP_BPF = 2**-BPF
+RECIP_BPF = 2 ** -BPF
 
 
 # Translated by Guido van Rossum from C source provided by
@@ -75,6 +94,7 @@
 
 import _random
 
+
 class Random(_random.Random):
     """Random number generator base class used by bound module functions.
 
@@ -180,7 +200,7 @@ def setstate(self, state):
             #   really unsigned 32-bit ints, so we convert negative ints from
             #   version 2 to positive longs for version 3.
             try:
-                internalstate = tuple(x % (2**32) for x in internalstate)
+                internalstate = tuple(x % (2 ** 32) for x in internalstate)
             except ValueError as e:
                 raise TypeError from e
             super().setstate(internalstate)
@@ -189,21 +209,21 @@ def setstate(self, state):
                              "Random.setstate() of version %s" %
                              (version, self.VERSION))
 
-## ---- Methods below this point do not need to be overridden when
-## ---- subclassing for the purpose of using a different core generator.
+    ## ---- Methods below this point do not need to be overridden when
+    ## ---- subclassing for the purpose of using a different core generator.
 
-## -------------------- bytes methods ---------------------
+    ## -------------------- bytes methods ---------------------
 
     def randbytes(self, n):
         """Generate n random bytes."""
         return self.getrandbits(n * 8).to_bytes(n, 'little')
 
-## -------------------- pickle support  -------------------
+    ## -------------------- pickle support  -------------------
 
     # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
     # longer called; we leave it here because it has been here since random was
     # rewritten back in 2001 and why risk breaking something.
-    def __getstate__(self): # for pickle
+    def __getstate__(self):  # for pickle
         return self.getstate()
 
     def __setstate__(self, state):  # for pickle
@@ -212,7 +232,7 @@ def __setstate__(self, state):  # for pickle
     def __reduce__(self):
         return self.__class__, (), self.getstate()
 
-## -------------------- integer methods  -------------------
+    ## -------------------- integer methods  -------------------
 
     def randrange(self, start, stop=None, step=1, _int=int):
         """Choose a random item from range(start, stop[, step]).
@@ -256,7 +276,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
         if n <= 0:
             raise ValueError("empty range for randrange()")
 
-        return istart + istep*self._randbelow(n)
+        return istart + istep * self._randbelow(n)
 
     def randint(self, a, b):
         """Return random integer in range [a, b], including both end points.
@@ -271,7 +291,7 @@ def _randbelow_with_getrandbits(self, n):
             return 0
         getrandbits = self.getrandbits
         k = n.bit_length()  # don't use (n-1) here because n can be 1
-        r = getrandbits(k)          # 0 <= r < 2**k
+        r = getrandbits(k)  # 0 <= r < 2**k
         while r >= n:
             r = getrandbits(k)
         return r
@@ -295,15 +315,16 @@ def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF):
         r = random()
         while r >= limit:
             r = random()
-        return int(r*maxsize) % n
+        return int(r * maxsize) % n
 
     _randbelow = _randbelow_with_getrandbits
 
-## -------------------- sequence methods  -------------------
+    ## -------------------- sequence methods  -------------------
 
     def choice(self, seq):
         """Choose a random element from a non-empty sequence."""
-        return seq[self._randbelow(len(seq))] # raises IndexError if seq is empty
+        # raises IndexError if seq is empty
+        return seq[self._randbelow(len(seq))]
 
     def shuffle(self, x, random=None):
         """Shuffle list x in place, and return None.
@@ -318,7 +339,7 @@ def shuffle(self, x, random=None):
             randbelow = self._randbelow
             for i in reversed(range(1, len(x))):
                 # pick an element in x[:i+1] with which to exchange x[i]
-                j = randbelow(i+1)
+                j = randbelow(i + 1)
                 x[i], x[j] = x[j], x[i]
         else:
             _warn('The *random* parameter to shuffle() has been deprecated\n'
@@ -328,7 +349,7 @@ def shuffle(self, x, random=None):
             _int = int
             for i in reversed(range(1, len(x))):
                 # pick an element in x[:i+1] with which to exchange x[i]
-                j = _int(random() * (i+1))
+                j = _int(random() * (i + 1))
                 x[i], x[j] = x[j], x[i]
 
     def sample(self, population, k, *, counts=None):
@@ -410,14 +431,15 @@ def sample(self, population, k, *, counts=None):
         result = [None] * k
         setsize = 21        # size of a small set minus size of an empty list
         if k > 5:
-            setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
+            setsize += 4 ** _ceil(_log(k * 3, 4))  # table size for big sets
         if n <= setsize:
-            # An n-length list is smaller than a k-length set
+            # An n-length list is smaller than a k-length set.
+            # Invariant:  non-selected at pool[0 : n-i]
             pool = list(population)
-            for i in range(k):         # invariant:  non-selected at [0,n-i)
-                j = randbelow(n-i)
+            for i in range(k):
+                j = randbelow(n - i)
                 result[i] = pool[j]
-                pool[j] = pool[n-i-1]   # move non-selected item into vacancy
+                pool[j] = pool[n - i - 1]  # move non-selected item into vacancy
         else:
             selected = set()
             selected_add = selected.add
@@ -456,15 +478,15 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1):
         return [population[bisect(cum_weights, random() * total, 0, hi)]
                 for i in _repeat(None, k)]
 
-## -------------------- real-valued distributions  -------------------
+    ## -------------------- real-valued distributions  -------------------
 
-## -------------------- uniform distribution -------------------
+    ## -------------------- uniform distribution -------------------
 
     def uniform(self, a, b):
         "Get a random number in the range [a, b) or [a, b] depending on rounding."
-        return a + (b-a) * self.random()
+        return a + (b - a) * self.random()
 
-## -------------------- triangular --------------------
+    ## -------------------- triangular --------------------
 
     def triangular(self, low=0.0, high=1.0, mode=None):
         """Triangular distribution.
@@ -486,7 +508,7 @@ def triangular(self, low=0.0, high=1.0, mode=None):
             low, high = high, low
         return low + (high - low) * _sqrt(u * c)
 
-## -------------------- normal distribution --------------------
+    ## -------------------- normal distribution --------------------
 
     def normalvariate(self, mu, sigma):
         """Normal distribution.
@@ -502,16 +524,16 @@ def normalvariate(self, mu, sigma):
         # Math Software, 3, (1977), pp257-260.
 
         random = self.random
-        while 1:
+        while True:
             u1 = random()
             u2 = 1.0 - random()
-            z = NV_MAGICCONST*(u1-0.5)/u2
-            zz = z*z/4.0
+            z = NV_MAGICCONST * (u1 - 0.5) / u2
+            zz = z * z / 4.0
             if zz <= -_log(u2):
                 break
-        return mu + z*sigma
+        return mu + z * sigma
 
-## -------------------- lognormal distribution --------------------
+    ## -------------------- lognormal distribution --------------------
 
     def lognormvariate(self, mu, sigma):
         """Log normal distribution.
@@ -523,7 +545,7 @@ def lognormvariate(self, mu, sigma):
         """
         return _exp(self.normalvariate(mu, sigma))
 
-## -------------------- exponential distribution --------------------
+    ## -------------------- exponential distribution --------------------
 
     def expovariate(self, lambd):
         """Exponential distribution.
@@ -540,9 +562,9 @@ def expovariate(self, lambd):
 
         # we use 1-random() instead of random() to preclude the
         # possibility of taking the log of zero.
-        return -_log(1.0 - self.random())/lambd
+        return -_log(1.0 - self.random()) / lambd
 
-## -------------------- von Mises distribution --------------------
+    ## -------------------- von Mises distribution --------------------
 
     def vonmisesvariate(self, mu, kappa):
         """Circular data distribution.
@@ -571,7 +593,7 @@ def vonmisesvariate(self, mu, kappa):
         s = 0.5 / kappa
         r = s + _sqrt(1.0 + s * s)
 
-        while 1:
+        while True:
             u1 = random()
             z = _cos(_pi * u1)
 
@@ -590,7 +612,7 @@ def vonmisesvariate(self, mu, kappa):
 
         return theta
 
-## -------------------- gamma distribution --------------------
+    ## -------------------- gamma distribution --------------------
 
     def gammavariate(self, alpha, beta):
         """Gamma distribution.  Not the gamma function!
@@ -625,32 +647,31 @@ def gammavariate(self, alpha, beta):
 
             while 1:
                 u1 = random()
-                if not 1e-7 < u1 < .9999999:
+                if not 1e-7 < u1 < 0.9999999:
                     continue
                 u2 = 1.0 - random()
-                v = _log(u1/(1.0-u1))/ainv
-                x = alpha*_exp(v)
-                z = u1*u1*u2
-                r = bbb+ccc*v-x
-                if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
+                v = _log(u1 / (1.0 - u1)) / ainv
+                x = alpha * _exp(v)
+                z = u1 * u1 * u2
+                r = bbb + ccc * v - x
+                if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z):
                     return x * beta
 
         elif alpha == 1.0:
             # expovariate(1/beta)
             return -_log(1.0 - random()) * beta
 
-        else:   # alpha is between 0 and 1 (exclusive)
-
+        else:
+            # alpha is between 0 and 1 (exclusive)
             # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
-
-            while 1:
+            while True:
                 u = random()
-                b = (_e + alpha)/_e
-                p = b*u
+                b = (_e + alpha) / _e
+                p = b * u
                 if p <= 1.0:
-                    x = p ** (1.0/alpha)
+                    x = p ** (1.0 / alpha)
                 else:
-                    x = -_log((b-p)/alpha)
+                    x = -_log((b - p) / alpha)
                 u1 = random()
                 if p > 1.0:
                     if u1 <= x ** (alpha - 1.0):
@@ -659,7 +680,7 @@ def gammavariate(self, alpha, beta):
                     break
             return x * beta
 
-## -------------------- Gauss (faster alternative) --------------------
+    ## -------------------- Gauss (faster alternative) --------------------
 
     def gauss(self, mu, sigma):
         """Gaussian distribution.
@@ -698,21 +719,21 @@ def gauss(self, mu, sigma):
             z = _cos(x2pi) * g2rad
             self.gauss_next = _sin(x2pi) * g2rad
 
-        return mu + z*sigma
-
-## -------------------- beta --------------------
-## See
-## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
-## for Ivan Frohne's insightful analysis of why the original implementation:
-##
-##    def betavariate(self, alpha, beta):
-##        # Discrete Event Simulation in C, pp 87-88.
-##
-##        y = self.expovariate(alpha)
-##        z = self.expovariate(1.0/beta)
-##        return z/(y+z)
-##
-## was dead wrong, and how it probably got that way.
+        return mu + z * sigma
+
+    ## -------------------- beta --------------------
+    ## See
+    ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
+    ## for Ivan Frohne's insightful analysis of why the original implementation:
+    ##
+    ##    def betavariate(self, alpha, beta):
+    ##        # Discrete Event Simulation in C, pp 87-88.
+    ##
+    ##        y = self.expovariate(alpha)
+    ##        z = self.expovariate(1.0/beta)
+    ##        return z/(y+z)
+    ##
+    ## was dead wrong, and how it probably got that way.
 
     def betavariate(self, alpha, beta):
         """Beta distribution.
@@ -725,21 +746,20 @@ def betavariate(self, alpha, beta):
         # This version due to Janne Sinkkonen, and matches all the std
         # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
         y = self.gammavariate(alpha, 1.0)
-        if y == 0:
-            return 0.0
-        else:
+        if y:
             return y / (y + self.gammavariate(beta, 1.0))
+        return 0.0
 
-## -------------------- Pareto --------------------
+    ## -------------------- Pareto --------------------
 
     def paretovariate(self, alpha):
         """Pareto distribution.  alpha is the shape parameter."""
         # Jain, pg. 495
 
         u = 1.0 - self.random()
-        return 1.0 / u ** (1.0/alpha)
+        return 1.0 / u ** (1.0 / alpha)
 
-## -------------------- Weibull --------------------
+    ## -------------------- Weibull --------------------
 
     def weibullvariate(self, alpha, beta):
         """Weibull distribution.
@@ -750,7 +770,8 @@ def weibullvariate(self, alpha, beta):
         # Jain, pg. 499; bug fix courtesy Bill Arms
 
         u = 1.0 - self.random()
-        return alpha * (-_log(u)) ** (1.0/beta)
+        return alpha * (-_log(u)) ** (1.0 / beta)
+
 
 ## --------------- Operating System Random Source  ------------------
 
@@ -789,6 +810,7 @@ def _notimplemented(self, *args, **kwds):
         raise NotImplementedError('System entropy source does not have state.')
     getstate = setstate = _notimplemented
 
+
 ## -------------------- test program --------------------
 
 def _test_generator(n, func, args):
@@ -806,11 +828,10 @@ def _test_generator(n, func, args):
         smallest = min(x, smallest)
         largest = max(x, largest)
     t1 = time.perf_counter()
-    print(round(t1-t0, 3), 'sec,', end=' ')
-    avg = total/n
-    stddev = _sqrt(sqsum/n - avg*avg)
-    print('avg %g, stddev %g, min %g, max %g\n' % \
-              (avg, stddev, smallest, largest))
+    print(round(t1 - t0, 3), 'sec,', end=' ')
+    avg = total / n
+    stddev = _sqrt(sqsum / n - avg * avg)
+    print('avg %g, stddev %g, min %g, max %g\n' % (avg, stddev, smallest, largest))
 
 
 def _test(N=2000):
@@ -829,11 +850,11 @@ def _test(N=2000):
     _test_generator(N, gammavariate, (200.0, 1.0))
     _test_generator(N, gauss, (0.0, 1.0))
     _test_generator(N, betavariate, (3.0, 3.0))
-    _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0))
+    _test_generator(N, triangular, (0.0, 1.0, 1.0 / 3.0))
 
 # Create one instance, seeded from current time, and export its methods
 # as module-level functions.  The functions share state across all uses
-#(both in the user's code and in the Python libraries), but that's fine
+# (both in the user's code and in the Python libraries), but that's fine
 # for most programs and is easier for the casual user than making them
 # instantiate their own Random() instance.
 



More information about the Python-checkins mailing list