Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2afb598

Browse files
rhettingermiss-islington
authored andcommitted
bpo-36324: NormalDist() add more tests and update comments (GH-12476)
* Improve coverage. * Note inherent limitations of the accuracy tests https://bugs.python.org/issue36324
1 parent aa3ecb8 commit 2afb598

1 file changed

Lines changed: 44 additions & 24 deletions

File tree

Lib/test/test_statistics.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,6 +2040,13 @@ def test_compare_to_variance(self):
20402040

20412041
class TestNormalDist(unittest.TestCase):
20422042

2043+
# General note on precision: The pdf(), cdf(), and overlap() methods
2044+
# depend on functions in the math libraries that do not make
2045+
# explicit accuracy guarantees. Accordingly, some of the accuracy
2046+
# tests below may fail if the underlying math functions are
2047+
# inaccurate. There isn't much we can do about this short of
2048+
# implementing our own implementations from scratch.
2049+
20432050
def test_slots(self):
20442051
nd = statistics.NormalDist(300, 23)
20452052
with self.assertRaises(TypeError):
@@ -2062,6 +2069,12 @@ def test_instantiation_and_attributes(self):
20622069
with self.assertRaises(statistics.StatisticsError):
20632070
statistics.NormalDist(500, -10)
20642071

2072+
# verify that subclass type is honored
2073+
class NewNormalDist(statistics.NormalDist):
2074+
pass
2075+
nnd = NewNormalDist(200, 5)
2076+
self.assertEqual(type(nnd), NewNormalDist)
2077+
20652078
def test_alternative_constructor(self):
20662079
NormalDist = statistics.NormalDist
20672080
data = [96, 107, 90, 92, 110]
@@ -2077,6 +2090,12 @@ def test_alternative_constructor(self):
20772090
with self.assertRaises(statistics.StatisticsError):
20782091
NormalDist.from_samples([10]) # only one input
20792092

2093+
# verify that subclass type is honored
2094+
class NewNormalDist(NormalDist):
2095+
pass
2096+
nnd = NewNormalDist.from_samples(data)
2097+
self.assertEqual(type(nnd), NewNormalDist)
2098+
20802099
def test_sample_generation(self):
20812100
NormalDist = statistics.NormalDist
20822101
mu, sigma = 10_000, 3.0
@@ -2099,12 +2118,6 @@ def test_sample_generation(self):
20992118
self.assertEqual(data2, data4)
21002119
self.assertNotEqual(data1, data2)
21012120

2102-
# verify that subclass type is honored
2103-
class NewNormalDist(NormalDist):
2104-
pass
2105-
nnd = NewNormalDist(200, 5)
2106-
self.assertEqual(type(nnd), NewNormalDist)
2107-
21082121
def test_pdf(self):
21092122
NormalDist = statistics.NormalDist
21102123
X = NormalDist(100, 15)
@@ -2151,8 +2164,8 @@ def test_cdf(self):
21512164
self.assertEqual(set(map(type, cdfs)), {float})
21522165
# Verify montonic
21532166
self.assertEqual(cdfs, sorted(cdfs))
2154-
# Verify center
2155-
self.assertAlmostEqual(X.cdf(100), 0.50)
2167+
# Verify center (should be exact)
2168+
self.assertEqual(X.cdf(100), 0.50)
21562169
# Check against a table of known values
21572170
# https://en.wikipedia.org/wiki/Standard_normal_table#Cumulative
21582171
Z = NormalDist()
@@ -2216,10 +2229,11 @@ def test_inv_cdf(self):
22162229
p = 1.0 - p
22172230
self.assertAlmostEqual(iq.cdf(iq.inv_cdf(p)), p)
22182231

2219-
# Now apply cdf() first. At six sigmas, the round-trip
2220-
# loses a lot of precision, so only check to 6 places.
2221-
for x in range(10, 190):
2222-
self.assertAlmostEqual(iq.inv_cdf(iq.cdf(x)), x, places=6)
2232+
# Now apply cdf() first. Near the tails, the round-trip loses
2233+
# precision and is ill-conditioned (small changes in the inputs
2234+
# give large changes in the output), so only check to 5 places.
2235+
for x in range(200):
2236+
self.assertAlmostEqual(iq.inv_cdf(iq.cdf(x)), x, places=5)
22232237

22242238
# Error cases:
22252239
with self.assertRaises(statistics.StatisticsError):
@@ -2237,6 +2251,9 @@ def test_inv_cdf(self):
22372251
iq.sigma = -0.1 # sigma under zero
22382252
iq.inv_cdf(0.5)
22392253

2254+
# Special values
2255+
self.assertTrue(math.isnan(Z.inv_cdf(float('NaN'))))
2256+
22402257
def test_overlap(self):
22412258
NormalDist = statistics.NormalDist
22422259

@@ -2275,6 +2292,7 @@ def overlap_numeric(X, Y, *, steps=8_192, z=5):
22752292
(NormalDist(-100, 15), NormalDist(110, 15)),
22762293
(NormalDist(-100, 15), NormalDist(-110, 15)),
22772294
# Misc cases with unequal standard deviations
2295+
(NormalDist(100, 12), NormalDist(100, 15)),
22782296
(NormalDist(100, 12), NormalDist(110, 15)),
22792297
(NormalDist(100, 12), NormalDist(150, 15)),
22802298
(NormalDist(100, 12), NormalDist(150, 35)),
@@ -2305,18 +2323,6 @@ def test_properties(self):
23052323
self.assertEqual(X.stdev, 15)
23062324
self.assertEqual(X.variance, 225)
23072325

2308-
def test_unary_operations(self):
2309-
NormalDist = statistics.NormalDist
2310-
X = NormalDist(100, 12)
2311-
Y = +X
2312-
self.assertIsNot(X, Y)
2313-
self.assertEqual(X.mu, Y.mu)
2314-
self.assertEqual(X.sigma, Y.sigma)
2315-
Y = -X
2316-
self.assertIsNot(X, Y)
2317-
self.assertEqual(X.mu, -Y.mu)
2318-
self.assertEqual(X.sigma, Y.sigma)
2319-
23202326
def test_same_type_addition_and_subtraction(self):
23212327
NormalDist = statistics.NormalDist
23222328
X = NormalDist(100, 12)
@@ -2340,13 +2346,27 @@ def test_translation_and_scaling(self):
23402346
with self.assertRaises(TypeError): # __rtruediv__
23412347
y / X
23422348

2349+
def test_unary_operations(self):
2350+
NormalDist = statistics.NormalDist
2351+
X = NormalDist(100, 12)
2352+
Y = +X
2353+
self.assertIsNot(X, Y)
2354+
self.assertEqual(X.mu, Y.mu)
2355+
self.assertEqual(X.sigma, Y.sigma)
2356+
Y = -X
2357+
self.assertIsNot(X, Y)
2358+
self.assertEqual(X.mu, -Y.mu)
2359+
self.assertEqual(X.sigma, Y.sigma)
2360+
23432361
def test_equality(self):
23442362
NormalDist = statistics.NormalDist
23452363
nd1 = NormalDist()
23462364
nd2 = NormalDist(2, 4)
23472365
nd3 = NormalDist()
2366+
nd4 = NormalDist(2, 4)
23482367
self.assertNotEqual(nd1, nd2)
23492368
self.assertEqual(nd1, nd3)
2369+
self.assertEqual(nd2, nd4)
23502370

23512371
# Test NotImplemented when types are different
23522372
class A:

0 commit comments

Comments
 (0)