/pod/set.py

http://pickled-object-database.googlecode.com/ · Python · 156 lines · 95 code · 37 blank · 24 comment · 32 complexity · 6f5d44b3e3ce89b8493afa6806f6b9c3 MD5 · raw file

  1. import exceptions
  2. import core
  3. import typed
  4. import query
  5. import fn
  6. class PodSetError(exceptions.BaseException):
  7. pass
  8. class Set(core.Object):
  9. def __init__(self, set = None, **kwargs):
  10. core.Object.__init__(self, **kwargs)
  11. if set:
  12. self.update(set)
  13. def __len__(self):
  14. # Return the cardinality of set s.
  15. get_one = query.RawQuery(select = fn.count(SetItem.id) >> 'count', where = SetItem.parent == self).get_one()
  16. if get_one:
  17. return get_one.count
  18. def __contains__(self, value):
  19. #Test x for membership in s.
  20. return True if ((SetItem.parent == self) & (SetItem.value == value)).get_one() else False
  21. def __iter__(self):
  22. return (item.value for item in core.Query(select = SetItem.value, where = SetItem.parent == self))
  23. def copy(self):
  24. return set([item.value for item in core.Query(select = SetItem.value, where = SetItem.parent == self)])
  25. def update(self, other):
  26. for elem in other:
  27. self.add(elem = elem)
  28. def add(self, elem):
  29. item = core.Query(where = (SetItem.parent == self) & (SetItem.value == elem)).get_one()
  30. if item:
  31. item.value = elem
  32. else:
  33. SetItem(parent = self, value = elem)
  34. def remove(self, elem):
  35. item = core.Query(where = (SetItem.parent == self) & (SetItem.value == elem)).get_one()
  36. if item:
  37. item.delete()
  38. else:
  39. raise KeyError
  40. def discard(self,elem):
  41. item = core.Query(where = (SetItem.parent == self) & (SetItem.value == elem)).get_one()
  42. if item:
  43. item.delete()
  44. def pop(self):
  45. item = core.Query(select = SetItem.value, where = SetItem.parent == self, limit = 1).get_one()
  46. if item:
  47. value = item.value
  48. item.delete()
  49. return value
  50. else:
  51. raise KeyError
  52. def clear(self):
  53. (SetItem.parent == self).delete()
  54. """ <= """
  55. def __le__(self, other):
  56. return self.issubset(other)
  57. def issubset(self, other):
  58. # set <= other. Test whether every element in the set is in other.
  59. return self.copy().issubset(other.copy() if isinstance(other, Set) else other)
  60. """ < """
  61. def __lt__(self, other):
  62. #set < other. Test whether the set is a true subset of other, that is, set <= other and set != other.
  63. return self.copy().__lt__(other.copy() if isinstance(other, Set) else other)
  64. """ >= """
  65. def __ge__(self, other):
  66. return self.issuperset(other)
  67. def issuperset(self, other):
  68. # set >= other. Test whether every element in other is in the set.
  69. super = True
  70. for elem in (other.copy() if isinstance(other, Set) else other):
  71. item = core.Query(where = (SetItem.parent == self) & (SetItem.value == elem)).get_one()
  72. if item is None:
  73. super = False
  74. return super
  75. """ > """
  76. def __gt__(self, other):
  77. # set > other. Test whether the set is a true superset of other, that is, set >= other and set != other.
  78. return self.copy().__gt__(other.copy() if isinstance(other, Set) else other)
  79. """ | """
  80. def __or__(self, other):
  81. return self.union(other)
  82. def union(self, other):
  83. #union(other, ...) set | other | ... Return a new set with elements from the set and all others.
  84. # Changed in version 2.6: Accepts multiple input iterables.
  85. return self.copy().union(other.copy() if isinstance(other, Set) else other)
  86. """ & """
  87. def __and__(self, other):
  88. return self.intersection(other)
  89. def intersection(self, other):
  90. #set & other & ... Return a new set with elements common to the set and all others.
  91. # Changed in version 2.6: Accepts multiple input iterables.
  92. return self.copy().intersection(other.copy() if isinstance(other, Set) else other)
  93. """ - """
  94. def __sub__(self, other):
  95. return self.difference(other)
  96. def difference(self, other):
  97. # difference(other, ...) set - other - ... Return a new set with elements in the set that are not in the others.
  98. # Changed in version 2.6: Accepts multiple input iterables.
  99. return self.copy().difference(other.copy() if isinstance(other, Set) else other)
  100. """ ^ """
  101. def __xor__(self, other):
  102. return self.symmetric_difference(other)
  103. def symmetric_difference(self, other):
  104. #set ^ other
  105. #Return a new set with elements in either the set or other but not both.
  106. return self.copy().symmetric_difference(other.copy() if isinstance(other, Set) else other)
  107. """ SET OPERATIONS """
  108. def isdisjoint(self, other):
  109. #Return True if the set has no elements in common with other. Sets are disjoint if and only if their intersection is the empty set.
  110. raise PodSetError, "method isdisjoint is not implemented at this time . . ."
  111. def intersection_update(self, other):
  112. raise PodSetError, "method intersection_update is not implemented at this time . . ."
  113. def difference_update(self, other):
  114. raise PodSetError, "method difference_update is not implemented at this time . . ."
  115. def symmetric_difference_update(self, other):
  116. raise PodSetError, "method symmetric_difference_update is not implemented at this time . . ."
  117. class SetItem(core.Object):
  118. parent = typed.PodObject(index = True)
  119. value = typed.Object(index = True)