Forward port r68792 and r68789 putting Counter in __all__ and adding Counter buildouts.

This commit is contained in:
Raymond Hettinger 2009-01-20 03:41:22 +00:00
parent afccd63ac9
commit 4d2073a073
3 changed files with 168 additions and 13 deletions

View file

@ -4,6 +4,8 @@ import unittest, doctest
from test import support
from collections import namedtuple, Counter, Mapping
import pickle, copy
from random import randrange
import operator
from collections import Hashable, Iterable, Iterator
from collections import Sized, Container, Callable
from collections import Set, MutableSet
@ -361,6 +363,8 @@ class TestCounter(unittest.TestCase):
def test_basics(self):
c = Counter('abcaba')
self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
self.assertEqual(c, Counter(a=3, b=2, c=1))
self.assert_(isinstance(c, dict))
self.assert_(isinstance(c, Mapping))
self.assert_(issubclass(Counter, dict))
@ -388,6 +392,7 @@ class TestCounter(unittest.TestCase):
c['a'] += 1 # increment an existing value
c['b'] -= 2 # sub existing value to zero
del c['c'] # remove an entry
del c['c'] # make sure that del doesn't raise KeyError
c['d'] -= 2 # sub from a missing value
c['e'] = -5 # directly assign a missing value
c['f'] += 4 # add to a missing value
@ -403,7 +408,8 @@ class TestCounter(unittest.TestCase):
self.assertEqual(repr(c), 'Counter()')
self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
self.assertRaises(TypeError, hash, c)
c.update(dict(a=5, b=3, c=1))
c.update(dict(a=5, b=3))
c.update(c=1)
c.update(Counter('a' * 50 + 'b' * 30))
c.update() # test case with no args
c.__init__('a' * 500 + 'b' * 300)
@ -447,7 +453,43 @@ class TestCounter(unittest.TestCase):
self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
self.assertEqual(set(Counter(s)), set(s))
def test_multiset_operations(self):
# Verify that adding a zero counter will strip zeros and negatives
c = Counter(a=10, b=-2, c=0) + Counter()
self.assertEqual(dict(c), dict(a=10))
elements = 'abcd'
for i in range(1000):
# test random pairs of multisets
p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
for counterop, numberop, defneg in [
(Counter.__add__, lambda x, y: x+y if x+y>0 else 0, True),
(Counter.__sub__, lambda x, y: x-y if x-y>0 else 0, False),
(Counter.__or__, max, False),
(Counter.__and__, min, False),
]:
result = counterop(p, q)
for x in elements:
# all except __add__ are undefined for negative inputs
if defneg or (p[x] >= 0 and q[x] >= 0):
self.assertEqual(numberop(p[x], q[x]), result[x])
# verify that results exclude non-positive counts
self.assert_(x>0 for x in result.values())
elements = 'abcdef'
for i in range(100):
# verify that random multisets with no repeats are exactly like sets
p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
for counterop, setop in [
(Counter.__sub__, set.__sub__),
(Counter.__or__, set.__or__),
(Counter.__and__, set.__and__),
]:
counter_result = counterop(p, q)
set_result = setop(set(p.elements()), set(q.elements()))
self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
import doctest, collections