39
39
40
40
from warnings import warn as _warn
41
41
from math import log as _log , exp as _exp , pi as _pi , e as _e , ceil as _ceil
42
- from math import sqrt as _sqrt , acos as _acos , cos as _cos , sin as _sin , tau as TWOPI
42
+ from math import sqrt as _sqrt , acos as _acos , cos as _cos , sin as _sin
43
+ from math import tau as TWOPI , floor as _floor
43
44
from os import urandom as _urandom
44
45
from _collections_abc import Set as _Set , Sequence as _Sequence
45
46
from itertools import accumulate as _accumulate , repeat as _repeat
@@ -234,7 +235,7 @@ def __reduce__(self):
234
235
235
236
## -------------------- integer methods -------------------
236
237
237
- def randrange (self , start , stop = None , step = 1 , _int = int ):
238
+ def randrange (self , start , stop = None , step = 1 ):
238
239
"""Choose a random item from range(start, stop[, step]).
239
240
240
241
This fixes the problem with randint() which includes the
@@ -244,7 +245,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
244
245
245
246
# This code is a bit messy to make it fast for the
246
247
# common case while still doing adequate error checking.
247
- istart = _int (start )
248
+ istart = int (start )
248
249
if istart != start :
249
250
raise ValueError ("non-integer arg 1 for randrange()" )
250
251
if stop is None :
@@ -253,7 +254,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
253
254
raise ValueError ("empty range for randrange()" )
254
255
255
256
# stop argument supplied.
256
- istop = _int (stop )
257
+ istop = int (stop )
257
258
if istop != stop :
258
259
raise ValueError ("non-integer stop for randrange()" )
259
260
width = istop - istart
@@ -263,7 +264,7 @@ def randrange(self, start, stop=None, step=1, _int=int):
263
264
raise ValueError ("empty range for randrange() (%d, %d, %d)" % (istart , istop , width ))
264
265
265
266
# Non-unit step argument supplied.
266
- istep = _int (step )
267
+ istep = int (step )
267
268
if istep != step :
268
269
raise ValueError ("non-integer step for randrange()" )
269
270
if istep > 0 :
@@ -296,7 +297,7 @@ def _randbelow_with_getrandbits(self, n):
296
297
r = getrandbits (k )
297
298
return r
298
299
299
- def _randbelow_without_getrandbits (self , n , int = int , maxsize = 1 << BPF ):
300
+ def _randbelow_without_getrandbits (self , n , maxsize = 1 << BPF ):
300
301
"""Return a random int in the range [0,n). Returns 0 if n==0.
301
302
302
303
The implementation does not use getrandbits, but only random.
@@ -307,15 +308,15 @@ def _randbelow_without_getrandbits(self, n, int=int, maxsize=1<<BPF):
307
308
_warn ("Underlying random() generator does not supply \n "
308
309
"enough bits to choose from a population range this large.\n "
309
310
"To remove the range limitation, add a getrandbits() method." )
310
- return int (random () * n )
311
+ return _floor (random () * n )
311
312
if n == 0 :
312
313
return 0
313
314
rem = maxsize % n
314
315
limit = (maxsize - rem ) / maxsize # int(limit * maxsize) % n == 0
315
316
r = random ()
316
317
while r >= limit :
317
318
r = random ()
318
- return int (r * maxsize ) % n
319
+ return _floor (r * maxsize ) % n
319
320
320
321
_randbelow = _randbelow_with_getrandbits
321
322
@@ -346,10 +347,10 @@ def shuffle(self, x, random=None):
346
347
'since Python 3.9 and will be removed in a subsequent '
347
348
'version.' ,
348
349
DeprecationWarning , 2 )
349
- _int = int
350
+ floor = _floor
350
351
for i in reversed (range (1 , len (x ))):
351
352
# pick an element in x[:i+1] with which to exchange x[i]
352
- j = _int (random () * (i + 1 ))
353
+ j = floor (random () * (i + 1 ))
353
354
x [i ], x [j ] = x [j ], x [i ]
354
355
355
356
def sample (self , population , k , * , counts = None ):
@@ -462,9 +463,9 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1):
462
463
n = len (population )
463
464
if cum_weights is None :
464
465
if weights is None :
465
- _int = int
466
+ floor = _floor
466
467
n += 0.0 # convert to float for a small speed improvement
467
- return [population [_int (random () * n )] for i in _repeat (None , k )]
468
+ return [population [floor (random () * n )] for i in _repeat (None , k )]
468
469
cum_weights = list (_accumulate (weights ))
469
470
elif weights is not None :
470
471
raise TypeError ('Cannot specify both weights and cumulative weights' )
@@ -814,24 +815,20 @@ def _notimplemented(self, *args, **kwds):
814
815
## -------------------- test program --------------------
815
816
816
817
def _test_generator (n , func , args ):
817
- import time
818
- print (n , 'times' , func .__name__ )
819
- total = 0.0
820
- sqsum = 0.0
821
- smallest = 1e10
822
- largest = - 1e10
823
- t0 = time .perf_counter ()
824
- for i in range (n ):
825
- x = func (* args )
826
- total += x
827
- sqsum = sqsum + x * x
828
- smallest = min (x , smallest )
829
- largest = max (x , largest )
830
- t1 = time .perf_counter ()
831
- print (round (t1 - t0 , 3 ), 'sec,' , end = ' ' )
832
- avg = total / n
833
- stddev = _sqrt (sqsum / n - avg * avg )
834
- print ('avg %g, stddev %g, min %g, max %g\n ' % (avg , stddev , smallest , largest ))
818
+ from statistics import stdev , fmean as mean
819
+ from time import perf_counter
820
+
821
+ t0 = perf_counter ()
822
+ data = [func (* args ) for i in range (n )]
823
+ t1 = perf_counter ()
824
+
825
+ xbar = mean (data )
826
+ sigma = stdev (data , xbar )
827
+ low = min (data )
828
+ high = max (data )
829
+
830
+ print (f'{ t1 - t0 :.3f} sec, { n } times { func .__name__ } ' )
831
+ print ('avg %g, stddev %g, min %g, max %g\n ' % (xbar , sigma , low , high ))
835
832
836
833
837
834
def _test (N = 2000 ):
0 commit comments