[Python-checkins] Small clean-ups for the random module (GH-21038)

Raymond Hettinger webhook-mailer at python.org
Mon Jun 22 22:39:08 EDT 2020


https://github.com/python/cpython/commit/26a1ad1c24717990265b71ed093d691500d6301c
commit: 26a1ad1c24717990265b71ed093d691500d6301c
branch: master
author: Raymond Hettinger <rhettinger at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-06-22T19:38:59-07:00
summary:

Small clean-ups for the random module (GH-21038)

files:
M Lib/random.py

diff --git a/Lib/random.py b/Lib/random.py
index 02a56c6935b89..ae7b5cf4e72e8 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -39,7 +39,8 @@
 
 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, tau as TWOPI
+from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
+from math import tau as TWOPI, floor as _floor
 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
@@ -234,7 +235,7 @@ def __reduce__(self):
 
     ## -------------------- integer methods  -------------------
 
-    def randrange(self, start, stop=None, step=1, _int=int):
+    def randrange(self, start, stop=None, step=1):
         """Choose a random item from range(start, stop[, step]).
 
         This fixes the problem with randint() which includes the
@@ -244,7 +245,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
 
         # This code is a bit messy to make it fast for the
         # common case while still doing adequate error checking.
-        istart = _int(start)
+        istart = int(start)
         if istart != start:
             raise ValueError("non-integer arg 1 for randrange()")
         if stop is None:
@@ -253,7 +254,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
             raise ValueError("empty range for randrange()")
 
         # stop argument supplied.
-        istop = _int(stop)
+        istop = int(stop)
         if istop != stop:
             raise ValueError("non-integer stop for randrange()")
         width = istop - istart
@@ -263,7 +264,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
             raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
 
         # Non-unit step argument supplied.
-        istep = _int(step)
+        istep = int(step)
         if istep != step:
             raise ValueError("non-integer step for randrange()")
         if istep > 0:
@@ -296,7 +297,7 @@ def _randbelow_with_getrandbits(self, n):
             r = getrandbits(k)
         return r
 
-    def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF):
+    def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):
         """Return a random int in the range [0,n).  Returns 0 if n==0.
 
         The implementation does not use getrandbits, but only random.
@@ -307,7 +308,7 @@ def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF):
             _warn("Underlying random() generator does not supply \n"
                 "enough bits to choose from a population range this large.\n"
                 "To remove the range limitation, add a getrandbits() method.")
-            return int(random() * n)
+            return _floor(random() * n)
         if n == 0:
             return 0
         rem = maxsize % n
@@ -315,7 +316,7 @@ def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF):
         r = random()
         while r >= limit:
             r = random()
-        return int(r * maxsize) % n
+        return _floor(r * maxsize) % n
 
     _randbelow = _randbelow_with_getrandbits
 
@@ -346,10 +347,10 @@ def shuffle(self, x, random=None):
                   'since Python 3.9 and will be removed in a subsequent '
                   'version.',
                   DeprecationWarning, 2)
-            _int = int
+            floor = _floor
             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 = floor(random() * (i + 1))
                 x[i], x[j] = x[j], x[i]
 
     def sample(self, population, k, *, counts=None):
@@ -462,9 +463,9 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1):
         n = len(population)
         if cum_weights is None:
             if weights is None:
-                _int = int
+                floor = _floor
                 n += 0.0    # convert to float for a small speed improvement
-                return [population[_int(random() * n)] for i in _repeat(None, k)]
+                return [population[floor(random() * n)] for i in _repeat(None, k)]
             cum_weights = list(_accumulate(weights))
         elif weights is not None:
             raise TypeError('Cannot specify both weights and cumulative weights')
@@ -814,24 +815,20 @@ def _notimplemented(self, *args, **kwds):
 ## -------------------- test program --------------------
 
 def _test_generator(n, func, args):
-    import time
-    print(n, 'times', func.__name__)
-    total = 0.0
-    sqsum = 0.0
-    smallest = 1e10
-    largest = -1e10
-    t0 = time.perf_counter()
-    for i in range(n):
-        x = func(*args)
-        total += x
-        sqsum = sqsum + x*x
-        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))
+    from statistics import stdev, fmean as mean
+    from time import perf_counter
+
+    t0 = perf_counter()
+    data = [func(*args) for i in range(n)]
+    t1 = perf_counter()
+
+    xbar = mean(data)
+    sigma = stdev(data, xbar)
+    low = min(data)
+    high = max(data)
+
+    print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}')
+    print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high))
 
 
 def _test(N=2000):



More information about the Python-checkins mailing list