Interfaces.py 10.9 KB
Newer Older
1
##############################################################################
matt@zope.com's avatar
matt@zope.com committed
2
#
3 4
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
5
#
matt@zope.com's avatar
matt@zope.com committed
6 7 8 9 10 11
# 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.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
12
#
13
##############################################################################
14

15 16
import OOBTree, Interface
from Interface import Interface
17

18
class ICollection(Interface):
19 20 21 22 23 24 25 26 27 28 29

    def clear():
        """Remove all of the items from the collection"""

    def __nonzero__():
        """Check if the collection is non-empty.

        Return a true value if the collection is non-empty and a
        false otherwise.
        """

30 31 32 33 34 35 36 37

class IReadSequence(Interface):

    def __getitem__(index):
        """Return a value at the givem index

        An IndexError is raised if the index cannot be found.
        """
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

    def __getslice__(index1, index2):
        """Return a subsequence from the original sequence

        Such that the subsequence includes the items from index1 up
        to, but not including, index2.
        """

class IKeyed(ICollection):

    def has_key(key):
        """Check whether the object has an item with the given key"""

    def keys(min=None, max=None):
        """Return an IReadSequence containing the keys in the collection

        The type of the IReadSequence is not specified. It could be a
        list or a tuple or some other type.

        If a min is specified, then output is constrained to
        items having keys greater than or equal to the given min.
        A min value of None is ignored.

        If a max is specified, then output is constrained to
        items having keys less than or equal to the given min.
        A max value of None is ignored.
        """

    def maxKey(key=None):
        """Return the maximum key

        If a key argument if provided, return the largest key that is
        less than or equal to the argument.
        """

    def minKey(key=None):
        """Return the minimum key

        If a key argument if provided, return the smallest key that is
        greater than or equal to the argument.
        """

class ISetMutable(IKeyed):
81

82 83 84 85 86 87 88 89
    def insert(key):
        """Add the key (value) to the set.

        If the key was already in the set, return 0, otherwise return 1.
        """

    def remove(key):
        """Remove the key from the set."""
90

91 92
    def update(seq):
        """Add the items from the given sequence to the set"""
93

94 95 96 97 98 99 100
class ISized(Interface):
    "anything supporting __len"

    def __len__():
        """Return the number of items in the container"""

class IKeySequence(IKeyed, ISized):
101 102 103 104 105 106 107 108 109 110 111 112 113 114

    def __getitem__(index):
        """Return the key in the given index position

        This allows iteration with for loops and use in functions,
        like map and list, that read sequences.
        """

class ISet(IKeySequence, ISetMutable):
    pass

class ITreeSet(IKeyed, ISetMutable):
    pass

115
class IMinimalDictionary(ISized):
116

117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
    def has_key(key):
        """Check whether the object has an item with the given key"""


    def get(key, default):
        """Get the value for the given key

        Return the default if the key is not in the  collection.
        """

    def __setitem__(key, value):
        """Set the value for the given key"""

    def __delitem__(key):
        """delete the value for the given key

        Raise a key error if the key if not in the collection."""

    def values():
        """Return a IReadSequence containing the values in the collection

        The type of the IReadSequence is not specified. It could be a
        list or a tuple or some other type.
        """

    def keys():
        """Return an Sequence containing the keys in the collection

        The type of the IReadSequence is not specified. It could be a
        list or a tuple or some other type.
        """

    def items():
        """Return a IReadSequence containing the items in the collection

        An item is a key-value tuple.

        The type of the IReadSequence is not specified. It could be a
        list or a tuple or some other type.
        """


class IDictionaryIsh(IKeyed, IMinimalDictionary):
160

161 162 163 164 165 166 167 168
    def update(collection):
        """Add the items from the given collection object to the collection

        The input collection must be a sequence of key-value tuples,
        or an object with an 'items' method that returns a sequence of
        key-value tuples.
        """

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
    def values(min=None, max=None):
        """Return a IReadSequence containing the values in the collection

        The type of the IReadSequence is not specified. It could be a
        list or a tuple or some other type.

        If a min is specified, then output is constrained to
        items having keys greater than or equal to the given min.
        A min value of None is ignored.

        If a max is specified, then output is constrained to
        items having keys less than or equal to the given min.
        A max value of None is ignored.
        """

    def items(min=None, max=None):
        """Return a IReadSequence containing the items in the collection

        An item is a key-value tuple.

        The type of the IReadSequence is not specified. It could be a
        list or a tuple or some other type.

        If a min is specified, then output is constrained to
        items having keys greater than or equal to the given min.
        A min value of None is ignored.

        If a max is specified, then output is constrained to
        items having keys less than or equal to the given min.
        A max value of None is ignored.
        """
200 201 202 203 204 205 206 207

    def byValue(minValue):
        """Return a sequence of value-key pairs, sorted by value

        Values < min are ommitted and other values are "normalized" by
        the minimum value. This normalization may be a noop, but, for
        integer values, the normalization is division.
        """
208

209 210 211
class IBTree(IDictionaryIsh):

    def insert(key, value):
Jim Fulton's avatar
Jim Fulton committed
212
        """Insert a key and value into the collection.
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228

        If the key was already in the collection, then there is no
        change and 0 is returned.

        If the key was not already in the collection, then the item is
        added and 1 is returned.

        This method is here to allow one to generate random keys and
        to insert and test whether the key was there in one operation.

        A standard idiom for generating new keys will be::

          key=generate_key()
          while not t.insert(key, value):
              key=generate_key()
        """
229

230
class IMerge(Interface):
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
    """Object with methods for merging sets, buckets, and trees.

    These methods are supplied in modules that define collection
    classes with particular key and value types. The operations apply
    only to collections from the same module.  For example, the
    IIBTree.union can only be used with IIBTree.IIBTree,
    IIBTree.IIBucket, IIBTree.IISet, and IIBTree.IITreeSet.

    The implementing module has a value type. The IOBTree and OOBTree
    modules have object value type. The IIBTree and OIBTree modules
    have integer value tyoes. Other modules may be defined in the
    future that have other value types.

    The individual types are classified into set (Set and TreeSet) and
    mapping (Bucket and BTree) types.
    """

    def difference(c1, c2):
        """Return the keys or items in c1 for which there is no key in
        c2.

252
        If c1 is None, then None is returned.  If c2 is None, then c1
253
        is returned.
254 255 256

        If neither c1 nor c2 is None, the output is a Set if c1 is a Set or
        TreeSet, and is a Bucket if c1 is a Bucket or BTree.
257 258 259 260 261 262 263 264 265 266 267 268 269
        """

    def union(c1, c2):
        """Compute the Union of c1 and c2.

        If c1 is None, then c2 is returned, otherwise, if c2 is None,
        then c1 is returned.

        The output is a Set containing keys from the input
        collections.
        """

    def intersection(c1, c2):
270
        """Compute the intersection of c1 and c2.
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290

        If c1 is None, then c2 is returned, otherwise, if c2 is None,
        then c1 is returned.

        The output is a Set containing matching keys from the input
        collections.
        """

class IIMerge(IMerge):
    """Merge collections with integer value type.

    A primary intent is to support operations with no or integer
    values, which are used as "scores" to rate indiviual keys. That
    is, in this context, a BTree or Bucket is viewed as a set with
    scored keys, using integer scores.
    """

    def weightedUnion(c1, c2, weight1=1, weight2=1):
        """Compute the weighted Union of c1 and c2.

291
        If c1 and c2 are None, the output is (0, None).
292

293
        If c1 is None and c2 is not None, the output is (weight2, c2).
294

295
        If c1 is not None and c2 is None, the output is (weight1, c1).
296

297
        If c1 and c2 are not None and not both sets, the output is 1
Andreas Jung's avatar
Andreas Jung committed
298
        and a Bucket such that the output values are::
299 300 301 302 303 304 305 306 307 308 309

          v1*weight1 + v2*weight2

          where:

            v1 is 0 if the key was not in c1. Otherwise, v1 is 1, if
            c1 is a set, or the value from c1.

            v2 is 0 if the key was not in c2. Otherwise, v2 is 2, if
            c2 is a set, or the value from c2.

310
        Note that c1 and c2 must be collections.
311

312 313 314 315 316
        """

    def weightedIntersection(c1, c2, weight1=1, weight2=1):
        """Compute the weighted intersection of c1 and c2.

317
        If c1 and c2 are None, the output is (0, None).
318

319
        If c1 is None and c2 is not None, the output is (weight2, c2).
320

321
        If c1 is not None and c2 is None, the output is (weight1, c1).
322

Andreas Jung's avatar
Andreas Jung committed
323
        If c1 and c2 are both sets, the output is the sum of the weights
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
        and the (unweighted) intersection of the sets.

        If c1 and c2 are not None and not both sets, the output is 1
        and a Bucket such that the output values are::

          v1*weight1 + v2*weight2

          where:

            v1 is 0 if the key was not in c1. Otherwise, v1 is 1, if
            c1 is a set, or the value from c1.

            v2 is 0 if the key was not in c2. Otherwise, v2 is 2, if
            c2 is a set, or the value from c2.

339
        Note that c1 and c2 must be collections.
340 341
        """

342 343 344 345 346 347 348 349 350 351 352
###############################################################
# IMPORTANT NOTE
#
# Getting the length of a BTree, TreeSet, or output of keys,
# values, or items of same is expensive. If you need to get the
# length, you need to maintain this separately.
#
# Eventually, I need to express this through the interfaces.
#
################################################################

353 354 355 356
OOBTree.OOSet.__implements__=ISet
OOBTree.OOTreeSet.__implements__=ITreeSet
OOBTree.OOBucket.__implements__=IDictionaryIsh
OOBTree.OOBTree.__implements__=IBTree