Commit 2b59b161 authored by Raymond Hettinger's avatar Raymond Hettinger

* Migrate sample distribution test from random.py to test_random.py.

* Use Sets module to more clearly articulate a couple of tests.
parent a372501f
...@@ -743,9 +743,6 @@ def _test_generator(n, funccall): ...@@ -743,9 +743,6 @@ def _test_generator(n, funccall):
print 'avg %g, stddev %g, min %g, max %g' % \ print 'avg %g, stddev %g, min %g, max %g' % \
(avg, stddev, smallest, largest) (avg, stddev, smallest, largest)
def _sample_generator(n, k):
# Return a fixed element from the sample. Validates random ordering.
return sample(xrange(n), k)[k//2]
def _test(N=2000): def _test(N=2000):
_test_generator(N, 'random()') _test_generator(N, 'random()')
...@@ -764,8 +761,6 @@ def _test(N=2000): ...@@ -764,8 +761,6 @@ def _test(N=2000):
_test_generator(N, 'gammavariate(200.0, 1.0)') _test_generator(N, 'gammavariate(200.0, 1.0)')
_test_generator(N, 'gauss(0.0, 1.0)') _test_generator(N, 'gauss(0.0, 1.0)')
_test_generator(N, 'betavariate(3.0, 3.0)') _test_generator(N, 'betavariate(3.0, 3.0)')
_test_generator(N, '_sample_generator(50, 5)') # expected s.d.: 14.4
_test_generator(N, '_sample_generator(50, 45)') # expected s.d.: 14.4
# Create one instance, seeded from current time, and export its methods # Create one instance, seeded from current time, and export its methods
# as module-level functions. The functions share state across all uses # as module-level functions. The functions share state across all uses
......
...@@ -4,6 +4,7 @@ import unittest ...@@ -4,6 +4,7 @@ import unittest
import random import random
import time import time
from math import log, exp, sqrt, pi from math import log, exp, sqrt, pi
from sets import Set
from test import test_support from test import test_support
class TestBasicOps(unittest.TestCase): class TestBasicOps(unittest.TestCase):
...@@ -61,11 +62,29 @@ class TestBasicOps(unittest.TestCase): ...@@ -61,11 +62,29 @@ class TestBasicOps(unittest.TestCase):
for k in xrange(N+1): for k in xrange(N+1):
s = self.gen.sample(population, k) s = self.gen.sample(population, k)
self.assertEqual(len(s), k) self.assertEqual(len(s), k)
uniq = dict.fromkeys(s) uniq = Set(s)
self.assertEqual(len(uniq), k) self.assertEqual(len(uniq), k)
self.failIf(None in uniq) self.failUnless(uniq <= Set(population))
self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0 self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0
def test_sample_distribution(self):
# For the entire allowable range of 0 <= k <= N, validate that
# sample generates all possible permutations
n = 5
pop = range(n)
trials = 10000 # large num prevents false negatives without slowing normal case
def factorial(n):
return n==0 and 1 or n * factorial(n-1)
for k in xrange(n):
expected = factorial(n) / factorial(n-k)
perms = {}
for i in xrange(trials):
perms[tuple(self.gen.sample(pop, k))] = None
if len(perms) == expected:
break
else:
self.fail()
def test_gauss(self): def test_gauss(self):
# Ensure that the seed() method initializes all the hidden state. In # 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 # particular, through 2.2.1 it failed to reset a piece of state used
...@@ -250,9 +269,7 @@ class TestModule(unittest.TestCase): ...@@ -250,9 +269,7 @@ class TestModule(unittest.TestCase):
def test__all__(self): def test__all__(self):
# tests validity but not completeness of the __all__ list # tests validity but not completeness of the __all__ list
defined = dict.fromkeys(dir(random)) self.failUnless(Set(random.__all__) <= Set(dir(random)))
for entry in random.__all__:
self.failUnless(entry in defined)
def test_main(): def test_main():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment