Last active
January 16, 2019 02:45
-
-
Save soeirosantos/f601eb74316968067f88db004eede811 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Node: | |
| def __init__(self, value=None): | |
| self.value = value | |
| self.next = None | |
| def __repr__(self): | |
| return "Node(value=%s,next=%s)" % (self.value, self.next) | |
| class Set: | |
| def __init__(self, data=[]): | |
| self._capacity = 100 | |
| self._size = 0 | |
| self.data = [Node() for n in range(self._capacity)] | |
| for d in data: | |
| self.add(d) | |
| def add(self, item): | |
| if item in self: | |
| return | |
| hashedPosition = self._hash(item) | |
| head = self.data[hashedPosition] | |
| if not head.value: | |
| head.value = item | |
| else: | |
| current = head | |
| while current.next: | |
| current = current.next | |
| current.next = Node(item) | |
| self._size += 1 | |
| def remove(self, item): | |
| if item not in self: | |
| return | |
| hashedPosition = self._hash(item) | |
| head = self.data[hashedPosition] | |
| previous = None | |
| current = head | |
| while current: | |
| if current.value == item: | |
| if previous: | |
| previous.next = current.next | |
| else: | |
| self.data[hashedPosition] = current.next or Node() | |
| self._size -= 1 | |
| return | |
| previous = current | |
| current = current.next | |
| def __iter__(self): | |
| self.iterCounter = 0 | |
| self.step = 0 | |
| self.nextItem = None | |
| return self | |
| def __next__(self): | |
| if self.iterCounter == len(self): | |
| raise StopIteration | |
| self.iterCounter += 1 | |
| if self.nextItem: | |
| value = self.nextItem.value | |
| self.nextItem = self.nextItem.next | |
| return value | |
| current = self.data[self.step] | |
| while not current.value: | |
| self.step += 1 | |
| current = self.data[self.step] | |
| self.nextItem = current.next | |
| self.step += 1 | |
| return current.value | |
| def __contains__(self, item): | |
| hashedPosition = self._hash(item) | |
| if self.data[hashedPosition].value: | |
| current = self.data[hashedPosition] | |
| while current: | |
| if current.value == item: | |
| return True | |
| current = current.next | |
| return False | |
| def __len__(self): | |
| return self._size | |
| def __repr__(self): | |
| return "Set(%s)" % str([x.value for x in self.data if x.value]) | |
| def _hash(self, item): | |
| return abs(hash(item)) % self._capacity |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import unittest | |
| from custom_set import Set | |
| class SetTest(unittest.TestCase): | |
| def test_add(self): | |
| cSet = Set() | |
| cSet.add("foo") | |
| assert len(cSet) == 1 | |
| def test_dont_add_duplicate(self): | |
| cSet = Set() | |
| cSet.add("foo") | |
| cSet.add("foo") | |
| assert len(cSet) == 1 | |
| def test_remove(self): | |
| cSet = Set() | |
| cSet.add("foo") | |
| cSet.add("bar") | |
| cSet.add("baz") | |
| assert len(cSet) == 3 | |
| cSet.remove("foo") | |
| assert len(cSet) == 2 | |
| assert "foo" not in cSet | |
| def test_contains(self): | |
| cSet = Set() | |
| cSet.add("foo") | |
| cSet.add("bar") | |
| assert "bar" in cSet | |
| def test_iteration(self): | |
| cSet = Set() | |
| cSet.add("foo") | |
| cSet.add("bar") | |
| elements_to_check = ["foo", "bar"] | |
| iterable = iter(cSet) | |
| current = next(iterable) | |
| assert current in elements_to_check | |
| elements_to_check.remove(current) | |
| current = next(iterable) | |
| assert current in elements_to_check | |
| def test_in_iteration(self): | |
| cSet = Set() | |
| cSet.add("foo") | |
| cSet.add("bar") | |
| elements_to_check = ["foo", "bar"] | |
| for el in cSet: | |
| assert el in elements_to_check | |
| elements_to_check.remove(el) | |
| if __name__ == '__main__': | |
| unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment