blob: 6bb2112f29748bbf3ea943fc18c26f3b6a0d3b87 [file] [log] [blame]
Raymond Hettingerd2305502003-01-16 12:02:35 +00001import unittest
2from test import test_support
Raymond Hettingera9f18dc2003-01-16 13:02:25 +00003from bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect
Raymond Hettinger0c410272004-01-05 10:13:35 +00004from UserList import UserList
Tim Peters36cdad12000-12-29 02:06:45 +00005
Raymond Hettingerd2305502003-01-16 12:02:35 +00006class TestBisect(unittest.TestCase):
Tim Peters36cdad12000-12-29 02:06:45 +00007
Raymond Hettingerd2305502003-01-16 12:02:35 +00008 precomputedCases = [
9 (bisect_right, [], 1, 0),
10 (bisect_right, [1], 0, 0),
11 (bisect_right, [1], 1, 1),
12 (bisect_right, [1], 2, 1),
13 (bisect_right, [1, 1], 0, 0),
14 (bisect_right, [1, 1], 1, 2),
15 (bisect_right, [1, 1], 2, 2),
16 (bisect_right, [1, 1, 1], 0, 0),
17 (bisect_right, [1, 1, 1], 1, 3),
18 (bisect_right, [1, 1, 1], 2, 3),
19 (bisect_right, [1, 1, 1, 1], 0, 0),
20 (bisect_right, [1, 1, 1, 1], 1, 4),
21 (bisect_right, [1, 1, 1, 1], 2, 4),
22 (bisect_right, [1, 2], 0, 0),
23 (bisect_right, [1, 2], 1, 1),
24 (bisect_right, [1, 2], 1.5, 1),
25 (bisect_right, [1, 2], 2, 2),
26 (bisect_right, [1, 2], 3, 2),
27 (bisect_right, [1, 1, 2, 2], 0, 0),
28 (bisect_right, [1, 1, 2, 2], 1, 2),
29 (bisect_right, [1, 1, 2, 2], 1.5, 2),
30 (bisect_right, [1, 1, 2, 2], 2, 4),
31 (bisect_right, [1, 1, 2, 2], 3, 4),
32 (bisect_right, [1, 2, 3], 0, 0),
33 (bisect_right, [1, 2, 3], 1, 1),
34 (bisect_right, [1, 2, 3], 1.5, 1),
35 (bisect_right, [1, 2, 3], 2, 2),
36 (bisect_right, [1, 2, 3], 2.5, 2),
37 (bisect_right, [1, 2, 3], 3, 3),
38 (bisect_right, [1, 2, 3], 4, 3),
39 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
40 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
41 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
42 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
43 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
44 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
45 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
46 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
47 (bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
Tim Peters36cdad12000-12-29 02:06:45 +000048
Raymond Hettingerd2305502003-01-16 12:02:35 +000049 (bisect_left, [], 1, 0),
50 (bisect_left, [1], 0, 0),
51 (bisect_left, [1], 1, 0),
52 (bisect_left, [1], 2, 1),
53 (bisect_left, [1, 1], 0, 0),
54 (bisect_left, [1, 1], 1, 0),
55 (bisect_left, [1, 1], 2, 2),
56 (bisect_left, [1, 1, 1], 0, 0),
57 (bisect_left, [1, 1, 1], 1, 0),
58 (bisect_left, [1, 1, 1], 2, 3),
59 (bisect_left, [1, 1, 1, 1], 0, 0),
60 (bisect_left, [1, 1, 1, 1], 1, 0),
61 (bisect_left, [1, 1, 1, 1], 2, 4),
62 (bisect_left, [1, 2], 0, 0),
63 (bisect_left, [1, 2], 1, 0),
64 (bisect_left, [1, 2], 1.5, 1),
65 (bisect_left, [1, 2], 2, 1),
66 (bisect_left, [1, 2], 3, 2),
67 (bisect_left, [1, 1, 2, 2], 0, 0),
68 (bisect_left, [1, 1, 2, 2], 1, 0),
69 (bisect_left, [1, 1, 2, 2], 1.5, 2),
70 (bisect_left, [1, 1, 2, 2], 2, 2),
71 (bisect_left, [1, 1, 2, 2], 3, 4),
72 (bisect_left, [1, 2, 3], 0, 0),
73 (bisect_left, [1, 2, 3], 1, 0),
74 (bisect_left, [1, 2, 3], 1.5, 1),
75 (bisect_left, [1, 2, 3], 2, 1),
76 (bisect_left, [1, 2, 3], 2.5, 2),
77 (bisect_left, [1, 2, 3], 3, 2),
78 (bisect_left, [1, 2, 3], 4, 3),
79 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
80 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
81 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
82 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
83 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
84 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
85 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
86 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
87 (bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
88 ]
Tim Peters36cdad12000-12-29 02:06:45 +000089
Raymond Hettingerd2305502003-01-16 12:02:35 +000090 def test_precomputed(self):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +000091 for func, data, elem, expected in self.precomputedCases:
92 self.assertEqual(func(data, elem), expected)
Raymond Hettinger0c410272004-01-05 10:13:35 +000093 self.assertEqual(func(UserList(data), elem), expected)
Raymond Hettingerd2305502003-01-16 12:02:35 +000094
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +000095 def test_random(self, n=25):
Raymond Hettinger44223752003-01-16 12:31:36 +000096 from random import randrange
97 for i in xrange(n):
98 data = [randrange(0, n, 2) for j in xrange(i)]
99 data.sort()
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000100 elem = randrange(-1, n+1)
Raymond Hettinger44223752003-01-16 12:31:36 +0000101 ip = bisect_left(data, elem)
102 if ip < len(data):
103 self.failUnless(elem <= data[ip])
104 if ip > 0:
105 self.failUnless(data[ip-1] < elem)
106 ip = bisect_right(data, elem)
107 if ip < len(data):
108 self.failUnless(elem < data[ip])
109 if ip > 0:
110 self.failUnless(data[ip-1] <= elem)
111
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000112 def test_optionalSlicing(self):
Raymond Hettinger6aa1c3f2003-01-16 14:00:15 +0000113 for func, data, elem, expected in self.precomputedCases:
114 for lo in xrange(4):
115 lo = min(len(data), lo)
116 for hi in xrange(3,8):
117 hi = min(len(data), hi)
118 ip = func(data, elem, lo, hi)
119 self.failUnless(lo <= ip <= hi)
120 if func is bisect_left and ip < hi:
121 self.failUnless(elem <= data[ip])
122 if func is bisect_left and ip > lo:
123 self.failUnless(data[ip-1] < elem)
124 if func is bisect_right and ip < hi:
125 self.failUnless(elem < data[ip])
126 if func is bisect_right and ip > lo:
127 self.failUnless(data[ip-1] <= elem)
128 self.assertEqual(ip, max(lo, min(hi, expected)))
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000129
130 def test_backcompatibility(self):
131 self.assertEqual(bisect, bisect_right)
132
Raymond Hettingerd2305502003-01-16 12:02:35 +0000133#==============================================================================
134
135class TestInsort(unittest.TestCase):
136
Raymond Hettinger0c410272004-01-05 10:13:35 +0000137 def test_vsBuiltinSort(self, n=500):
Raymond Hettingerd2305502003-01-16 12:02:35 +0000138 from random import choice
Raymond Hettinger0c410272004-01-05 10:13:35 +0000139 for insorted in (list(), UserList()):
140 for i in xrange(n):
141 digit = choice("0123456789")
142 if digit in "02468":
143 f = insort_left
144 else:
145 f = insort_right
146 f(insorted, digit)
147 self.assertEqual(sorted(insorted), insorted)
Raymond Hettingerd2305502003-01-16 12:02:35 +0000148
Raymond Hettingera9f18dc2003-01-16 13:02:25 +0000149 def test_backcompatibility(self):
150 self.assertEqual(insort, insort_right)
151
Raymond Hettingerd2305502003-01-16 12:02:35 +0000152#==============================================================================
153
Raymond Hettinger44223752003-01-16 12:31:36 +0000154libreftest = """
155Example from the Library Reference: Doc/lib/libbisect.tex
156
157The bisect() function is generally useful for categorizing numeric data.
158This example uses bisect() to look up a letter grade for an exam total
159(say) based on a set of ordered numeric breakpoints: 85 and up is an `A',
16075..84 is a `B', etc.
161
162 >>> grades = "FEDCBA"
163 >>> breakpoints = [30, 44, 66, 75, 85]
164 >>> from bisect import bisect
165 >>> def grade(total):
166 ... return grades[bisect(breakpoints, total)]
167 ...
168 >>> grade(66)
169 'C'
170 >>> map(grade, [33, 99, 77, 44, 12, 88])
171 ['E', 'A', 'B', 'D', 'F', 'A']
172
Raymond Hettinger44223752003-01-16 12:31:36 +0000173"""
174
Raymond Hettingerd2305502003-01-16 12:02:35 +0000175#------------------------------------------------------------------------------
176
Raymond Hettinger44223752003-01-16 12:31:36 +0000177__test__ = {'libreftest' : libreftest}
178
Raymond Hettingerd2305502003-01-16 12:02:35 +0000179def test_main(verbose=None):
180 from test import test_bisect
Walter Dörwald21d3a322003-05-01 17:45:56 +0000181 test_support.run_unittest(TestBisect, TestInsort)
Raymond Hettinger44223752003-01-16 12:31:36 +0000182 test_support.run_doctest(test_bisect, verbose)
Raymond Hettingerd2305502003-01-16 12:02:35 +0000183
184if __name__ == "__main__":
185 test_main(verbose=True)