cpython/Lib/test/test_bisect.py

259 lines
9.5 KiB
Python
Raw Normal View History

import unittest
from test import test_support
from bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect
from UserList import UserList
class TestBisect(unittest.TestCase):
precomputedCases = [
(bisect_right, [], 1, 0),
(bisect_right, [1], 0, 0),
(bisect_right, [1], 1, 1),
(bisect_right, [1], 2, 1),
(bisect_right, [1, 1], 0, 0),
(bisect_right, [1, 1], 1, 2),
(bisect_right, [1, 1], 2, 2),
(bisect_right, [1, 1, 1], 0, 0),
(bisect_right, [1, 1, 1], 1, 3),
(bisect_right, [1, 1, 1], 2, 3),
(bisect_right, [1, 1, 1, 1], 0, 0),
(bisect_right, [1, 1, 1, 1], 1, 4),
(bisect_right, [1, 1, 1, 1], 2, 4),
(bisect_right, [1, 2], 0, 0),
(bisect_right, [1, 2], 1, 1),
(bisect_right, [1, 2], 1.5, 1),
(bisect_right, [1, 2], 2, 2),
(bisect_right, [1, 2], 3, 2),
(bisect_right, [1, 1, 2, 2], 0, 0),
(bisect_right, [1, 1, 2, 2], 1, 2),
(bisect_right, [1, 1, 2, 2], 1.5, 2),
(bisect_right, [1, 1, 2, 2], 2, 4),
(bisect_right, [1, 1, 2, 2], 3, 4),
(bisect_right, [1, 2, 3], 0, 0),
(bisect_right, [1, 2, 3], 1, 1),
(bisect_right, [1, 2, 3], 1.5, 1),
(bisect_right, [1, 2, 3], 2, 2),
(bisect_right, [1, 2, 3], 2.5, 2),
(bisect_right, [1, 2, 3], 3, 3),
(bisect_right, [1, 2, 3], 4, 3),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 1),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 3),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 6),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 10),
(bisect_right, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10),
(bisect_left, [], 1, 0),
(bisect_left, [1], 0, 0),
(bisect_left, [1], 1, 0),
(bisect_left, [1], 2, 1),
(bisect_left, [1, 1], 0, 0),
(bisect_left, [1, 1], 1, 0),
(bisect_left, [1, 1], 2, 2),
(bisect_left, [1, 1, 1], 0, 0),
(bisect_left, [1, 1, 1], 1, 0),
(bisect_left, [1, 1, 1], 2, 3),
(bisect_left, [1, 1, 1, 1], 0, 0),
(bisect_left, [1, 1, 1, 1], 1, 0),
(bisect_left, [1, 1, 1, 1], 2, 4),
(bisect_left, [1, 2], 0, 0),
(bisect_left, [1, 2], 1, 0),
(bisect_left, [1, 2], 1.5, 1),
(bisect_left, [1, 2], 2, 1),
(bisect_left, [1, 2], 3, 2),
(bisect_left, [1, 1, 2, 2], 0, 0),
(bisect_left, [1, 1, 2, 2], 1, 0),
(bisect_left, [1, 1, 2, 2], 1.5, 2),
(bisect_left, [1, 1, 2, 2], 2, 2),
(bisect_left, [1, 1, 2, 2], 3, 4),
(bisect_left, [1, 2, 3], 0, 0),
(bisect_left, [1, 2, 3], 1, 0),
(bisect_left, [1, 2, 3], 1.5, 1),
(bisect_left, [1, 2, 3], 2, 1),
(bisect_left, [1, 2, 3], 2.5, 2),
(bisect_left, [1, 2, 3], 3, 2),
(bisect_left, [1, 2, 3], 4, 3),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 0, 0),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1, 0),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 1.5, 1),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2, 1),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 2.5, 3),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3, 3),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 3.5, 6),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 4, 6),
(bisect_left, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4], 5, 10)
]
def test_precomputed(self):
for func, data, elem, expected in self.precomputedCases:
self.assertEqual(func(data, elem), expected)
self.assertEqual(func(UserList(data), elem), expected)
def test_random(self, n=25):
from random import randrange
Merged revisions 55007-55179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r55077 | guido.van.rossum | 2007-05-02 11:54:37 -0700 (Wed, 02 May 2007) | 2 lines Use the new print syntax, at least. ........ r55142 | fred.drake | 2007-05-04 21:27:30 -0700 (Fri, 04 May 2007) | 1 line remove old cruftiness ........ r55143 | fred.drake | 2007-05-04 21:52:16 -0700 (Fri, 04 May 2007) | 1 line make this work with the new Python ........ r55162 | neal.norwitz | 2007-05-06 22:29:18 -0700 (Sun, 06 May 2007) | 1 line Get asdl code gen working with Python 2.3. Should continue to work with 3.0 ........ r55164 | neal.norwitz | 2007-05-07 00:00:38 -0700 (Mon, 07 May 2007) | 1 line Verify checkins to p3yk (sic) branch go to 3000 list. ........ r55166 | neal.norwitz | 2007-05-07 00:12:35 -0700 (Mon, 07 May 2007) | 1 line Fix this test so it runs again by importing warnings_test properly. ........ r55167 | neal.norwitz | 2007-05-07 01:03:22 -0700 (Mon, 07 May 2007) | 8 lines So long xrange. range() now supports values that are outside -sys.maxint to sys.maxint. floats raise a TypeError. This has been sitting for a long time. It probably has some problems and needs cleanup. Objects/rangeobject.c now uses 4-space indents since it is almost completely new. ........ r55171 | guido.van.rossum | 2007-05-07 10:21:26 -0700 (Mon, 07 May 2007) | 4 lines Fix two tests that were previously depending on significant spaces at the end of a line (and before that on Python 2.x print behavior that has no exact equivalent in 3.0). ........
2007-05-07 19:24:25 -03:00
for i in range(n):
data = [randrange(0, n, 2) for j in range(i)]
data.sort()
elem = randrange(-1, n+1)
ip = bisect_left(data, elem)
if ip < len(data):
self.failUnless(elem <= data[ip])
if ip > 0:
self.failUnless(data[ip-1] < elem)
ip = bisect_right(data, elem)
if ip < len(data):
self.failUnless(elem < data[ip])
if ip > 0:
self.failUnless(data[ip-1] <= elem)
def test_optionalSlicing(self):
for func, data, elem, expected in self.precomputedCases:
Merged revisions 55007-55179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r55077 | guido.van.rossum | 2007-05-02 11:54:37 -0700 (Wed, 02 May 2007) | 2 lines Use the new print syntax, at least. ........ r55142 | fred.drake | 2007-05-04 21:27:30 -0700 (Fri, 04 May 2007) | 1 line remove old cruftiness ........ r55143 | fred.drake | 2007-05-04 21:52:16 -0700 (Fri, 04 May 2007) | 1 line make this work with the new Python ........ r55162 | neal.norwitz | 2007-05-06 22:29:18 -0700 (Sun, 06 May 2007) | 1 line Get asdl code gen working with Python 2.3. Should continue to work with 3.0 ........ r55164 | neal.norwitz | 2007-05-07 00:00:38 -0700 (Mon, 07 May 2007) | 1 line Verify checkins to p3yk (sic) branch go to 3000 list. ........ r55166 | neal.norwitz | 2007-05-07 00:12:35 -0700 (Mon, 07 May 2007) | 1 line Fix this test so it runs again by importing warnings_test properly. ........ r55167 | neal.norwitz | 2007-05-07 01:03:22 -0700 (Mon, 07 May 2007) | 8 lines So long xrange. range() now supports values that are outside -sys.maxint to sys.maxint. floats raise a TypeError. This has been sitting for a long time. It probably has some problems and needs cleanup. Objects/rangeobject.c now uses 4-space indents since it is almost completely new. ........ r55171 | guido.van.rossum | 2007-05-07 10:21:26 -0700 (Mon, 07 May 2007) | 4 lines Fix two tests that were previously depending on significant spaces at the end of a line (and before that on Python 2.x print behavior that has no exact equivalent in 3.0). ........
2007-05-07 19:24:25 -03:00
for lo in range(4):
lo = min(len(data), lo)
Merged revisions 55007-55179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r55077 | guido.van.rossum | 2007-05-02 11:54:37 -0700 (Wed, 02 May 2007) | 2 lines Use the new print syntax, at least. ........ r55142 | fred.drake | 2007-05-04 21:27:30 -0700 (Fri, 04 May 2007) | 1 line remove old cruftiness ........ r55143 | fred.drake | 2007-05-04 21:52:16 -0700 (Fri, 04 May 2007) | 1 line make this work with the new Python ........ r55162 | neal.norwitz | 2007-05-06 22:29:18 -0700 (Sun, 06 May 2007) | 1 line Get asdl code gen working with Python 2.3. Should continue to work with 3.0 ........ r55164 | neal.norwitz | 2007-05-07 00:00:38 -0700 (Mon, 07 May 2007) | 1 line Verify checkins to p3yk (sic) branch go to 3000 list. ........ r55166 | neal.norwitz | 2007-05-07 00:12:35 -0700 (Mon, 07 May 2007) | 1 line Fix this test so it runs again by importing warnings_test properly. ........ r55167 | neal.norwitz | 2007-05-07 01:03:22 -0700 (Mon, 07 May 2007) | 8 lines So long xrange. range() now supports values that are outside -sys.maxint to sys.maxint. floats raise a TypeError. This has been sitting for a long time. It probably has some problems and needs cleanup. Objects/rangeobject.c now uses 4-space indents since it is almost completely new. ........ r55171 | guido.van.rossum | 2007-05-07 10:21:26 -0700 (Mon, 07 May 2007) | 4 lines Fix two tests that were previously depending on significant spaces at the end of a line (and before that on Python 2.x print behavior that has no exact equivalent in 3.0). ........
2007-05-07 19:24:25 -03:00
for hi in range(3,8):
hi = min(len(data), hi)
ip = func(data, elem, lo, hi)
self.failUnless(lo <= ip <= hi)
if func is bisect_left and ip < hi:
self.failUnless(elem <= data[ip])
if func is bisect_left and ip > lo:
self.failUnless(data[ip-1] < elem)
if func is bisect_right and ip < hi:
self.failUnless(elem < data[ip])
if func is bisect_right and ip > lo:
self.failUnless(data[ip-1] <= elem)
self.assertEqual(ip, max(lo, min(hi, expected)))
def test_backcompatibility(self):
self.assertEqual(bisect, bisect_right)
def test_keyword_args(self):
data = [10, 20, 30, 40, 50]
self.assertEqual(bisect_left(a=data, x=25, lo=1, hi=3), 2)
self.assertEqual(bisect_right(a=data, x=25, lo=1, hi=3), 2)
self.assertEqual(bisect(a=data, x=25, lo=1, hi=3), 2)
insort_left(a=data, x=25, lo=1, hi=3)
insort_right(a=data, x=25, lo=1, hi=3)
insort(a=data, x=25, lo=1, hi=3)
self.assertEqual(data, [10, 20, 25, 25, 25, 30, 40, 50])
#==============================================================================
class TestInsort(unittest.TestCase):
def test_vsBuiltinSort(self, n=500):
from random import choice
for insorted in (list(), UserList()):
Merged revisions 55007-55179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r55077 | guido.van.rossum | 2007-05-02 11:54:37 -0700 (Wed, 02 May 2007) | 2 lines Use the new print syntax, at least. ........ r55142 | fred.drake | 2007-05-04 21:27:30 -0700 (Fri, 04 May 2007) | 1 line remove old cruftiness ........ r55143 | fred.drake | 2007-05-04 21:52:16 -0700 (Fri, 04 May 2007) | 1 line make this work with the new Python ........ r55162 | neal.norwitz | 2007-05-06 22:29:18 -0700 (Sun, 06 May 2007) | 1 line Get asdl code gen working with Python 2.3. Should continue to work with 3.0 ........ r55164 | neal.norwitz | 2007-05-07 00:00:38 -0700 (Mon, 07 May 2007) | 1 line Verify checkins to p3yk (sic) branch go to 3000 list. ........ r55166 | neal.norwitz | 2007-05-07 00:12:35 -0700 (Mon, 07 May 2007) | 1 line Fix this test so it runs again by importing warnings_test properly. ........ r55167 | neal.norwitz | 2007-05-07 01:03:22 -0700 (Mon, 07 May 2007) | 8 lines So long xrange. range() now supports values that are outside -sys.maxint to sys.maxint. floats raise a TypeError. This has been sitting for a long time. It probably has some problems and needs cleanup. Objects/rangeobject.c now uses 4-space indents since it is almost completely new. ........ r55171 | guido.van.rossum | 2007-05-07 10:21:26 -0700 (Mon, 07 May 2007) | 4 lines Fix two tests that were previously depending on significant spaces at the end of a line (and before that on Python 2.x print behavior that has no exact equivalent in 3.0). ........
2007-05-07 19:24:25 -03:00
for i in range(n):
digit = choice("0123456789")
if digit in "02468":
f = insort_left
else:
f = insort_right
f(insorted, digit)
self.assertEqual(sorted(insorted), insorted)
def test_backcompatibility(self):
self.assertEqual(insort, insort_right)
#==============================================================================
class LenOnly:
"Dummy sequence class defining __len__ but not __getitem__."
def __len__(self):
return 10
class GetOnly:
"Dummy sequence class defining __getitem__ but not __len__."
def __getitem__(self, ndx):
return 10
class CmpErr:
"Dummy element that always raises an error during comparison"
Restructure comparison dramatically. There is no longer a default *ordering* between objects; there is only a default equality test (defined by an object being equal to itself only). Read the comment in object.c. The current implementation never uses a three-way comparison to compute a rich comparison, but it does use a rich comparison to compute a three-way comparison. I'm not quite done ripping out all the calls to PyObject_Compare/Cmp, or replacing tp_compare implementations with tp_richcompare implementations; but much of that has happened (to make most unit tests pass). The following tests still fail, because I need help deciding or understanding: test_codeop -- depends on comparing code objects test_datetime -- need Tim Peters' opinion test_marshal -- depends on comparing code objects test_mutants -- need help understanding it The problem with test_codeop and test_marshal is this: these tests compare two different code objects and expect them to be equal. Is that still a feature we'd like to support? I've temporarily removed the comparison and hash code from code objects, so they use the default (equality by pointer only) comparison. For the other two tests, run them to see for yourself. (There may be more failing test with "-u all".) A general problem with getting lots of these tests to pass is the reality that for object types that have a natural total ordering, implementing __cmp__ is much more convenient than implementing __eq__, __ne__, __lt__, and so on. Should we go back to allowing __cmp__ to provide a total ordering? Should we provide some other way to implement rich comparison with a single method override? Alex proposed a __key__() method; I've considered a __richcmp__() method. Or perhaps __cmp__() just shouldn't be killed off...
2006-08-23 21:41:19 -03:00
def __lt__(self, other):
raise ZeroDivisionError
Restructure comparison dramatically. There is no longer a default *ordering* between objects; there is only a default equality test (defined by an object being equal to itself only). Read the comment in object.c. The current implementation never uses a three-way comparison to compute a rich comparison, but it does use a rich comparison to compute a three-way comparison. I'm not quite done ripping out all the calls to PyObject_Compare/Cmp, or replacing tp_compare implementations with tp_richcompare implementations; but much of that has happened (to make most unit tests pass). The following tests still fail, because I need help deciding or understanding: test_codeop -- depends on comparing code objects test_datetime -- need Tim Peters' opinion test_marshal -- depends on comparing code objects test_mutants -- need help understanding it The problem with test_codeop and test_marshal is this: these tests compare two different code objects and expect them to be equal. Is that still a feature we'd like to support? I've temporarily removed the comparison and hash code from code objects, so they use the default (equality by pointer only) comparison. For the other two tests, run them to see for yourself. (There may be more failing test with "-u all".) A general problem with getting lots of these tests to pass is the reality that for object types that have a natural total ordering, implementing __cmp__ is much more convenient than implementing __eq__, __ne__, __lt__, and so on. Should we go back to allowing __cmp__ to provide a total ordering? Should we provide some other way to implement rich comparison with a single method override? Alex proposed a __key__() method; I've considered a __richcmp__() method. Or perhaps __cmp__() just shouldn't be killed off...
2006-08-23 21:41:19 -03:00
__gt__ = __lt__
__le__ = __lt__
__ge__ = __lt__
__eq__ = __lt__
__ne__ = __lt__
class TestErrorHandling(unittest.TestCase):
def test_non_sequence(self):
for f in (bisect_left, bisect_right, insort_left, insort_right):
self.assertRaises(TypeError, f, 10, 10)
def test_len_only(self):
for f in (bisect_left, bisect_right, insort_left, insort_right):
self.assertRaises(TypeError, f, LenOnly(), 10)
def test_get_only(self):
for f in (bisect_left, bisect_right, insort_left, insort_right):
self.assertRaises(TypeError, f, GetOnly(), 10)
2004-09-27 20:11:35 -03:00
def test_cmp_err(self):
seq = [CmpErr(), CmpErr(), CmpErr()]
for f in (bisect_left, bisect_right, insort_left, insort_right):
self.assertRaises(ZeroDivisionError, f, seq, 10)
def test_arg_parsing(self):
for f in (bisect_left, bisect_right, insort_left, insort_right):
self.assertRaises(TypeError, f, 10)
#==============================================================================
libreftest = """
Example from the Library Reference: Doc/lib/libbisect.tex
The bisect() function is generally useful for categorizing numeric data.
This example uses bisect() to look up a letter grade for an exam total
(say) based on a set of ordered numeric breakpoints: 85 and up is an `A',
75..84 is a `B', etc.
>>> grades = "FEDCBA"
>>> breakpoints = [30, 44, 66, 75, 85]
>>> from bisect import bisect
>>> def grade(total):
... return grades[bisect(breakpoints, total)]
...
>>> grade(66)
'C'
Merged revisions 56125-56153 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r56127 | georg.brandl | 2007-06-30 09:32:49 +0200 (Sat, 30 Jun 2007) | 2 lines Fix a place where floor division would be in order. ........ r56135 | guido.van.rossum | 2007-07-01 06:13:54 +0200 (Sun, 01 Jul 2007) | 28 lines Make map() and filter() identical to itertools.imap() and .ifilter(), respectively. I fixed two bootstrap issues, due to the dynamic import of itertools: 1. Starting python requires that map() and filter() are not used until site.py has added build/lib.<arch> to sys.path. 2. Building python requires that setup.py and distutils and everything they use is free of map() and filter() calls. Beyond this, I only fixed the tests in test_builtin.py. Others, please help fixing the remaining tests that are now broken! The fixes are usually simple: a. map(None, X) -> list(X) b. map(F, X) -> list(map(F, X)) c. map(lambda x: F(x), X) -> [F(x) for x in X] d. filter(F, X) -> list(filter(F, X)) e. filter(lambda x: P(x), X) -> [x for x in X if P(x)] Someone, please also contribute a fixer for 2to3 to do this. It can leave map()/filter() calls alone that are already inside a list() or sorted() call or for-loop. Only in rare cases have I seen code that depends on map() of lists of different lengths going to the end of the longest, or on filter() of a string or tuple returning an object of the same type; these will need more thought to fix. ........ r56136 | guido.van.rossum | 2007-07-01 06:22:01 +0200 (Sun, 01 Jul 2007) | 3 lines Make it so that test_decimal fails instead of hangs, to help automated test runners. ........ r56139 | georg.brandl | 2007-07-01 18:20:58 +0200 (Sun, 01 Jul 2007) | 2 lines Fix a few test cases after the map->imap change. ........ r56142 | neal.norwitz | 2007-07-02 06:38:12 +0200 (Mon, 02 Jul 2007) | 1 line Get a bunch more tests passing after converting map/filter to return iterators. ........ r56147 | guido.van.rossum | 2007-07-02 15:32:02 +0200 (Mon, 02 Jul 2007) | 4 lines Fix the remaining failing unit tests (at least on OSX). Also tweaked urllib2 so it doesn't raise socket.gaierror when all network interfaces are turned off. ........
2007-07-03 05:25:58 -03:00
>>> list(map(grade, [33, 99, 77, 44, 12, 88]))
['E', 'A', 'B', 'D', 'F', 'A']
"""
#------------------------------------------------------------------------------
__test__ = {'libreftest' : libreftest}
def test_main(verbose=None):
from test import test_bisect
from types import BuiltinFunctionType
import sys
test_classes = [TestBisect, TestInsort]
if isinstance(bisect_left, BuiltinFunctionType):
test_classes.append(TestErrorHandling)
test_support.run_unittest(*test_classes)
test_support.run_doctest(test_bisect, verbose)
# verify reference counting
if verbose and hasattr(sys, "gettotalrefcount"):
import gc
counts = [None] * 5
Merged revisions 55007-55179 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r55077 | guido.van.rossum | 2007-05-02 11:54:37 -0700 (Wed, 02 May 2007) | 2 lines Use the new print syntax, at least. ........ r55142 | fred.drake | 2007-05-04 21:27:30 -0700 (Fri, 04 May 2007) | 1 line remove old cruftiness ........ r55143 | fred.drake | 2007-05-04 21:52:16 -0700 (Fri, 04 May 2007) | 1 line make this work with the new Python ........ r55162 | neal.norwitz | 2007-05-06 22:29:18 -0700 (Sun, 06 May 2007) | 1 line Get asdl code gen working with Python 2.3. Should continue to work with 3.0 ........ r55164 | neal.norwitz | 2007-05-07 00:00:38 -0700 (Mon, 07 May 2007) | 1 line Verify checkins to p3yk (sic) branch go to 3000 list. ........ r55166 | neal.norwitz | 2007-05-07 00:12:35 -0700 (Mon, 07 May 2007) | 1 line Fix this test so it runs again by importing warnings_test properly. ........ r55167 | neal.norwitz | 2007-05-07 01:03:22 -0700 (Mon, 07 May 2007) | 8 lines So long xrange. range() now supports values that are outside -sys.maxint to sys.maxint. floats raise a TypeError. This has been sitting for a long time. It probably has some problems and needs cleanup. Objects/rangeobject.c now uses 4-space indents since it is almost completely new. ........ r55171 | guido.van.rossum | 2007-05-07 10:21:26 -0700 (Mon, 07 May 2007) | 4 lines Fix two tests that were previously depending on significant spaces at the end of a line (and before that on Python 2.x print behavior that has no exact equivalent in 3.0). ........
2007-05-07 19:24:25 -03:00
for i in range(len(counts)):
test_support.run_unittest(*test_classes)
gc.collect()
counts[i] = sys.gettotalrefcount()
print(counts)
if __name__ == "__main__":
test_main(verbose=True)