I'm trying to build the Set class from scratch in python but it's not working very well with the tester I was given.
The class works well with no coding errors but it's just not giving the expected results as it should. I'm not sure what's causing the proplem.
This is my class:
class mySet:
def __init__(self, data = None):
if data == None:
self.elements = []
else:
self.elements = []
if len(data) > 1:
for i in data:
if i not in self.elements:
self.elements.append(i)
def add(self, data):
if data not in self.elements:
self.elements.append(data)
def pop(self):
if len(self.elements) > 0:
return self.elements.pop()
raise KeyError('empty set!')
def remove(self, key):
if key in self.elements:
self.elements.remove(key)
else:
raise KeyError('This value was not found in the set')
def discard(self, key):
if key in self.elements:
self.elements.remove(key)
def clear(self):
if len(self.elements) > 0:
self.elements.clear()
def copy(self):
from copy import copy
return copy(self)
def issubset(self, otherSet):
return self.__le__(otherSet)
def ispropersubset(self, otherSet):
return self.__lt__(otherSet)
def issuperset(self, otherSet):
return self.__ge__(otherSet)
def ispropersuperset(self, otherSet):
return self.__gt__(otherSet)
def union(self, otherSet):
return self.__or__(otherSet)
def intersection(self, otherSet):
return self.__and__(otherSet)
def difference(self, otherSet):
return self.__sub__(otherSet)
def symmetric_difference(self, otherSet):
return self.__xor__(otherSet)
def isdisjoint(self, otherSet):
if len(self.__xor__(otherSet)) == 0:
return True
return False
def update(self, otherSet):
self.__ior__(otherSet)
def intersection_update(self, otherSet):
self.__iand__(otherSet)
def difference_update(self, otherSet):
self.__isub__(otherSet)
def symmetric_difference_update(self, otherSet):
self.__ixor__(otherSet)
def __str__(self):
return f'{self.elements}'
def __repr__(self):
return self.__str__()
def __len__(self):
return len(self.elements)
def __contains__(self, key):
if key in self.elements:
return True
return False
def __eq__(self, other):
if isinstance(other, mySet):
if self.elements == other.elements:
return True
return False
return False
def __ne__(self, other):
if isinstance(other, mySet):
if self.elements != other.elements:
return True
return False
return False
def __le__(self, other):
if isinstance(other, mySet):
if self.elements <= other.elements:
return True
return False
return False
def __lt__(self, other):
if isinstance(other, mySet):
if self.__le__(other) and self.__ne__(other):
return True
return False
return False
def __ge__(self, other):
if isinstance(other, mySet):
if self.elements >= other.elements:
return True
return False
return False
def __gt__(self, other):
if isinstance(other, mySet):
if self.__ge__(other) and self.__ne__(other):
return True
return False
return False
def __or__(self, other):
if isinstance(other, mySet):
result = self.copy()
for i in other.elements:
result.add(i)
return result
def __and__(self, other):
if isinstance(other, mySet):
result = mySet()
for i in self.elements:
if i in other.elements:
result.add(i)
return result
def __sub__(self, other):
if isinstance(other, mySet):
result = mySet()
for i in self.elements:
if i not in other.elements:
result.add(i)
return result
def __xor__(self, other):
if isinstance(other, mySet):
result = mySet()
for i in other.elements:
if i not in self.elements:
result.add(i)
for j in self.elements:
if j not in other.elements:
result.add(j)
return result
def __ior__(self, other):
self.add(other.elements)
def __iand__(self, other):
result = self.__and__(other)
self.elements = result
def __isub__(self, other):
result = self.__sub__(other)
self.elements = result
def __ixor__(self, other):
result = self.__xor__(other)
self.elements = result
this is the tester program if it's going to help: Tester program
It's going to be easier to just copy\paste the tester program because it's super long. the Tester doesn't have any issues it's just the set class.
This is the errors I'm getting:
Error: init 7. Expected: [1, 2, 3], Got: [1, 3, 2]
Error: init 8. Expected: [1, 2, 3], Got: [1, 3, 2]
Error: init 10. Expected: [1, 2, 3], Got: [1, 3, 2]
Error: init 12. Expected: True, Got: False
Error: euqals 2. Expected: True, Got: False
Error: euqals 5. Expected: False, Got: True
Error: isdisjoint 1. Expected: True, Got: False
Error: isdisjoint 2. Expected: True, Got: False
Error: isdisjoint 5. Expected: True, Got: False
Error: isdisjoint 6. Expected: True, Got: False
Error: add 1. Expected: [], Got: [1]
Error: add 2. Expected: [4, 2, 1, 3], Got: [1, 2, 3, 4]
Error: update 1A. Expected: [1, 2, 3, 4, 5], Got: [1, 2, 3, [3, 4, 5]]
Error: update 2A. Expected: [1, 2, 3], Got: [[1, 2, 3]]
Error: update 3A. Expected: [1, 2, 3], Got: [1, 2, 3, []]
Error: update 4A. Expected: [1, 2, 3], Got: [1, 2, 3, [1, 2, 3]]
Error: union 2A. Expected: [2, 3, 4, 5, 6], Got: [4, 5, 6, 2, 3, 4, 5]
Error: union 3A. Expected: [4, 5, 6], Got: [4, 5, 6, 2, 3, 4, 5]
Error: union 4A. Expected: [4, 5, 6], Got: [4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5]
Error: union 1B. Expected: [1, 2, 3, 4, 5, 6], Got: [1, 2, 3, 4, 5, 6, 4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5]
Error: union 2B. Expected: [2, 3, 4, 5, 6], Got: [4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 2, 3, 4, 5]
Error: union 3B. Expected: [4, 5, 6], Got: [4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 2, 3, 4, 5]
Error: union 4B. Expected: [4, 5, 6], Got: [4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 4, 5, 6, 2, 3, 4, 5, 2, 3, 4, 5]
Error: difference 2A. Expected: [], Got: [1]
Error: difference 2B. Expected: [], Got: [1]
Error: symmetric_difference 1A. Expected: [1, 2, 3, 4, 5, 6], Got: [4, 5, 6, 1, 2, 3]
Error: symmetric_difference 2A. Expected: [1, 4, 5], Got: [4, 5, 1]
Error: symmetric_difference 1B. Expected: [1, 2, 3, 4, 5, 6], Got: [4, 5, 6, 1, 2, 3]
Error: symmetric_difference 2B. Expected: [1, 4, 5], Got: [4, 5, 1]
Error: discard 2. Expected: [3, 2], Got: [2, 3]
177 tests run.
30 errors found
sorry if it's super long but it's what it is.
CodePudding user response:
A large number of the errors are because the __eq__()
method simply compares the elements
lists directly. When comparing lists, order is significant, but it shouldn't be significant for sets, and you're getting errors when the order is different.
If you assume that the elements all implement <
, you can sort them before comparing.
def __eq__(self, other):
if isinstance(other, mySet):
if sorted(self.elements) == sorted(other.elements):
return True
return False
return False
This should fix all the ones where expected and got are the same except for order. It also fixes some of the "Expected: True Got: False" errors, because they're testing the result of ==
internally.
The logic of isdisjoin()
is wrong. If the sets are disjoint, __xor__
will return a set that contains all the elements of both sets, since it returns all the elements that are in one but not in the other. You should use self.intersection(other)
rather than self.__xor__(other)
.
The reason for the add 1
, difference 2A
, and difference 2B
errors is because of the test if len(data) > 1:
in __init__()
. If you call mySet([1])
, the length is 1, which is not greater than 1. Get rid of that test, it's not needed. If you really want to keep it, it should be if len(data) > 0:
.
The logic of __ior__()
is wrong. It's adding other.elements
as a single element in the set, it needs to iterate over it:
def __ior__(self, other):
for i in other.elements:
self.add(i)
This is causing all the update
errors.
All the union
errors are because your original add()
method didn't check for duplicates.