Commit ea76c980 authored by Tim Peters's avatar Tim Peters

Implemented <, <=, >, >= for sets, giving subset and proper-subset

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.
parent 93d8d48c
...@@ -74,9 +74,11 @@ the following operations: ...@@ -74,9 +74,11 @@ the following operations:
\lineii{\var{x} not in \var{s}} \lineii{\var{x} not in \var{s}}
{test \var{x} for non-membership in \var{s}} {test \var{x} for non-membership in \var{s}}
\lineii{\var{s}.issubset(\var{t})} \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})} \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 \hline
\lineii{\var{s} | \var{t}} \lineii{\var{s} | \var{t}}
...@@ -99,9 +101,14 @@ the following operations: ...@@ -99,9 +101,14 @@ the following operations:
{new set with a shallow copy of \var{s}} {new set with a shallow copy of \var{s}}
\end{tableii} \end{tableii}
In addition to the above operations, both \class{Set} and \class{ImmutableSet} In addition, both \class{Set} and \class{ImmutableSet}
support set to set equality comparisons. Two sets are equal if and only if support set to set comparisons. Two sets are equal if and only if
every element of each set is contained in the other. 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} The following table lists operations available in \class{ImmutableSet}
but not found in \class{Set}: but not found in \class{Set}:
......
...@@ -275,6 +275,18 @@ class BaseSet(object): ...@@ -275,6 +275,18 @@ class BaseSet(object):
return False return False
return True 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 # Assorted helpers
def _binary_sanity_check(self, other): def _binary_sanity_check(self, other):
......
...@@ -364,23 +364,37 @@ class TestSubsets(unittest.TestCase): ...@@ -364,23 +364,37 @@ class TestSubsets(unittest.TestCase):
case2method = {"<=": "issubset", case2method = {"<=": "issubset",
">=": "issuperset", ">=": "issuperset",
} }
cases_with_ops = Set(["==", "!="])
reverse = {"==": "==",
"!=": "!=",
"<": ">",
">": "<",
"<=": ">=",
">=": "<=",
}
def test_issubset(self): def test_issubset(self):
x = self.left x = self.left
y = self.right y = self.right
for case in "!=", "==", "<", "<=", ">", ">=": for case in "!=", "==", "<", "<=", ">", ">=":
expected = case in self.cases 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: if case in TestSubsets.case2method:
# Test the method-name spelling.
method = getattr(x, TestSubsets.case2method[case]) method = getattr(x, TestSubsets.case2method[case])
result = method(y) result = method(y)
self.assertEqual(result, expected) 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): class TestSubsetEqualEmpty(TestSubsets):
...@@ -410,7 +424,7 @@ class TestSubsetEmptyNonEmpty(TestSubsets): ...@@ -410,7 +424,7 @@ class TestSubsetEmptyNonEmpty(TestSubsets):
class TestSubsetPartial(TestSubsets): class TestSubsetPartial(TestSubsets):
left = Set([1]) left = Set([1])
right = Set([1, 2]) right = Set([1, 2])
name = "one a non-empty subset of other" name = "one a non-empty proper subset of other"
cases = "!=", "<", "<=" cases = "!=", "<", "<="
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
......
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