]> granicus.if.org Git - python/commitdiff
Implemented <, <=, >, >= for sets, giving subset and proper-subset
authorTim Peters <tim.peters@gmail.com>
Sun, 25 Aug 2002 18:43:10 +0000 (18:43 +0000)
committerTim Peters <tim.peters@gmail.com>
Sun, 25 Aug 2002 18:43:10 +0000 (18:43 +0000)
meanings.  I did not add new, e.g., ispropersubset() methods; we're
going nuts on those, and, e.g., there was no "friendly name" for
== either.

Doc/lib/libsets.tex
Lib/sets.py
Lib/test/test_sets.py

index 8ce62c88980efcc5920265b07a2a38ad2e228250..c5239a4f2c953e398bc4ca7ba2dff5ff82ab9880 100644 (file)
@@ -74,9 +74,11 @@ the following operations:
   \lineii{\var{x} not in \var{s}}
          {test \var{x} for non-membership in \var{s}}
   \lineii{\var{s}.issubset(\var{t})}
-         {test whether every element in \var{s} is in \var{t}}
+         {test whether every element in \var{s} is in \var{t};
+         \code{\var{s} <= \var{t}} is equivalent}
   \lineii{\var{s}.issuperset(\var{t})}
-         {test whether every element in \var{t} is in \var{s}}
+         {test whether every element in \var{t} is in \var{s};
+         \code{\var{s} >= \var{t}} is equivalent}
 
   \hline
   \lineii{\var{s} | \var{t}}
@@ -99,9 +101,14 @@ the following operations:
          {new set with a shallow copy of \var{s}}
 \end{tableii}
 
-In addition to the above operations, both \class{Set} and \class{ImmutableSet}
-support set to set equality comparisons.  Two sets are equal if and only if
-every element of each set is contained in the other.
+In addition, both \class{Set} and \class{ImmutableSet}
+support set to set comparisons.  Two sets are equal if and only if
+every element of each set is contained in the other (each is a subset
+of the other).
+A set is less than another set if and only if the first set is a proper
+subset of the second set (is a subset, but is not equal).
+A set is greater than another set if and only if the first set is a proper
+superset of the second set (is a superset, but is not equal).
 
 The following table lists operations available in \class{ImmutableSet}
 but not found in \class{Set}:
index ff0ace0fc70d2ebbf40a2af34f3449e725605eca..3897fb9d7ccec6ca908f2f207d9738f54905abcb 100644 (file)
@@ -275,6 +275,18 @@ class BaseSet(object):
                 return False
         return True
 
+    # Inequality comparisons using the is-subset relation.
+    __le__ = issubset
+    __ge__ = issuperset
+
+    def __lt__(self, other):
+        self._binary_sanity_check(other)
+        return len(self) < len(other) and self.issubset(other)
+
+    def __gt__(self, other):
+        self._binary_sanity_check(other)
+        return len(self) > len(other) and self.issuperset(other)
+
     # Assorted helpers
 
     def _binary_sanity_check(self, other):
index 15c52c80b31b2464a13d73d4e4a5b5204123e2f9..840036cc654d8c9f97b700ffdebf8cac8770bc37 100644 (file)
@@ -364,23 +364,37 @@ class TestSubsets(unittest.TestCase):
     case2method = {"<=": "issubset",
                    ">=": "issuperset",
                   }
-    cases_with_ops = Set(["==", "!="])
+
+    reverse = {"==": "==",
+               "!=": "!=",
+               "<":  ">",
+               ">":  "<",
+               "<=": ">=",
+               ">=": "<=",
+              }
 
     def test_issubset(self):
         x = self.left
         y = self.right
         for case in "!=", "==", "<", "<=", ">", ">=":
             expected = case in self.cases
+            # Test the binary infix spelling.
+            result = eval("x" + case + "y", locals())
+            self.assertEqual(result, expected)
+            # Test the "friendly" method-name spelling, if one exists.
             if case in TestSubsets.case2method:
-                # Test the method-name spelling.
                 method = getattr(x, TestSubsets.case2method[case])
                 result = method(y)
                 self.assertEqual(result, expected)
-            if case in TestSubsets.cases_with_ops:
-                # Test the binary infix spelling.
-                result = eval("x" + case + "y", locals())
-                self.assertEqual(result, expected)
 
+            # Now do the same for the operands reversed.
+            rcase = TestSubsets.reverse[case]
+            result = eval("y" + rcase + "x", locals())
+            self.assertEqual(result, expected)
+            if rcase in TestSubsets.case2method:
+                method = getattr(y, TestSubsets.case2method[rcase])
+                result = method(x)
+                self.assertEqual(result, expected)
 #------------------------------------------------------------------------------
 
 class TestSubsetEqualEmpty(TestSubsets):
@@ -410,7 +424,7 @@ class TestSubsetEmptyNonEmpty(TestSubsets):
 class TestSubsetPartial(TestSubsets):
    left  = Set([1])
    right = Set([1, 2])
-   name  = "one a non-empty subset of other"
+   name  = "one a non-empty proper subset of other"
    cases = "!=", "<", "<="
 
 #------------------------------------------------------------------------------