Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: tools/auto_bisect/math_utils_test.py

Issue 736573002: Add unit tests for functions in math_utils.py (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated an incorrect comment. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/auto_bisect/math_utils.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import math 5 import math
6 import unittest 6 import unittest
7 7
8 import math_utils 8 import math_utils
9 9
10 10
11 class MathUtilsTest(unittest.TestCase): 11 class MathUtilsTest(unittest.TestCase):
12 """Tests for mathematical utility functions.""" 12 """Tests for mathematical utility functions."""
13 13
14 def testTruncatedMeanRaisesError(self): 14 def testTruncatedMean_EmptyList(self):
15 """TruncatedMean should raise an error when passed an empty list.""" 15 # TruncatedMean raises an error when passed an empty list.
16 with self.assertRaises(TypeError): 16 self.assertRaises(TypeError, math_utils.TruncatedMean, [], 0)
17 math_utils.TruncatedMean([], 0)
18 17
19 def testMeanSingleNum(self): 18 def testTruncatedMean_TruncateTooMuch(self):
20 """Tests the Mean function with a single number.""" 19 # An exception is raised if 50% or more is truncated from both sides.
20 self.assertRaises(TypeError, math_utils.TruncatedMean, [1, 2, 3], 1.0)
21 self.assertRaises(
22 ZeroDivisionError, math_utils.TruncatedMean, [1, 2, 3], 0.5)
23
24 def testTruncatedMean_AlwaysKeepsAtLeastTwoValues(self):
25 # If the length of the input is 1 or 2, nothing is truncated and
26 # the average is returned.
27 self.assertEqual(5.0, math_utils.TruncatedMean([5.0], 0.0))
28 self.assertEqual(5.0, math_utils.TruncatedMean([5.0], 0.25))
29 self.assertEqual(5.0, math_utils.TruncatedMean([5.0], 0.5))
30 self.assertEqual(5.5, math_utils.TruncatedMean([5.0, 6.0], 0.0))
31 self.assertEqual(5.5, math_utils.TruncatedMean([5.0, 6.0], 0.25))
32 self.assertEqual(5.5, math_utils.TruncatedMean([5.0, 6.0], 0.5))
33
34 def testTruncatedMean_Interquartile_NumValuesDivisibleByFour(self):
35 self.assertEqual(5.0, math_utils.TruncatedMean([1, 4, 6, 100], 0.25))
36 self.assertEqual(
37 6.5, math_utils.TruncatedMean([1, 2, 5, 6, 7, 8, 40, 50], 0.25))
38
39 def testTruncatedMean_Weighting(self):
40 # In the list [0, 1, 4, 5, 20, 100], when 25% of the list at the start
41 # and end are discarded, the part that's left is [1, 4, 5, 20], but
42 # first and last values are weighted so that they only count for half
43 # as much. So the truncated mean is (1/2 + 4 + 5 + 20/2) / 5.0.
44 self.assertEqual(6.5, (0.5 + 4 + 5 + 10) / 3.0)
45 self.assertEqual(6.5, math_utils.TruncatedMean([0, 1, 4, 5, 20, 100], 0.25))
46
47 def testMean_OneValue(self):
21 self.assertEqual(3.0, math_utils.Mean([3])) 48 self.assertEqual(3.0, math_utils.Mean([3]))
22 49
23 def testMeanShortList(self): 50 def testMean_ShortList(self):
24 """Tests the Mean function with a short list."""
25 self.assertEqual(0.5, math_utils.Mean([-3, 0, 1, 4])) 51 self.assertEqual(0.5, math_utils.Mean([-3, 0, 1, 4]))
26 52
27 def testMeanCompareAlternateImplementation(self): 53 def testMean_CompareAlternateImplementation(self):
28 """Tests Mean by comparing against an alternate implementation.""" 54 """Tests Mean by comparing against an alternate implementation."""
29 def AlternateMeanFunction(values): 55 def AlternateMean(values):
30 """Simple arithmetic mean function."""
31 return sum(values) / float(len(values)) 56 return sum(values) / float(len(values))
32 test_values_lists = [[1], [5, 6.5, 1.2, 3], [-3, 0, 1, 4], 57 test_value_lists = [
33 [-3, -1, 0.12, 0.752, 3.33, 8, 16, 32, 439]] 58 [1],
34 for values in test_values_lists: 59 [5, 6.5, 1.2, 3],
35 self.assertEqual( 60 [-3, 0, 1, 4],
36 AlternateMeanFunction(values), 61 [-3, -1, 0.12, 0.752, 3.33, 8, 16, 32, 439],
37 math_utils.Mean(values)) 62 ]
63 for value_list in test_value_lists:
64 self.assertEqual(AlternateMean(value_list), math_utils.Mean(value_list))
38 65
39 def testRelativeChange(self): 66 def testRelativeChange_NonZero(self):
40 """Tests the common cases for calculating relative change."""
41 # The change is relative to the first value, regardless of which is bigger. 67 # The change is relative to the first value, regardless of which is bigger.
42 self.assertEqual(0.5, math_utils.RelativeChange(1.0, 1.5)) 68 self.assertEqual(0.5, math_utils.RelativeChange(1.0, 1.5))
43 self.assertEqual(0.5, math_utils.RelativeChange(2.0, 1.0)) 69 self.assertEqual(0.5, math_utils.RelativeChange(2.0, 1.0))
44 70
45 def testRelativeChangeFromZero(self): 71 def testRelativeChange_FromZero(self):
46 """Tests what happens when relative change from zero is calculated."""
47 # If the first number is zero, then the result is not a number. 72 # If the first number is zero, then the result is not a number.
48 self.assertEqual(0, math_utils.RelativeChange(0, 0)) 73 self.assertEqual(0, math_utils.RelativeChange(0, 0))
49 self.assertTrue( 74 self.assertTrue(math.isnan(math_utils.RelativeChange(0, 1)))
50 math.isnan(math_utils.RelativeChange(0, 1))) 75 self.assertTrue(math.isnan(math_utils.RelativeChange(0, -1)))
51 self.assertTrue(
52 math.isnan(math_utils.RelativeChange(0, -1)))
53 76
54 def testRelativeChangeWithNegatives(self): 77 def testRelativeChange_Negative(self):
55 """Tests that relative change given is always positive.""" 78 # Note that the return value of RelativeChange is always positive.
56 self.assertEqual(3.0, math_utils.RelativeChange(-1, 2)) 79 self.assertEqual(3.0, math_utils.RelativeChange(-1, 2))
57 self.assertEqual(3.0, math_utils.RelativeChange(1, -2)) 80 self.assertEqual(3.0, math_utils.RelativeChange(1, -2))
58 self.assertEqual(1.0, math_utils.RelativeChange(-1, -2)) 81 self.assertEqual(1.0, math_utils.RelativeChange(-1, -2))
59 82
83 def testVariance_EmptyList(self):
84 self.assertRaises(TypeError, math_utils.Variance, [])
85
86 def testVariance_OneValue(self):
87 self.assertEqual(0, math_utils.Variance([0]))
88 self.assertEqual(0, math_utils.Variance([4.3]))
89
90 def testVariance_ShortList(self):
91 # Population variance is the average of squared deviations from the mean.
92 # The deviations from the mean in this example are [3.5, 0.5, -0.5, -3.5],
93 # and the squared deviations are [12.25, 0.25, 0.25, 12.25].
94 # With sample variance, however, 1 is subtracted from the sample size.
95 # So the sample variance is sum([12.25, 0.25, 0.25, 12.25]) / 3.0.
96 self.assertAlmostEqual(8.333333334, sum([12.25, 0.25, 0.25, 12.25]) / 3.0)
97 self.assertAlmostEqual(8.333333334, math_utils.Variance([-3, 0, 1, 4]))
98
99 def testStandardDeviation(self):
100 # Standard deviation is the square root of variance.
101 self.assertRaises(TypeError, math_utils.StandardDeviation, [])
102 self.assertEqual(0.0, math_utils.StandardDeviation([4.3]))
103 self.assertAlmostEqual(2.88675135, math.sqrt(8.33333333333333))
104 self.assertAlmostEqual(2.88675135,
105 math_utils.StandardDeviation([-3, 0, 1, 4]))
106
107 def testStandardError(self):
108 # Standard error is std. dev. divided by square root of sample size.
109 self.assertEqual(0.0, math_utils.StandardError([]))
110 self.assertEqual(0.0, math_utils.StandardError([4.3]))
111 self.assertAlmostEqual(1.44337567, 2.88675135 / math.sqrt(4))
112 self.assertAlmostEqual(1.44337567, math_utils.StandardError([-3, 0, 1, 4]))
60 113
61 if __name__ == '__main__': 114 if __name__ == '__main__':
62 unittest.main() 115 unittest.main()
OLDNEW
« no previous file with comments | « tools/auto_bisect/math_utils.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698