test_random.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. import unittest
  2. import random
  3. import time
  4. import pickle
  5. import warnings
  6. from math import log, exp, pi, fsum, sin
  7. from functools import reduce
  8. from test import test_support
  9. class TestBasicOps(unittest.TestCase):
  10. # Superclass with tests common to all generators.
  11. # Subclasses must arrange for self.gen to retrieve the Random instance
  12. # to be tested.
  13. def randomlist(self, n):
  14. """Helper function to make a list of random numbers"""
  15. return [self.gen.random() for i in xrange(n)]
  16. def test_autoseed(self):
  17. self.gen.seed()
  18. state1 = self.gen.getstate()
  19. time.sleep(0.1)
  20. self.gen.seed() # diffent seeds at different times
  21. state2 = self.gen.getstate()
  22. self.assertNotEqual(state1, state2)
  23. def test_saverestore(self):
  24. N = 1000
  25. self.gen.seed()
  26. state = self.gen.getstate()
  27. randseq = self.randomlist(N)
  28. self.gen.setstate(state) # should regenerate the same sequence
  29. self.assertEqual(randseq, self.randomlist(N))
  30. def test_seedargs(self):
  31. for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20),
  32. 3.14, 1+2j, 'a', tuple('abc')]:
  33. self.gen.seed(arg)
  34. for arg in [range(3), dict(one=1)]:
  35. self.assertRaises(TypeError, self.gen.seed, arg)
  36. self.assertRaises(TypeError, self.gen.seed, 1, 2)
  37. self.assertRaises(TypeError, type(self.gen), [])
  38. def test_jumpahead(self):
  39. self.gen.seed()
  40. state1 = self.gen.getstate()
  41. self.gen.jumpahead(100)
  42. state2 = self.gen.getstate() # s/b distinct from state1
  43. self.assertNotEqual(state1, state2)
  44. self.gen.jumpahead(100)
  45. state3 = self.gen.getstate() # s/b distinct from state2
  46. self.assertNotEqual(state2, state3)
  47. with test_support.check_py3k_warnings(quiet=True):
  48. self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg
  49. self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many
  50. def test_jumpahead_produces_valid_state(self):
  51. # From http://bugs.python.org/issue14591.
  52. self.gen.seed(199210368)
  53. self.gen.jumpahead(13550674232554645900)
  54. for i in range(500):
  55. val = self.gen.random()
  56. self.assertLess(val, 1.0)
  57. def test_sample(self):
  58. # For the entire allowable range of 0 <= k <= N, validate that
  59. # the sample is of the correct length and contains only unique items
  60. N = 100
  61. population = xrange(N)
  62. for k in xrange(N+1):
  63. s = self.gen.sample(population, k)
  64. self.assertEqual(len(s), k)
  65. uniq = set(s)
  66. self.assertEqual(len(uniq), k)
  67. self.assertTrue(uniq <= set(population))
  68. self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0
  69. def test_sample_distribution(self):
  70. # For the entire allowable range of 0 <= k <= N, validate that
  71. # sample generates all possible permutations
  72. n = 5
  73. pop = range(n)
  74. trials = 10000 # large num prevents false negatives without slowing normal case
  75. def factorial(n):
  76. return reduce(int.__mul__, xrange(1, n), 1)
  77. for k in xrange(n):
  78. expected = factorial(n) // factorial(n-k)
  79. perms = {}
  80. for i in xrange(trials):
  81. perms[tuple(self.gen.sample(pop, k))] = None
  82. if len(perms) == expected:
  83. break
  84. else:
  85. self.fail()
  86. def test_sample_inputs(self):
  87. # SF bug #801342 -- population can be any iterable defining __len__()
  88. self.gen.sample(set(range(20)), 2)
  89. self.gen.sample(range(20), 2)
  90. self.gen.sample(xrange(20), 2)
  91. self.gen.sample(str('abcdefghijklmnopqrst'), 2)
  92. self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
  93. def test_sample_on_dicts(self):
  94. self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2)
  95. # SF bug #1460340 -- random.sample can raise KeyError
  96. a = dict.fromkeys(range(10)+range(10,100,2)+range(100,110))
  97. self.gen.sample(a, 3)
  98. # A followup to bug #1460340: sampling from a dict could return
  99. # a subset of its keys or of its values, depending on the size of
  100. # the subset requested.
  101. N = 30
  102. d = dict((i, complex(i, i)) for i in xrange(N))
  103. for k in xrange(N+1):
  104. samp = self.gen.sample(d, k)
  105. # Verify that we got ints back (keys); the values are complex.
  106. for x in samp:
  107. self.assertTrue(type(x) is int)
  108. samp.sort()
  109. self.assertEqual(samp, range(N))
  110. def test_gauss(self):
  111. # Ensure that the seed() method initializes all the hidden state. In
  112. # particular, through 2.2.1 it failed to reset a piece of state used
  113. # by (and only by) the .gauss() method.
  114. for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
  115. self.gen.seed(seed)
  116. x1 = self.gen.random()
  117. y1 = self.gen.gauss(0, 1)
  118. self.gen.seed(seed)
  119. x2 = self.gen.random()
  120. y2 = self.gen.gauss(0, 1)
  121. self.assertEqual(x1, x2)
  122. self.assertEqual(y1, y2)
  123. def test_pickling(self):
  124. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  125. state = pickle.dumps(self.gen, proto)
  126. origseq = [self.gen.random() for i in xrange(10)]
  127. newgen = pickle.loads(state)
  128. restoredseq = [newgen.random() for i in xrange(10)]
  129. self.assertEqual(origseq, restoredseq)
  130. def test_bug_1727780(self):
  131. # verify that version-2-pickles can be loaded
  132. # fine, whether they are created on 32-bit or 64-bit
  133. # platforms, and that version-3-pickles load fine.
  134. files = [("randv2_32.pck", 780),
  135. ("randv2_64.pck", 866),
  136. ("randv3.pck", 343)]
  137. for file, value in files:
  138. f = open(test_support.findfile(file),"rb")
  139. r = pickle.load(f)
  140. f.close()
  141. self.assertEqual(r.randrange(1000), value)
  142. class WichmannHill_TestBasicOps(TestBasicOps):
  143. gen = random.WichmannHill()
  144. def test_setstate_first_arg(self):
  145. self.assertRaises(ValueError, self.gen.setstate, (2, None, None))
  146. def test_strong_jumpahead(self):
  147. # tests that jumpahead(n) semantics correspond to n calls to random()
  148. N = 1000
  149. s = self.gen.getstate()
  150. self.gen.jumpahead(N)
  151. r1 = self.gen.random()
  152. # now do it the slow way
  153. self.gen.setstate(s)
  154. for i in xrange(N):
  155. self.gen.random()
  156. r2 = self.gen.random()
  157. self.assertEqual(r1, r2)
  158. def test_gauss_with_whseed(self):
  159. # Ensure that the seed() method initializes all the hidden state. In
  160. # particular, through 2.2.1 it failed to reset a piece of state used
  161. # by (and only by) the .gauss() method.
  162. for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
  163. self.gen.whseed(seed)
  164. x1 = self.gen.random()
  165. y1 = self.gen.gauss(0, 1)
  166. self.gen.whseed(seed)
  167. x2 = self.gen.random()
  168. y2 = self.gen.gauss(0, 1)
  169. self.assertEqual(x1, x2)
  170. self.assertEqual(y1, y2)
  171. def test_bigrand(self):
  172. # Verify warnings are raised when randrange is too large for random()
  173. with warnings.catch_warnings():
  174. warnings.filterwarnings("error", "Underlying random")
  175. self.assertRaises(UserWarning, self.gen.randrange, 2**60)
  176. class SystemRandom_TestBasicOps(TestBasicOps):
  177. gen = random.SystemRandom()
  178. def test_autoseed(self):
  179. # Doesn't need to do anything except not fail
  180. self.gen.seed()
  181. def test_saverestore(self):
  182. self.assertRaises(NotImplementedError, self.gen.getstate)
  183. self.assertRaises(NotImplementedError, self.gen.setstate, None)
  184. def test_seedargs(self):
  185. # Doesn't need to do anything except not fail
  186. self.gen.seed(100)
  187. def test_jumpahead(self):
  188. # Doesn't need to do anything except not fail
  189. self.gen.jumpahead(100)
  190. def test_gauss(self):
  191. self.gen.gauss_next = None
  192. self.gen.seed(100)
  193. self.assertEqual(self.gen.gauss_next, None)
  194. def test_pickling(self):
  195. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  196. self.assertRaises(NotImplementedError, pickle.dumps, self.gen, proto)
  197. def test_53_bits_per_float(self):
  198. # This should pass whenever a C double has 53 bit precision.
  199. span = 2 ** 53
  200. cum = 0
  201. for i in xrange(100):
  202. cum |= int(self.gen.random() * span)
  203. self.assertEqual(cum, span-1)
  204. def test_bigrand(self):
  205. # The randrange routine should build-up the required number of bits
  206. # in stages so that all bit positions are active.
  207. span = 2 ** 500
  208. cum = 0
  209. for i in xrange(100):
  210. r = self.gen.randrange(span)
  211. self.assertTrue(0 <= r < span)
  212. cum |= r
  213. self.assertEqual(cum, span-1)
  214. def test_bigrand_ranges(self):
  215. for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
  216. start = self.gen.randrange(2 ** (i-2))
  217. stop = self.gen.randrange(2 ** i)
  218. if stop <= start:
  219. continue
  220. self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
  221. def test_rangelimits(self):
  222. for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
  223. self.assertEqual(set(range(start,stop)),
  224. set([self.gen.randrange(start,stop) for i in xrange(100)]))
  225. def test_genrandbits(self):
  226. # Verify ranges
  227. for k in xrange(1, 1000):
  228. self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
  229. # Verify all bits active
  230. getbits = self.gen.getrandbits
  231. for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
  232. cum = 0
  233. for i in xrange(100):
  234. cum |= getbits(span)
  235. self.assertEqual(cum, 2**span-1)
  236. # Verify argument checking
  237. self.assertRaises(TypeError, self.gen.getrandbits)
  238. self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
  239. self.assertRaises(ValueError, self.gen.getrandbits, 0)
  240. self.assertRaises(ValueError, self.gen.getrandbits, -1)
  241. self.assertRaises(TypeError, self.gen.getrandbits, 10.1)
  242. def test_randbelow_logic(self, _log=log, int=int):
  243. # check bitcount transition points: 2**i and 2**(i+1)-1
  244. # show that: k = int(1.001 + _log(n, 2))
  245. # is equal to or one greater than the number of bits in n
  246. for i in xrange(1, 1000):
  247. n = 1L << i # check an exact power of two
  248. numbits = i+1
  249. k = int(1.00001 + _log(n, 2))
  250. self.assertEqual(k, numbits)
  251. self.assertTrue(n == 2**(k-1))
  252. n += n - 1 # check 1 below the next power of two
  253. k = int(1.00001 + _log(n, 2))
  254. self.assertIn(k, [numbits, numbits+1])
  255. self.assertTrue(2**k > n > 2**(k-2))
  256. n -= n >> 15 # check a little farther below the next power of two
  257. k = int(1.00001 + _log(n, 2))
  258. self.assertEqual(k, numbits) # note the stronger assertion
  259. self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion
  260. class MersenneTwister_TestBasicOps(TestBasicOps):
  261. gen = random.Random()
  262. def test_setstate_first_arg(self):
  263. self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
  264. def test_setstate_middle_arg(self):
  265. # Wrong type, s/b tuple
  266. self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
  267. # Wrong length, s/b 625
  268. self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None))
  269. # Wrong type, s/b tuple of 625 ints
  270. self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None))
  271. # Last element s/b an int also
  272. self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None))
  273. # Last element s/b between 0 and 624
  274. with self.assertRaises((ValueError, OverflowError)):
  275. self.gen.setstate((2, (1,)*624+(625,), None))
  276. with self.assertRaises((ValueError, OverflowError)):
  277. self.gen.setstate((2, (1,)*624+(-1,), None))
  278. def test_referenceImplementation(self):
  279. # Compare the python implementation with results from the original
  280. # code. Create 2000 53-bit precision random floats. Compare only
  281. # the last ten entries to show that the independent implementations
  282. # are tracking. Here is the main() function needed to create the
  283. # list of expected random numbers:
  284. # void main(void){
  285. # int i;
  286. # unsigned long init[4]={61731, 24903, 614, 42143}, length=4;
  287. # init_by_array(init, length);
  288. # for (i=0; i<2000; i++) {
  289. # printf("%.15f ", genrand_res53());
  290. # if (i%5==4) printf("\n");
  291. # }
  292. # }
  293. expected = [0.45839803073713259,
  294. 0.86057815201978782,
  295. 0.92848331726782152,
  296. 0.35932681119782461,
  297. 0.081823493762449573,
  298. 0.14332226470169329,
  299. 0.084297823823520024,
  300. 0.53814864671831453,
  301. 0.089215024911993401,
  302. 0.78486196105372907]
  303. self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
  304. actual = self.randomlist(2000)[-10:]
  305. for a, e in zip(actual, expected):
  306. self.assertAlmostEqual(a,e,places=14)
  307. def test_strong_reference_implementation(self):
  308. # Like test_referenceImplementation, but checks for exact bit-level
  309. # equality. This should pass on any box where C double contains
  310. # at least 53 bits of precision (the underlying algorithm suffers
  311. # no rounding errors -- all results are exact).
  312. from math import ldexp
  313. expected = [0x0eab3258d2231fL,
  314. 0x1b89db315277a5L,
  315. 0x1db622a5518016L,
  316. 0x0b7f9af0d575bfL,
  317. 0x029e4c4db82240L,
  318. 0x04961892f5d673L,
  319. 0x02b291598e4589L,
  320. 0x11388382c15694L,
  321. 0x02dad977c9e1feL,
  322. 0x191d96d4d334c6L]
  323. self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
  324. actual = self.randomlist(2000)[-10:]
  325. for a, e in zip(actual, expected):
  326. self.assertEqual(long(ldexp(a, 53)), e)
  327. def test_long_seed(self):
  328. # This is most interesting to run in debug mode, just to make sure
  329. # nothing blows up. Under the covers, a dynamically resized array
  330. # is allocated, consuming space proportional to the number of bits
  331. # in the seed. Unfortunately, that's a quadratic-time algorithm,
  332. # so don't make this horribly big.
  333. seed = (1L << (10000 * 8)) - 1 # about 10K bytes
  334. self.gen.seed(seed)
  335. def test_53_bits_per_float(self):
  336. # This should pass whenever a C double has 53 bit precision.
  337. span = 2 ** 53
  338. cum = 0
  339. for i in xrange(100):
  340. cum |= int(self.gen.random() * span)
  341. self.assertEqual(cum, span-1)
  342. def test_bigrand(self):
  343. # The randrange routine should build-up the required number of bits
  344. # in stages so that all bit positions are active.
  345. span = 2 ** 500
  346. cum = 0
  347. for i in xrange(100):
  348. r = self.gen.randrange(span)
  349. self.assertTrue(0 <= r < span)
  350. cum |= r
  351. self.assertEqual(cum, span-1)
  352. def test_bigrand_ranges(self):
  353. for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
  354. start = self.gen.randrange(2 ** (i-2))
  355. stop = self.gen.randrange(2 ** i)
  356. if stop <= start:
  357. continue
  358. self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
  359. def test_rangelimits(self):
  360. for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
  361. self.assertEqual(set(range(start,stop)),
  362. set([self.gen.randrange(start,stop) for i in xrange(100)]))
  363. def test_genrandbits(self):
  364. # Verify cross-platform repeatability
  365. self.gen.seed(1234567)
  366. self.assertEqual(self.gen.getrandbits(100),
  367. 97904845777343510404718956115L)
  368. # Verify ranges
  369. for k in xrange(1, 1000):
  370. self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
  371. # Verify all bits active
  372. getbits = self.gen.getrandbits
  373. for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
  374. cum = 0
  375. for i in xrange(100):
  376. cum |= getbits(span)
  377. self.assertEqual(cum, 2**span-1)
  378. # Verify argument checking
  379. self.assertRaises(TypeError, self.gen.getrandbits)
  380. self.assertRaises(TypeError, self.gen.getrandbits, 'a')
  381. self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
  382. self.assertRaises(ValueError, self.gen.getrandbits, 0)
  383. self.assertRaises(ValueError, self.gen.getrandbits, -1)
  384. def test_randbelow_logic(self, _log=log, int=int):
  385. # check bitcount transition points: 2**i and 2**(i+1)-1
  386. # show that: k = int(1.001 + _log(n, 2))
  387. # is equal to or one greater than the number of bits in n
  388. for i in xrange(1, 1000):
  389. n = 1L << i # check an exact power of two
  390. numbits = i+1
  391. k = int(1.00001 + _log(n, 2))
  392. self.assertEqual(k, numbits)
  393. self.assertTrue(n == 2**(k-1))
  394. n += n - 1 # check 1 below the next power of two
  395. k = int(1.00001 + _log(n, 2))
  396. self.assertIn(k, [numbits, numbits+1])
  397. self.assertTrue(2**k > n > 2**(k-2))
  398. n -= n >> 15 # check a little farther below the next power of two
  399. k = int(1.00001 + _log(n, 2))
  400. self.assertEqual(k, numbits) # note the stronger assertion
  401. self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion
  402. def test_randrange_bug_1590891(self):
  403. start = 1000000000000
  404. stop = -100000000000000000000
  405. step = -200
  406. x = self.gen.randrange(start, stop, step)
  407. self.assertTrue(stop < x <= start)
  408. self.assertEqual((x+stop)%step, 0)
  409. def gamma(z, sqrt2pi=(2.0*pi)**0.5):
  410. # Reflection to right half of complex plane
  411. if z < 0.5:
  412. return pi / sin(pi*z) / gamma(1.0-z)
  413. # Lanczos approximation with g=7
  414. az = z + (7.0 - 0.5)
  415. return az ** (z-0.5) / exp(az) * sqrt2pi * fsum([
  416. 0.9999999999995183,
  417. 676.5203681218835 / z,
  418. -1259.139216722289 / (z+1.0),
  419. 771.3234287757674 / (z+2.0),
  420. -176.6150291498386 / (z+3.0),
  421. 12.50734324009056 / (z+4.0),
  422. -0.1385710331296526 / (z+5.0),
  423. 0.9934937113930748e-05 / (z+6.0),
  424. 0.1659470187408462e-06 / (z+7.0),
  425. ])
  426. class TestDistributions(unittest.TestCase):
  427. def test_zeroinputs(self):
  428. # Verify that distributions can handle a series of zero inputs'
  429. g = random.Random()
  430. x = [g.random() for i in xrange(50)] + [0.0]*5
  431. g.random = x[:].pop; g.uniform(1,10)
  432. g.random = x[:].pop; g.paretovariate(1.0)
  433. g.random = x[:].pop; g.expovariate(1.0)
  434. g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
  435. g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0)
  436. g.random = x[:].pop; g.normalvariate(0.0, 1.0)
  437. g.random = x[:].pop; g.gauss(0.0, 1.0)
  438. g.random = x[:].pop; g.lognormvariate(0.0, 1.0)
  439. g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0)
  440. g.random = x[:].pop; g.gammavariate(0.01, 1.0)
  441. g.random = x[:].pop; g.gammavariate(1.0, 1.0)
  442. g.random = x[:].pop; g.gammavariate(200.0, 1.0)
  443. g.random = x[:].pop; g.betavariate(3.0, 3.0)
  444. g.random = x[:].pop; g.triangular(0.0, 1.0, 1.0/3.0)
  445. def test_avg_std(self):
  446. # Use integration to test distribution average and standard deviation.
  447. # Only works for distributions which do not consume variates in pairs
  448. g = random.Random()
  449. N = 5000
  450. x = [i/float(N) for i in xrange(1,N)]
  451. for variate, args, mu, sigmasqrd in [
  452. (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
  453. (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0),
  454. (g.expovariate, (1.5,), 1/1.5, 1/1.5**2),
  455. (g.vonmisesvariate, (1.23, 0), pi, pi**2/3),
  456. (g.paretovariate, (5.0,), 5.0/(5.0-1),
  457. 5.0/((5.0-1)**2*(5.0-2))),
  458. (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),
  459. gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
  460. g.random = x[:].pop
  461. y = []
  462. for i in xrange(len(x)):
  463. try:
  464. y.append(variate(*args))
  465. except IndexError:
  466. pass
  467. s1 = s2 = 0
  468. for e in y:
  469. s1 += e
  470. s2 += (e - mu) ** 2
  471. N = len(y)
  472. self.assertAlmostEqual(s1/N, mu, places=2,
  473. msg='%s%r' % (variate.__name__, args))
  474. self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2,
  475. msg='%s%r' % (variate.__name__, args))
  476. def test_constant(self):
  477. g = random.Random()
  478. N = 100
  479. for variate, args, expected in [
  480. (g.uniform, (10.0, 10.0), 10.0),
  481. (g.triangular, (10.0, 10.0), 10.0),
  482. (g.triangular, (10.0, 10.0, 10.0), 10.0),
  483. (g.expovariate, (float('inf'),), 0.0),
  484. (g.vonmisesvariate, (3.0, float('inf')), 3.0),
  485. (g.gauss, (10.0, 0.0), 10.0),
  486. (g.lognormvariate, (0.0, 0.0), 1.0),
  487. (g.lognormvariate, (-float('inf'), 0.0), 0.0),
  488. (g.normalvariate, (10.0, 0.0), 10.0),
  489. (g.paretovariate, (float('inf'),), 1.0),
  490. (g.weibullvariate, (10.0, float('inf')), 10.0),
  491. (g.weibullvariate, (0.0, 10.0), 0.0),
  492. ]:
  493. for i in range(N):
  494. self.assertEqual(variate(*args), expected)
  495. def test_von_mises_range(self):
  496. # Issue 17149: von mises variates were not consistently in the
  497. # range [0, 2*PI].
  498. g = random.Random()
  499. N = 100
  500. for mu in 0.0, 0.1, 3.1, 6.2:
  501. for kappa in 0.0, 2.3, 500.0:
  502. for _ in range(N):
  503. sample = g.vonmisesvariate(mu, kappa)
  504. self.assertTrue(
  505. 0 <= sample <= random.TWOPI,
  506. msg=("vonmisesvariate({}, {}) produced a result {} out"
  507. " of range [0, 2*pi]").format(mu, kappa, sample))
  508. def test_von_mises_large_kappa(self):
  509. # Issue #17141: vonmisesvariate() was hang for large kappas
  510. random.vonmisesvariate(0, 1e15)
  511. random.vonmisesvariate(0, 1e100)
  512. class TestModule(unittest.TestCase):
  513. def testMagicConstants(self):
  514. self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
  515. self.assertAlmostEqual(random.TWOPI, 6.28318530718)
  516. self.assertAlmostEqual(random.LOG4, 1.38629436111989)
  517. self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627)
  518. def test__all__(self):
  519. # tests validity but not completeness of the __all__ list
  520. self.assertTrue(set(random.__all__) <= set(dir(random)))
  521. def test_random_subclass_with_kwargs(self):
  522. # SF bug #1486663 -- this used to erroneously raise a TypeError
  523. class Subclass(random.Random):
  524. def __init__(self, newarg=None):
  525. random.Random.__init__(self)
  526. Subclass(newarg=1)
  527. def test_main(verbose=None):
  528. testclasses = [WichmannHill_TestBasicOps,
  529. MersenneTwister_TestBasicOps,
  530. TestDistributions,
  531. TestModule]
  532. try:
  533. random.SystemRandom().random()
  534. except NotImplementedError:
  535. pass
  536. else:
  537. testclasses.append(SystemRandom_TestBasicOps)
  538. test_support.run_unittest(*testclasses)
  539. # verify reference counting
  540. import sys
  541. if verbose and hasattr(sys, "gettotalrefcount"):
  542. counts = [None] * 5
  543. for i in xrange(len(counts)):
  544. test_support.run_unittest(*testclasses)
  545. counts[i] = sys.gettotalrefcount()
  546. print counts
  547. if __name__ == "__main__":
  548. test_main(verbose=True)