[Zope3-dev] weightedUnion (& friends) vs negative weights

Tim Peters tim@zope.com
Mon, 17 Jun 2002 13:12:02 -0400


I first bumped into this when working on ZCTextIndex.  Consider this
program:

"""
try:
    from Persistence.BTrees.IIBTree import * # Zope3
except ImportError:
    from BTrees.IIBTree import *             # Zope2

a = IIBucket([(1, 10), (3, 30)])
b = IIBucket([(1, 11), (2, 21)])

c = weightedUnion(a, b, 2, 3)
print c

c = weightedUnion(a, b, 2, -3)
print c

c = weightedUnion(a, b, -2, -3)
print c
"""

The first output matches the docs:

    weightedUnion(a, b, 2, 3) ->
    (1, IIBucket([(1, 53), (2, 63), (3, 60)]))

That is, the values in A are multiplied by 2, the values in B by 3, and the
weighted values from A and B for corresponding keys are summed.

The second output is puzzling, and doesn't match the docs:

    weightedUnion(a, b, 2, -3) ->
    (1, IIBucket([(1, 17), (2, -3), (3, 60)]))

In effect, the values in B are ignored, acting as if they were all 1 (or
acting as if they were all -3, and as if B's weight were 1).

The third output is possibly even more puzzling:

    weightedUnion(a, b, -2, -3) ->
    (1, IISet([1, 2, 3]))

Now the values in both inputs are ignored, and the weights are ignored, and
the result is a set instead of a mapping.  This happens whenever both
weights are negative.

It's hard to believe the last two behaviors are intentional, but I'm willing
to be told they are <wink>.  Are they?  If they aren't, does anybody care?
Does anyone have code relying on it?

I bumped into this when trying to find the difference between scores in two
mappings, via weights of 1 and -1.  As in the second example above, that
didn't work, acting instead like the mapping with weight -1 had *scores*
(values) that were each -1.  In the end, it turned out I didn't need to find
the difference, so let it slide then.