* Migrate sample distribution test from random.py to test_random.py.
authorRaymond Hettinger <python@rcn.com>
Fri, 17 Jan 2003 17:23:23 +0000 (17:23 +0000)
committerRaymond Hettinger <python@rcn.com>
Fri, 17 Jan 2003 17:23:23 +0000 (17:23 +0000)
* Use Sets module to more clearly articulate a couple of tests.

Lib/random.py
Lib/test/test_random.py

index 3db1f1a3facd8993e4abef867237909dc1a83c2c..2d4859cf02e117f2b06b7ec37c2c1c9e91bd7f0a 100644 (file)
@@ -743,9 +743,6 @@ def _test_generator(n, funccall):
     print 'avg %g, stddev %g, min %g, max %g' % \
               (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):
     _test_generator(N, 'random()')
@@ -764,8 +761,6 @@ def _test(N=2000):
     _test_generator(N, 'gammavariate(200.0, 1.0)')
     _test_generator(N, 'gauss(0.0, 1.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
 # as module-level functions.  The functions share state across all uses
index 1f6abfeb31f6b1384150cf6aa06b5efa784cf33f..cc9b44e77b6f466d8ad4c405c9642d5fd947e4f8 100644 (file)
@@ -4,6 +4,7 @@ import unittest
 import random
 import time
 from math import log, exp, sqrt, pi
+from sets import Set
 from test import test_support
 
 class TestBasicOps(unittest.TestCase):
@@ -61,11 +62,29 @@ class TestBasicOps(unittest.TestCase):
         for k in xrange(N+1):
             s = self.gen.sample(population, k)
             self.assertEqual(len(s), k)
-            uniq = dict.fromkeys(s)
+            uniq = Set(s)
             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
 
+    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):
         # 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
@@ -250,9 +269,7 @@ class TestModule(unittest.TestCase):
 
     def test__all__(self):
         # tests validity but not completeness of the __all__ list
-        defined = dict.fromkeys(dir(random))
-        for entry in random.__all__:
-            self.failUnless(entry in defined)
+        self.failUnless(Set(random.__all__) <= Set(dir(random)))
 
 def test_main():
     suite = unittest.TestSuite()