mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Small clean-ups for the random module (GH-21038) (GH-21065)
This commit is contained in:
		
							parent
							
								
									ddd3c465bd
								
							
						
					
					
						commit
						cd696201ff
					
				
					 1 changed files with 27 additions and 30 deletions
				
			
		|  | @ -39,7 +39,8 @@ | ||||||
| 
 | 
 | ||||||
| from warnings import warn as _warn | 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 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 os import urandom as _urandom | ||||||
| from _collections_abc import Set as _Set, Sequence as _Sequence | from _collections_abc import Set as _Set, Sequence as _Sequence | ||||||
| from itertools import accumulate as _accumulate, repeat as _repeat | from itertools import accumulate as _accumulate, repeat as _repeat | ||||||
|  | @ -234,7 +235,7 @@ def __reduce__(self): | ||||||
| 
 | 
 | ||||||
|     ## -------------------- integer methods  ------------------- |     ## -------------------- 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]). |         """Choose a random item from range(start, stop[, step]). | ||||||
| 
 | 
 | ||||||
|         This fixes the problem with randint() which includes the |         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 |         # This code is a bit messy to make it fast for the | ||||||
|         # common case while still doing adequate error checking. |         # common case while still doing adequate error checking. | ||||||
|         istart = _int(start) |         istart = int(start) | ||||||
|         if istart != start: |         if istart != start: | ||||||
|             raise ValueError("non-integer arg 1 for randrange()") |             raise ValueError("non-integer arg 1 for randrange()") | ||||||
|         if stop is None: |         if stop is None: | ||||||
|  | @ -253,7 +254,7 @@ def randrange(self, start, stop=None, step=1, _int=int): | ||||||
|             raise ValueError("empty range for randrange()") |             raise ValueError("empty range for randrange()") | ||||||
| 
 | 
 | ||||||
|         # stop argument supplied. |         # stop argument supplied. | ||||||
|         istop = _int(stop) |         istop = int(stop) | ||||||
|         if istop != stop: |         if istop != stop: | ||||||
|             raise ValueError("non-integer stop for randrange()") |             raise ValueError("non-integer stop for randrange()") | ||||||
|         width = istop - istart |         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)) |             raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width)) | ||||||
| 
 | 
 | ||||||
|         # Non-unit step argument supplied. |         # Non-unit step argument supplied. | ||||||
|         istep = _int(step) |         istep = int(step) | ||||||
|         if istep != step: |         if istep != step: | ||||||
|             raise ValueError("non-integer step for randrange()") |             raise ValueError("non-integer step for randrange()") | ||||||
|         if istep > 0: |         if istep > 0: | ||||||
|  | @ -296,7 +297,7 @@ def _randbelow_with_getrandbits(self, n): | ||||||
|             r = getrandbits(k) |             r = getrandbits(k) | ||||||
|         return r |         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. |         """Return a random int in the range [0,n).  Returns 0 if n==0. | ||||||
| 
 | 
 | ||||||
|         The implementation does not use getrandbits, but only random. |         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" |             _warn("Underlying random() generator does not supply \n" | ||||||
|                 "enough bits to choose from a population range this large.\n" |                 "enough bits to choose from a population range this large.\n" | ||||||
|                 "To remove the range limitation, add a getrandbits() method.") |                 "To remove the range limitation, add a getrandbits() method.") | ||||||
|             return int(random() * n) |             return _floor(random() * n) | ||||||
|         if n == 0: |         if n == 0: | ||||||
|             return 0 |             return 0 | ||||||
|         rem = maxsize % n |         rem = maxsize % n | ||||||
|  | @ -315,7 +316,7 @@ def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF): | ||||||
|         r = random() |         r = random() | ||||||
|         while r >= limit: |         while r >= limit: | ||||||
|             r = random() |             r = random() | ||||||
|         return int(r * maxsize) % n |         return _floor(r * maxsize) % n | ||||||
| 
 | 
 | ||||||
|     _randbelow = _randbelow_with_getrandbits |     _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 ' |                   'since Python 3.9 and will be removed in a subsequent ' | ||||||
|                   'version.', |                   'version.', | ||||||
|                   DeprecationWarning, 2) |                   DeprecationWarning, 2) | ||||||
|             _int = int |             floor = _floor | ||||||
|             for i in reversed(range(1, len(x))): |             for i in reversed(range(1, len(x))): | ||||||
|                 # pick an element in x[:i+1] with which to exchange x[i] |                 # 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] |                 x[i], x[j] = x[j], x[i] | ||||||
| 
 | 
 | ||||||
|     def sample(self, population, k, *, counts=None): |     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) |         n = len(population) | ||||||
|         if cum_weights is None: |         if cum_weights is None: | ||||||
|             if weights is None: |             if weights is None: | ||||||
|                 _int = int |                 floor = _floor | ||||||
|                 n += 0.0    # convert to float for a small speed improvement |                 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)) |             cum_weights = list(_accumulate(weights)) | ||||||
|         elif weights is not None: |         elif weights is not None: | ||||||
|             raise TypeError('Cannot specify both weights and cumulative weights') |             raise TypeError('Cannot specify both weights and cumulative weights') | ||||||
|  | @ -814,24 +815,20 @@ def _notimplemented(self, *args, **kwds): | ||||||
| ## -------------------- test program -------------------- | ## -------------------- test program -------------------- | ||||||
| 
 | 
 | ||||||
| def _test_generator(n, func, args): | def _test_generator(n, func, args): | ||||||
|     import time |     from statistics import stdev, fmean as mean | ||||||
|     print(n, 'times', func.__name__) |     from time import perf_counter | ||||||
|     total = 0.0 | 
 | ||||||
|     sqsum = 0.0 |     t0 = perf_counter() | ||||||
|     smallest = 1e10 |     data = [func(*args) for i in range(n)] | ||||||
|     largest = -1e10 |     t1 = perf_counter() | ||||||
|     t0 = time.perf_counter() | 
 | ||||||
|     for i in range(n): |     xbar = mean(data) | ||||||
|         x = func(*args) |     sigma = stdev(data, xbar) | ||||||
|         total += x |     low = min(data) | ||||||
|         sqsum = sqsum + x*x |     high = max(data) | ||||||
|         smallest = min(x, smallest) | 
 | ||||||
|         largest = max(x, largest) |     print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}') | ||||||
|     t1 = time.perf_counter() |     print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high)) | ||||||
|     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): | def _test(N=2000): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)