Commit f6513a88 authored by Tim Peters's avatar Tim Peters

Added the first, trivial tests of weightedUnion and weightedIntersection,

and started repairing obvious errors in their docs.  More to come.
parent d877b311
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
# #
# Copyright (c) 2001, 2002 Zope Corporation and Contributors. # Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved. # All Rights Reserved.
# #
# This software is subject to the provisions of the Zope Public License, # This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE
# #
############################################################################## ##############################################################################
import OOBTree, Interface import OOBTree, Interface
...@@ -78,7 +78,7 @@ class IKeyed(ICollection): ...@@ -78,7 +78,7 @@ class IKeyed(ICollection):
""" """
class ISetMutable(IKeyed): class ISetMutable(IKeyed):
def insert(key): def insert(key):
"""Add the key (value) to the set. """Add the key (value) to the set.
...@@ -87,7 +87,7 @@ class ISetMutable(IKeyed): ...@@ -87,7 +87,7 @@ class ISetMutable(IKeyed):
def remove(key): def remove(key):
"""Remove the key from the set.""" """Remove the key from the set."""
def update(seq): def update(seq):
"""Add the items from the given sequence to the set""" """Add the items from the given sequence to the set"""
...@@ -113,7 +113,7 @@ class ITreeSet(IKeyed, ISetMutable): ...@@ -113,7 +113,7 @@ class ITreeSet(IKeyed, ISetMutable):
pass pass
class IMinimalDictionary(ISized): class IMinimalDictionary(ISized):
def has_key(key): def has_key(key):
"""Check whether the object has an item with the given key""" """Check whether the object has an item with the given key"""
...@@ -205,7 +205,7 @@ class IDictionaryIsh(IKeyed, IMinimalDictionary): ...@@ -205,7 +205,7 @@ class IDictionaryIsh(IKeyed, IMinimalDictionary):
the minimum value. This normalization may be a noop, but, for the minimum value. This normalization may be a noop, but, for
integer values, the normalization is division. integer values, the normalization is division.
""" """
class IBTree(IDictionaryIsh): class IBTree(IDictionaryIsh):
def insert(key, value): def insert(key, value):
...@@ -288,15 +288,13 @@ class IIMerge(IMerge): ...@@ -288,15 +288,13 @@ class IIMerge(IMerge):
def weightedUnion(c1, c2, weight1=1, weight2=1): def weightedUnion(c1, c2, weight1=1, weight2=1):
"""Compute the weighted Union of c1 and c2. """Compute the weighted Union of c1 and c2.
If c1 and c2 are None, the output is 0 and None If c1 and c2 are None, the output is (0, None).
if c1 is None and c2 is not None, the output is weight2 and If c1 is None and c2 is not None, the output is (weight2, c2).
c2.
if c1 is not None and c2 not None and both sets, the output is If c1 is not None and c2 is None, the output is (weight1, c1).
weight1 and c1.
If c1 and c2 are not None and not both sets, the output is 1 If c1 and c2 are not None and not both sets, the output is 1
and a Bucket such that the output values are:: and a Bucket such that the output values are::
v1*weight1 + v2*weight2 v1*weight1 + v2*weight2
...@@ -309,20 +307,18 @@ class IIMerge(IMerge): ...@@ -309,20 +307,18 @@ class IIMerge(IMerge):
v2 is 0 if the key was not in c2. Otherwise, v2 is 2, if v2 is 0 if the key was not in c2. Otherwise, v2 is 2, if
c2 is a set, or the value from c2. c2 is a set, or the value from c2.
Note that c1 and c2 must be collections. Note that c1 and c2 must be collections.
""" """
def weightedIntersection(c1, c2, weight1=1, weight2=1): def weightedIntersection(c1, c2, weight1=1, weight2=1):
"""Compute the weighted intersection of c1 and c2. """Compute the weighted intersection of c1 and c2.
If c1 and c2 are None, the output is None, None. If c1 and c2 are None, the output is (0, None).
if c1 is None and c2 is not None, the output is weight2 and If c1 is None and c2 is not None, the output is (weight2, c2).
c2.
if c1 is not None and c2 not None, the output is weight1 and If c1 is not None and c2 is None, the output is (weight1, c1).
c1.
If c1 and c2 are both sets, the output is the sum of the weights If c1 and c2 are both sets, the output is the sum of the weights
and the (unweighted) intersection of the sets. and the (unweighted) intersection of the sets.
...@@ -340,7 +336,7 @@ class IIMerge(IMerge): ...@@ -340,7 +336,7 @@ class IIMerge(IMerge):
v2 is 0 if the key was not in c2. Otherwise, v2 is 2, if v2 is 0 if the key was not in c2. Otherwise, v2 is 2, if
c2 is a set, or the value from c2. c2 is a set, or the value from c2.
Note that c1 and c2 must be collections. Note that c1 and c2 must be collections.
""" """
############################################################### ###############################################################
......
...@@ -327,12 +327,73 @@ class TestImports(TestCase): ...@@ -327,12 +327,73 @@ class TestImports(TestCase):
else: else:
self.fail("OOBTree shouldn't have multiunion") self.fail("OOBTree shouldn't have multiunion")
# Subclasses must set up (as class variables):
# weightedUnion, weightedIntersection
# builders -- sequence of constructors, taking items
class Weighted(TestCase):
def setUp(self):
self.Aitems = [(1, 10), (3, 30), (5, 50), (6, 60)]
self.Bitems = [(2, 21), (3, 31), (4, 41), (6, 61), (7, 71)]
self.As = [make(self.Aitems) for make in self.builders]
self.Bs = [make(self.Bitems) for make in self.builders]
self.emptys = [make([]) for make in self.builders]
def testBothNone(self):
for op in self.weightedUnion, self.weightedIntersection:
w, C = op(None, None)
self.assert_(C is None)
self.assertEqual(w, 0)
w, C = op(None, None, 42, 666)
self.assert_(C is None)
self.assertEqual(w, 0)
def testLeftNone(self):
for op in self.weightedUnion, self.weightedIntersection:
for A in self.As + self.emptys:
w, C = op(None, A)
self.assert_(C is A)
self.assertEqual(w, 1)
w, C = op(None, A, 42, 666)
self.assert_(C is A)
self.assertEqual(w, 666)
def testRightNone(self):
for op in self.weightedUnion, self.weightedIntersection:
for A in self.As + self.emptys:
w, C = op(A, None)
self.assert_(C is A)
self.assertEqual(w, 1)
w, C = op(A, None, 42, 666)
self.assert_(C is A)
self.assertEqual(w, 42)
# Given a set builder (like OITreeSet or OISet), return a function that
# takes a list of (key, value) pairs and builds a set out of the keys.
def itemsToSet(setbuilder):
def result(items, setbuilder=setbuilder):
return setbuilder([key for key, value in items])
return result
class TestWeightedII(Weighted):
from BTrees.IIBTree import weightedUnion, weightedIntersection
builders = IIBucket, IIBTree, itemsToSet(IISet), itemsToSet(IITreeSet)
class TestWeightedOI(Weighted):
from BTrees.OIBTree import weightedUnion, weightedIntersection
builders = OIBucket, OIBTree, itemsToSet(OISet), itemsToSet(OITreeSet)
def test_suite(): def test_suite():
s = TestSuite() s = TestSuite()
for klass in (TestIIMultiUnion, TestIOMultiUnion, for klass in (TestIIMultiUnion, TestIOMultiUnion,
TestImports, TestImports,
PureII, PureIO, PureOI, PureOO): PureII, PureIO, PureOI, PureOO,
TestWeightedII, TestWeightedOI):
s.addTest(makeSuite(klass)) s.addTest(makeSuite(klass))
return s return s
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment