summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_random.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_random.py')
-rw-r--r--Lib/test/test_random.py227
1 files changed, 84 insertions, 143 deletions
diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py
index caa4f28..776d0c4 100644
--- a/Lib/test/test_random.py
+++ b/Lib/test/test_random.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import unittest
import random
@@ -6,8 +6,7 @@ import time
import pickle
import warnings
from math import log, exp, pi, fsum, sin
-from functools import reduce
-from test import test_support
+from test import support
class TestBasicOps(unittest.TestCase):
# Superclass with tests common to all generators.
@@ -16,7 +15,7 @@ class TestBasicOps(unittest.TestCase):
def randomlist(self, n):
"""Helper function to make a list of random numbers"""
- return [self.gen.random() for i in xrange(n)]
+ return [self.gen.random() for i in range(n)]
def test_autoseed(self):
self.gen.seed()
@@ -35,42 +34,27 @@ class TestBasicOps(unittest.TestCase):
self.assertEqual(randseq, self.randomlist(N))
def test_seedargs(self):
- for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20),
+ for arg in [None, 0, 0, 1, 1, -1, -1, 10**20, -(10**20),
3.14, 1+2j, 'a', tuple('abc')]:
self.gen.seed(arg)
- for arg in [range(3), dict(one=1)]:
+ for arg in [list(range(3)), dict(one=1)]:
self.assertRaises(TypeError, self.gen.seed, arg)
- self.assertRaises(TypeError, self.gen.seed, 1, 2)
+ self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
self.assertRaises(TypeError, type(self.gen), [])
- def test_jumpahead(self):
- self.gen.seed()
- state1 = self.gen.getstate()
- self.gen.jumpahead(100)
- state2 = self.gen.getstate() # s/b distinct from state1
- self.assertNotEqual(state1, state2)
- self.gen.jumpahead(100)
- state3 = self.gen.getstate() # s/b distinct from state2
- self.assertNotEqual(state2, state3)
-
- with test_support.check_py3k_warnings(quiet=True):
- self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg
- self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many
-
- def test_jumpahead_produces_valid_state(self):
- # From http://bugs.python.org/issue14591.
- self.gen.seed(199210368)
- self.gen.jumpahead(13550674232554645900)
- for i in range(500):
- val = self.gen.random()
- self.assertLess(val, 1.0)
+ def test_choice(self):
+ choice = self.gen.choice
+ with self.assertRaises(IndexError):
+ choice([])
+ self.assertEqual(choice([50]), 50)
+ self.assertIn(choice([25, 75]), [25, 75])
def test_sample(self):
# For the entire allowable range of 0 <= k <= N, validate that
# the sample is of the correct length and contains only unique items
N = 100
- population = xrange(N)
- for k in xrange(N+1):
+ population = range(N)
+ for k in range(N+1):
s = self.gen.sample(population, k)
self.assertEqual(len(s), k)
uniq = set(s)
@@ -85,11 +69,13 @@ class TestBasicOps(unittest.TestCase):
pop = range(n)
trials = 10000 # large num prevents false negatives without slowing normal case
def factorial(n):
- return reduce(int.__mul__, xrange(1, n), 1)
- for k in xrange(n):
+ if n == 0:
+ return 1
+ return n * factorial(n - 1)
+ for k in range(n):
expected = factorial(n) // factorial(n-k)
perms = {}
- for i in xrange(trials):
+ for i in range(trials):
perms[tuple(self.gen.sample(pop, k))] = None
if len(perms) == expected:
break
@@ -100,29 +86,12 @@ class TestBasicOps(unittest.TestCase):
# SF bug #801342 -- population can be any iterable defining __len__()
self.gen.sample(set(range(20)), 2)
self.gen.sample(range(20), 2)
- self.gen.sample(xrange(20), 2)
+ self.gen.sample(range(20), 2)
self.gen.sample(str('abcdefghijklmnopqrst'), 2)
self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
def test_sample_on_dicts(self):
- self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2)
-
- # SF bug #1460340 -- random.sample can raise KeyError
- a = dict.fromkeys(range(10)+range(10,100,2)+range(100,110))
- self.gen.sample(a, 3)
-
- # A followup to bug #1460340: sampling from a dict could return
- # a subset of its keys or of its values, depending on the size of
- # the subset requested.
- N = 30
- d = dict((i, complex(i, i)) for i in xrange(N))
- for k in xrange(N+1):
- samp = self.gen.sample(d, k)
- # Verify that we got ints back (keys); the values are complex.
- for x in samp:
- self.assertTrue(type(x) is int)
- samp.sort()
- self.assertEqual(samp, range(N))
+ self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2)
def test_gauss(self):
# Ensure that the seed() method initializes all the hidden state. In
@@ -143,9 +112,9 @@ class TestBasicOps(unittest.TestCase):
def test_pickling(self):
state = pickle.dumps(self.gen)
- origseq = [self.gen.random() for i in xrange(10)]
+ origseq = [self.gen.random() for i in range(10)]
newgen = pickle.loads(state)
- restoredseq = [newgen.random() for i in xrange(10)]
+ restoredseq = [newgen.random() for i in range(10)]
self.assertEqual(origseq, restoredseq)
def test_bug_1727780(self):
@@ -156,52 +125,18 @@ class TestBasicOps(unittest.TestCase):
("randv2_64.pck", 866),
("randv3.pck", 343)]
for file, value in files:
- f = open(test_support.findfile(file),"rb")
+ f = open(support.findfile(file),"rb")
r = pickle.load(f)
f.close()
- self.assertEqual(r.randrange(1000), value)
-
-class WichmannHill_TestBasicOps(TestBasicOps):
- gen = random.WichmannHill()
-
- def test_setstate_first_arg(self):
- self.assertRaises(ValueError, self.gen.setstate, (2, None, None))
-
- def test_strong_jumpahead(self):
- # tests that jumpahead(n) semantics correspond to n calls to random()
- N = 1000
- s = self.gen.getstate()
- self.gen.jumpahead(N)
- r1 = self.gen.random()
- # now do it the slow way
- self.gen.setstate(s)
- for i in xrange(N):
- self.gen.random()
- r2 = self.gen.random()
- self.assertEqual(r1, r2)
-
- def test_gauss_with_whseed(self):
- # Ensure that the seed() method initializes all the hidden state. In
- # particular, through 2.2.1 it failed to reset a piece of state used
- # by (and only by) the .gauss() method.
-
- for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
- self.gen.whseed(seed)
- x1 = self.gen.random()
- y1 = self.gen.gauss(0, 1)
+ self.assertEqual(int(r.random()*1000), value)
- self.gen.whseed(seed)
- x2 = self.gen.random()
- y2 = self.gen.gauss(0, 1)
-
- self.assertEqual(x1, x2)
- self.assertEqual(y1, y2)
-
- def test_bigrand(self):
- # Verify warnings are raised when randrange is too large for random()
- with warnings.catch_warnings():
- warnings.filterwarnings("error", "Underlying random")
- self.assertRaises(UserWarning, self.gen.randrange, 2**60)
+ def test_bug_9025(self):
+ # Had problem with an uneven distribution in int(n*random())
+ # Verify the fix by checking that distributions fall within expectations.
+ n = 100000
+ randrange = self.gen.randrange
+ k = sum(randrange(6755399441055744) % 3 == 2 for i in range(n))
+ self.assertTrue(0.30 < k/n < .37, (k/n))
class SystemRandom_TestBasicOps(TestBasicOps):
gen = random.SystemRandom()
@@ -218,10 +153,6 @@ class SystemRandom_TestBasicOps(TestBasicOps):
# Doesn't need to do anything except not fail
self.gen.seed(100)
- def test_jumpahead(self):
- # Doesn't need to do anything except not fail
- self.gen.jumpahead(100)
-
def test_gauss(self):
self.gen.gauss_next = None
self.gen.seed(100)
@@ -234,7 +165,7 @@ class SystemRandom_TestBasicOps(TestBasicOps):
# This should pass whenever a C double has 53 bit precision.
span = 2 ** 53
cum = 0
- for i in xrange(100):
+ for i in range(100):
cum |= int(self.gen.random() * span)
self.assertEqual(cum, span-1)
@@ -243,7 +174,7 @@ class SystemRandom_TestBasicOps(TestBasicOps):
# in stages so that all bit positions are active.
span = 2 ** 500
cum = 0
- for i in xrange(100):
+ for i in range(100):
r = self.gen.randrange(span)
self.assertTrue(0 <= r < span)
cum |= r
@@ -260,18 +191,18 @@ class SystemRandom_TestBasicOps(TestBasicOps):
def test_rangelimits(self):
for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
self.assertEqual(set(range(start,stop)),
- set([self.gen.randrange(start,stop) for i in xrange(100)]))
+ set([self.gen.randrange(start,stop) for i in range(100)]))
def test_genrandbits(self):
# Verify ranges
- for k in xrange(1, 1000):
+ for k in range(1, 1000):
self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
# Verify all bits active
getbits = self.gen.getrandbits
for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
cum = 0
- for i in xrange(100):
+ for i in range(100):
cum |= getbits(span)
self.assertEqual(cum, 2**span-1)
@@ -286,12 +217,12 @@ class SystemRandom_TestBasicOps(TestBasicOps):
# check bitcount transition points: 2**i and 2**(i+1)-1
# show that: k = int(1.001 + _log(n, 2))
# is equal to or one greater than the number of bits in n
- for i in xrange(1, 1000):
- n = 1L << i # check an exact power of two
+ for i in range(1, 1000):
+ n = 1 << i # check an exact power of two
numbits = i+1
k = int(1.00001 + _log(n, 2))
self.assertEqual(k, numbits)
- self.assertTrue(n == 2**(k-1))
+ self.assertEqual(n, 2**(k-1))
n += n - 1 # check 1 below the next power of two
k = int(1.00001 + _log(n, 2))
@@ -307,6 +238,17 @@ class SystemRandom_TestBasicOps(TestBasicOps):
class MersenneTwister_TestBasicOps(TestBasicOps):
gen = random.Random()
+ def test_guaranteed_stable(self):
+ # These sequences are guaranteed to stay the same across versions of python
+ self.gen.seed(3456147, version=1)
+ self.assertEqual([self.gen.random().hex() for i in range(4)],
+ ['0x1.ac362300d90d2p-1', '0x1.9d16f74365005p-1',
+ '0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
+ self.gen.seed("the quick brown fox", version=2)
+ self.assertEqual([self.gen.random().hex() for i in range(4)],
+ ['0x1.1239ddfb11b7cp-3', '0x1.b3cbb5c51b120p-4',
+ '0x1.8c4f55116b60fp-1', '0x1.63eb525174a27p-1'])
+
def test_setstate_first_arg(self):
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
@@ -346,7 +288,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
0.089215024911993401,
0.78486196105372907]
- self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
+ self.gen.seed(61731 + (24903<<32) + (614<<64) + (42143<<96))
actual = self.randomlist(2000)[-10:]
for a, e in zip(actual, expected):
self.assertAlmostEqual(a,e,places=14)
@@ -358,20 +300,20 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
# no rounding errors -- all results are exact).
from math import ldexp
- expected = [0x0eab3258d2231fL,
- 0x1b89db315277a5L,
- 0x1db622a5518016L,
- 0x0b7f9af0d575bfL,
- 0x029e4c4db82240L,
- 0x04961892f5d673L,
- 0x02b291598e4589L,
- 0x11388382c15694L,
- 0x02dad977c9e1feL,
- 0x191d96d4d334c6L]
- self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
+ expected = [0x0eab3258d2231f,
+ 0x1b89db315277a5,
+ 0x1db622a5518016,
+ 0x0b7f9af0d575bf,
+ 0x029e4c4db82240,
+ 0x04961892f5d673,
+ 0x02b291598e4589,
+ 0x11388382c15694,
+ 0x02dad977c9e1fe,
+ 0x191d96d4d334c6]
+ self.gen.seed(61731 + (24903<<32) + (614<<64) + (42143<<96))
actual = self.randomlist(2000)[-10:]
for a, e in zip(actual, expected):
- self.assertEqual(long(ldexp(a, 53)), e)
+ self.assertEqual(int(ldexp(a, 53)), e)
def test_long_seed(self):
# This is most interesting to run in debug mode, just to make sure
@@ -379,14 +321,14 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
# is allocated, consuming space proportional to the number of bits
# in the seed. Unfortunately, that's a quadratic-time algorithm,
# so don't make this horribly big.
- seed = (1L << (10000 * 8)) - 1 # about 10K bytes
+ seed = (1 << (10000 * 8)) - 1 # about 10K bytes
self.gen.seed(seed)
def test_53_bits_per_float(self):
# This should pass whenever a C double has 53 bit precision.
span = 2 ** 53
cum = 0
- for i in xrange(100):
+ for i in range(100):
cum |= int(self.gen.random() * span)
self.assertEqual(cum, span-1)
@@ -395,7 +337,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
# in stages so that all bit positions are active.
span = 2 ** 500
cum = 0
- for i in xrange(100):
+ for i in range(100):
r = self.gen.randrange(span)
self.assertTrue(0 <= r < span)
cum |= r
@@ -412,22 +354,22 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
def test_rangelimits(self):
for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
self.assertEqual(set(range(start,stop)),
- set([self.gen.randrange(start,stop) for i in xrange(100)]))
+ set([self.gen.randrange(start,stop) for i in range(100)]))
def test_genrandbits(self):
# Verify cross-platform repeatability
self.gen.seed(1234567)
self.assertEqual(self.gen.getrandbits(100),
- 97904845777343510404718956115L)
+ 97904845777343510404718956115)
# Verify ranges
- for k in xrange(1, 1000):
+ for k in range(1, 1000):
self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
# Verify all bits active
getbits = self.gen.getrandbits
for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
cum = 0
- for i in xrange(100):
+ for i in range(100):
cum |= getbits(span)
self.assertEqual(cum, 2**span-1)
@@ -442,12 +384,12 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
# check bitcount transition points: 2**i and 2**(i+1)-1
# show that: k = int(1.001 + _log(n, 2))
# is equal to or one greater than the number of bits in n
- for i in xrange(1, 1000):
- n = 1L << i # check an exact power of two
+ for i in range(1, 1000):
+ n = 1 << i # check an exact power of two
numbits = i+1
k = int(1.00001 + _log(n, 2))
self.assertEqual(k, numbits)
- self.assertTrue(n == 2**(k-1))
+ self.assertEqual(n, 2**(k-1))
n += n - 1 # check 1 below the next power of two
k = int(1.00001 + _log(n, 2))
@@ -489,7 +431,7 @@ class TestDistributions(unittest.TestCase):
def test_zeroinputs(self):
# Verify that distributions can handle a series of zero inputs'
g = random.Random()
- x = [g.random() for i in xrange(50)] + [0.0]*5
+ x = [g.random() for i in range(50)] + [0.0]*5
g.random = x[:].pop; g.uniform(1,10)
g.random = x[:].pop; g.paretovariate(1.0)
g.random = x[:].pop; g.expovariate(1.0)
@@ -509,7 +451,7 @@ class TestDistributions(unittest.TestCase):
# Only works for distributions which do not consume variates in pairs
g = random.Random()
N = 5000
- x = [i/float(N) for i in xrange(1,N)]
+ x = [i/float(N) for i in range(1,N)]
for variate, args, mu, sigmasqrd in [
(g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
(g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0),
@@ -520,7 +462,7 @@ class TestDistributions(unittest.TestCase):
gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
g.random = x[:].pop
y = []
- for i in xrange(len(x)):
+ for i in range(len(x)):
try:
y.append(variate(*args))
except IndexError:
@@ -530,8 +472,8 @@ class TestDistributions(unittest.TestCase):
s1 += e
s2 += (e - mu) ** 2
N = len(y)
- self.assertAlmostEqual(s1/N, mu, 2)
- self.assertAlmostEqual(s2/(N-1), sigmasqrd, 2)
+ self.assertAlmostEqual(s1/N, mu, places=2)
+ self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2)
class TestModule(unittest.TestCase):
def testMagicConstants(self):
@@ -553,8 +495,7 @@ class TestModule(unittest.TestCase):
def test_main(verbose=None):
- testclasses = [WichmannHill_TestBasicOps,
- MersenneTwister_TestBasicOps,
+ testclasses = [MersenneTwister_TestBasicOps,
TestDistributions,
TestModule]
@@ -565,16 +506,16 @@ def test_main(verbose=None):
else:
testclasses.append(SystemRandom_TestBasicOps)
- test_support.run_unittest(*testclasses)
+ support.run_unittest(*testclasses)
# verify reference counting
import sys
if verbose and hasattr(sys, "gettotalrefcount"):
counts = [None] * 5
- for i in xrange(len(counts)):
- test_support.run_unittest(*testclasses)
+ for i in range(len(counts)):
+ support.run_unittest(*testclasses)
counts[i] = sys.gettotalrefcount()
- print counts
+ print(counts)
if __name__ == "__main__":
test_main(verbose=True)