diff --git a/.DS_Store b/.DS_Store index 66b2488..486420a 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/setup.py b/setup.py index 30846ee..b02ac1f 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,15 @@ +"""Setup for data-structure package.""" from setuptools import setup extra_packages = { - 'testing': ['ipython', 'pytest', 'pytest-cov', 'tox'] + 'testing': ['ipython', 'pytest', 'tox'] } setup( name='data-structures', desctription='A variety of data structures built with Python.', version='0.1', - author='James Salamonsen', + author='James Salamonsen and Alex Short', author_email='jamessalamonsen@gmail.com', license='MIT', py_modules=[], @@ -19,4 +20,4 @@ 'console_scripts': [ ] } -) \ No newline at end of file +) diff --git a/src/.DS_Store b/src/.DS_Store index 38734ca..a1d6b9e 100644 Binary files a/src/.DS_Store and b/src/.DS_Store differ diff --git a/src/BST.py b/src/BST.py deleted file mode 100644 index 502cace..0000000 --- a/src/BST.py +++ /dev/null @@ -1,221 +0,0 @@ -"""Implementing a Binary Search tree with In Order Traversal.""" - - -class Node(object): - def __init__(self, entry, left=None, iterable=None, parent=None): - """Node for tree.""" - self.val = entry - self.left = left - self.right = iterable - self.parent = parent - - -class BinarySearchTree(object): - - def __init__(self, iterable=None): - # import pdb; pdb.set_trace() - """This will sety what wwe will be iterating through.""" - self.visited = [] - self.list = [] - self.size = 0 - self.root = None - self.iterable = iterable - if iterable is not None: - if type(iterable) in [list, tuple]: - for element in iterable: - self.list.append(element) - self.insert(element) - - def insert(self, entry): - # import pdb; pdb.set_trace() - if type(entry) not in [float, int]: - raise TypeError("NUMBERS!!!!! numbers...") - if not self.root: - self.root = Node(entry) - self.size += 1 - else: - curr = self.root - while curr: - if entry > curr.val: - if curr.right: - curr = curr.right - continue - else: - curr.right = Node(entry) - self.size += 1 - curr.right.parent = curr - elif entry < curr.val: - if curr.left: - curr = curr.left - continue - else: - curr.left = Node(entry) - self.size += 1 - curr.left.parent = curr - else: - return - - def search(self, entry): - """.""" - if type(entry) not in [float, int]: - raise TypeError("NUMBERS!!!!! numbers...") - else: - curr = self.root - while curr: - if entry > curr.val: - if curr.right: - curr = curr.right - continue - elif entry < curr.val: - if curr.left: - curr = curr.left - continue - else: - return curr - - def depth_first(self, entry): - if entry is None: - return 0 - left_depth = self.depth_first(entry.left) - right_depth = self.depth_first(entry.right) - if (left_depth > right_depth): - return left_depth + 1 - return right_depth + 1 - - def breadth_first(self): - self.nodes_to_visit = [] - curr = self.root - self.nodes_to_visit.append(curr) - while self.nodes_to_visit: - curr = self.nodes_to_visit.pop(0) - if curr.left: - self.nodes_to_visit.append(curr.left) - if curr.right: - self.nodes_to_visit.append(curr.right) - yield curr - - def pre_order_trav(self, entry=None): - if entry: - curr = entry - else: - curr = self.root - yield curr.val - if curr.left: - for item in self.pre_order_trav(curr.left): - yield item - if curr.right: - for item in self.pre_order_trav(curr.right): - yield item - - def pre_order(self): - for node_data in self.pre_order_trav(): - yield node_data - - def in_order_trav(self, entry=None): - if entry: - curr = entry - else: - curr = self.root - if curr.left: - for item in self.in_order_trav(curr.left): - yield item - yield curr.val - if curr.right: - for item in self.in_order_trav(curr.right): - yield item - - def in_order(self): - for node_data in self.in_order_trav(): - yield node_data - - def post_order_trav(self, entry=None): - if entry: - curr = entry - else: - curr = self.root - if curr.left: - for item in self.post_order_trav(curr.left): - yield item - if curr.right: - for item in self.post_order_trav(curr.right): - yield item - yield curr.val - - def post_order(self): - for node_data in self.post_order_trav(): - yield node_data - - def check_that_balance(self, target=None): - """check the balance of your treeeee""" - if self.size == 0: - return 0 - if not target: - target = self.root - else: - target = self.search(target) - return self.depth_first(target.right) - self.depth_first(target.left) - - def find_min_depth(self, target): - curr = target - while curr.left is not None: - curr = curr.left - return curr - - def find_max_depth(self, target): - curr = target - while curr.right is not None: - curr = curr.right - return curr - - def deletion(self, target): - """nope""" - delete_node = self.search(target) - if delete_node is None: - return 'This is the end!' - else: - self.size -= 1 - if delete_node.left is None and delete_node.right is None: - if delete_node.val > delete_node.parent.val: - delete_node.parent.right = None - else: - delete_node.parent.left = None - elif delete_node.left and not delete_node.right: - if delete_node.val > delete_node.parent.val: - delete_node.parent.right = delete_node.left - delete_node.left.parent = delete_node.parent - else: - delete_node.parent.left = delete_node.left - delete_node.left.parent = delete_node.parent - elif delete_node.right and not delete_node.left: - if delete_node.val > delete_node.parent.val: - delete_node.parent.right = delete_node.right - delete_node.right.parent = delete_node.parent - else: - delete_node.parent.left = delete_node.right - delete_node.left.parent = delete_node.parent - else: - if self.check_that_balance(target) > 0: - min_val = self.find_min_depth(delete_node.right) - delete_node.val = min_val.val - if min_val.right is None: - min_val.parent.left = None - min_val.parent = None - else: - min_val.val = min_val.right.val - min_val.right.parent = None - min_val.right = None - else: - max_val = self.find_max_depth(delete_node.left) - delete_node.val = max_val.val - if max_val.left is None: - max_val.parent.right = None - max_val.parent = None - else: - max_val.val = max_val.left.val - max_val.left.parent = None - max_val.left = None - -if __name__ == '__main__': # pragma: no cover - b = BinarySearchTree([5, 3, 7, 2, 8, 4, 9, 1]) - gen = b.in_order() - [i for i in gen] diff --git a/src/insertion_sort.py b/src/insertion_sort.py new file mode 100644 index 0000000..49b0f97 --- /dev/null +++ b/src/insertion_sort.py @@ -0,0 +1,46 @@ +"""An example of the insertion sort.""" + + +def insertion_sort(numbers): + """Will sort any given number iterable into a min first list.""" + new = [] + while len(new) < len(numbers): + x = 0 + for i in numbers: + while True: + try: + if new[x] >= i: + new.insert(x, i) + x = 0 + break + else: + x += 1 + except IndexError: + new.append(i) + x = 0 + break + return new + + +def existing_set_insertion_sort(numbers, existing_set): + """Will sort any given number iterable into a min first list.""" + new = list(existing_set) + while len(new) < len(numbers) + len(existing_set): + x = 0 + for i in numbers: + while True: + try: + if x is 0 and new[x] >= i: + new.insert(x, i) + break + elif new[x] >= i: + new.insert(x, i) + x = 0 + break + else: + x += 1 + except IndexError: + new.append(i) + x = 0 + break + return new diff --git a/src/merge_sort.py b/src/merge_sort.py new file mode 100644 index 0000000..14a8e5c --- /dev/null +++ b/src/merge_sort.py @@ -0,0 +1,92 @@ +"""A merge sort function.""" +from insertion_sort import existing_set_insertion_sort as esis + +from insertion_sort import insertion_sort + + +def merge2(numbers): + """Mob Programming""" + if len(numbers) == 1: + return numbers + if len(numbers) == 2: + if numbers[0] > numbers[1]: + numbers[0], numbers[1] = numbers[1], numbers[0] + return numbers + midpnt = len(numbers) // 2 + left = merge2(numbers[:midpnt]) + right = merge2(numbers[midpnt:]) + + output = [] + while left or right: + if left and right and left[0] < right[0]: + output.append(left.pop(0)) + elif left and right and left[0] >= right[0]: + output.append(right.pop(0)) + elif left and not right: + output.extend(left) + break + elif right and not left: + output.extend(right) + break + + return output + + +def merge_sort(numbers): + """Sort a iterable of numbers into min first via merge sort non-recursively.""" + final = [] + compare = [] + temp = [] + hold_extra = [] + if len(numbers) == 1: + return numbers + elif len(numbers) == 2: + if numbers[0] > numbers[1]: + numbers[0], numbers[1] = numbers[1], numbers[0] + return numbers + + elif len(numbers) == 3: + return insertion_sort(numbers) + if len(numbers) % 2 == 0: + for i in range(0, len(numbers), 2): + temp.append(numbers[i: i + 2]) + for pair in temp: + if pair[0] > pair[1]: + pair[0], pair[1] = pair[1], pair[0] + else: + for i in range(0, len(numbers) - 1, 2): + temp.append(numbers[i: i + 2]) + for pair in temp: + if pair[0] > pair[1]: + pair[0], pair[1] = pair[1], pair[0] + hold_extra.append(numbers[len(numbers) - 1]) + while 1: + if final: + if len(final) == 1: + if hold_extra: + return esis(hold_extra, final[0]) + return final[0] + temp = list(final) + if len(temp) % 2 == 1: + hold_extra.extend(temp[len(temp) - 1]) + final = [] + for i in range(0, len(temp) - 1, 2): + t = 0 + k = 0 + while 1: + if t >= len(temp[i]) and k >= len(temp[i + 1]): + final.append(compare) + compare = [] + break + elif t >= len(temp[i]): + compare.append(temp[i + 1][k]) + k += 1 + elif k >= len(temp[i + 1]): + compare.append(temp[i][t]) + t += 1 + elif temp[i][t] >= temp[i + 1][k]: + compare.append(temp[i + 1][k]) + k += 1 + elif temp[i][t] <= temp[i + 1][k]: + compare.append(temp[i][t]) + t += 1 diff --git a/src/quick_sort.py b/src/quick_sort.py new file mode 100644 index 0000000..d6ee68d --- /dev/null +++ b/src/quick_sort.py @@ -0,0 +1,25 @@ +"""This is an implemntation of quick_sort.""" + + +def quick_sort(numbers): + import pdb; pdb.set_trace() + pivot = numbers[0] + pivot_index = numbers.index(pivot) + store_index = numbers.index(pivot) + 1 + for i in numbers[1:]: + if i < pivot: + new_nums = [pivot] + bigger_nums = [] + check_list = list(numbers[store_index:]) + count = 0 + for number in check_list: + count += 1 + thing = check_list[count] + print(number) + print(thing) + if number < pivot: + number, check_list[store_index] = check_list[store_index], number + store_index += 1 + print(new_nums) + print(check_list) + # pivot, check_list[store_index - 1] = check_list[store_index - 1], pivot diff --git a/src/radix_sort.py b/src/radix_sort.py new file mode 100644 index 0000000..4279c90 --- /dev/null +++ b/src/radix_sort.py @@ -0,0 +1,15 @@ +from itertools import chain + + +def radix(set, curr_idx=0): + bucket = [[] for _ in range(10)] + place = curr_idx + for number in set: + try: + value = int(str(number)[:: - 1][place]) + bucket[value].append(number) + except: + bucket[0].append(number) + if len(bucket[0]) == len(set): + return bucket[0] + return radix(list(chain.from_iterable(bucket)), place+1) diff --git a/src/something.py b/src/something.py new file mode 100644 index 0000000..f27205c --- /dev/null +++ b/src/something.py @@ -0,0 +1,67 @@ +def merge_sort(numbers): + """Sort a iterable of numbers into min first via merge sort.""" + final = [] + compare = [] + temp = [] + if len(numbers) == 1: + return numbers + elif len(numbers) == 2: + if numbers[0] > numbers[1]: + numbers[0], numbers[1] = numbers[1], numbers[0] + return numbers + elif len(numbers) == 3: + + elif len(numbers) % 2 == 0: + for i in range(0, len(numbers), 2): + temp.append(numbers[i: i + 2]) + for pair in temp: + if pair[0] > pair[1]: + pair[0], pair[1] = pair[1], pair[0] + else: + for i in range(0, len(numbers) - 1, 2): + temp.append(numbers[i: i + 2]) + for pair in temp: + if pair[0] > pair[1]: + pair[0], pair[1] = pair[1], pair[0] + temp[0].append(numbers[len(numbers) - 1]) + while 1: + if final: + if len(final) == 1: + return final[0] + temp = list(final) + print(temp) + final = [] + if len(temp) % 2 != 0: + temp[0].extend(temp[len(temp) - 1]) + for i in range(0, len(temp) - 1, 2): + t = 0 + k = 0 + while 1: + # import pdb; pdb.set_trace() + if t >= len(temp[i]) and k >= len(temp[i + 1]): + if len(temp) % 2 != 0: + num = round(len(compare) / 2) + ss = compare[:num] + for i in range(0, len(ss) - 1, 2): + if ss[i] > ss[i + 1]: + ss[i], ss[i + 1] = ss[i + 1], ss[i] + final.append(ss) + ss = compare[num:] + for i in range(0, len(ss) - 1, 2): + if ss[i] > ss[i + 1]: + ss[i], ss[i + 1] = ss[i + 1], ss[i] + final.append(ss) + compare = [] + break + elif t >= len(temp[i]): + compare.append(temp[i + 1][k]) + k += 1 + elif k >= len(temp[i + 1]): + compare.append(temp[i][t]) + t += 1 + elif temp[i][t] >= temp[i + 1][k]: + compare.append(temp[i + 1][k]) + k += 1 + elif temp[i][t] <= temp[i + 1][k]: + compare.append(temp[i][t]) + t += 1 diff --git a/src/test_BST.py b/src/test_BST.py deleted file mode 100644 index 3c3bf66..0000000 --- a/src/test_BST.py +++ /dev/null @@ -1,167 +0,0 @@ -"""Test the tree.py module.""" -import pytest -from BST import BinarySearchTree - -a = BinarySearchTree([12, 42, 4, 87, 2, 65, 0]) - -b = BinarySearchTree([5, 3, 7, 2, 8, 4, 9, 1]) - -c = BinarySearchTree([-2, -6, 22.55, 0, -94, 2, -1]) - - -@pytest.fixture -def bitr(): # pragma: no cover - """Init a new Binary Tree.""" - tree = BinarySearchTree() - return tree - - -@pytest.fixture -def bitr_iter(): # pragma: no cover - """Init a new Binary tree from an iterable.""" - return a.iterable - return b.iterable - return c.iterable - - -def test_tree_empty(): - """Instantiate a new Binary tree, that should be an empty list.""" - b = BinarySearchTree([]) - assert b.size == 0 - - -def test_type_error_insert(): - """Test for type error in insert function""" - with pytest.raises(TypeError): - b.insert('not a number') - - -def test_type_error_search(): - """Test for type error in the search function""" - with pytest.raises(TypeError): - b.search('still not a number') - - -def test_bitr_search(): - """Test the seartch function""" - assert a.search(12).left.val == 4 - assert a.search(4).left.val == 2 - assert a.search(87).left.val == 65 - assert b.search(3).left.val == 2 - assert b.search(5).left.val == 3 - assert c.search(-2).left.val == -6 - assert c.search(0).left.val == -1 - assert c.search(-6).left.val == -94 - - -def test_bitr_iter_in_order(): - """Test the in order funciton.""" - gena = a.in_order() - a_list = [item for item in gena] - assert a_list == [0, 2, 4, 12, 42, 65, 87] - assert a_list[0] == 0 - assert a_list[1] == 2 - assert a_list[2] == 4 - assert len(a_list) == 7 - genb = b.in_order() - b_list = [item for item in genb] - assert b_list == [1, 2, 3, 4, 5, 7, 8, 9] - assert b_list[0] == 1 - assert b_list[1] == 2 - assert b_list[2] == 3 - assert len(b_list) == 8 - genc = c.in_order() - c_list = [item for item in genc] - assert c_list == [-94, -6, -2, -1, 0, 2, 22.55] - assert c_list[0] == -94 - assert c_list[1] == -6 - assert c_list[2] == -2 - assert len(c_list) == 7 - - -def test_bitr_iter_pre_order(): - """Test the pre order funciton.""" - gena = a.pre_order() - a_list = [item for item in gena] - assert a_list == [12, 4, 2, 0, 42, 87, 65] - assert a_list[0] == 12 - assert a_list[1] == 4 - assert a_list[6] == 65 - assert len(a_list) == 7 - genb = b.pre_order() - b_list = [item for item in genb] - assert b_list == [5, 3, 2, 1, 4, 7, 8, 9] - assert b_list[0] == 5 - assert b_list[1] == 3 - assert b_list[6] == 8 - assert len(b_list) == 8 - genc = c.pre_order() - c_list = [item for item in genc] - assert c_list == [-2, -6, -94, 22.55, 0, -1, 2] - assert c_list[0] == -2 - assert c_list[1] == -6 - assert c_list[6] == 2 - assert len(c_list) == 7 - - -def test_bitr_iter_post_order(): - """Test the post order funciton.""" - gena = a.post_order() - a_list = [item for item in gena] - assert a_list == [0, 2, 4, 65, 87, 42, 12] - assert a_list[0] == 0 - assert a_list[3] == 65 - assert a_list[2] == 4 - assert len(a_list) == 7 - gen = b.post_order() - b_list = [item for item in gen] - assert b_list == [1, 2, 4, 3, 9, 8, 7, 5] - assert b_list[0] == 1 - assert b_list[3] == 3 - assert b_list[2] == 4 - assert len(b_list) == 8 - genc = c.post_order() - c_list = [item for item in genc] - assert c_list == [-94, -6, -1, 2, 0, 22.55, -2] - assert c_list[0] == -94 - assert c_list[3] == 2 - assert c_list[2] == -1 - assert len(c_list) == 7 - - -def test_bitr_breadth(): - """Test the breadth first traversal.""" - abf = a.breadth_first() - assert [ab.val for ab in abf] == [12, 4, 42, 2, 87, 0, 65] - bbf = b.breadth_first() - assert [bb.val for bb in bbf] == [5, 3, 7, 2, 4, 8, 1, 9] - cbf = c.breadth_first() - assert [cb.val for cb in cbf] == [-2, -6, 22.55, -94, 0, -1, 2] - - -def test_bitr_insert(): - """Push the insert function.""" - a.insert(30) - gena = a.in_order() - a_list = [item for item in gena] - assert a_list == [0, 2, 4, 12, 30, 42, 65, 87] - a.insert(2.5) - gena = a.in_order() - a_list = [item for item in gena] - assert a_list == [0, 2, 2.5, 4, 12, 30, 42, 65, 87] - b.insert(1.1) - genb = b.in_order() - b_list = [item for item in genb] - assert b_list == [1, 1.1, 2, 3, 4, 5, 7, 8, 9] - b.insert(-90) - genb = b.in_order() - b_list = [item for item in genb] - assert b_list == [-90, 1, 1.1, 2, 3, 4, 5, 7, 8, 9] - c.insert(31) - genc = c.in_order() - c_list = [item for item in genc] - assert c_list == [-94, -6, -2, -1, 0, 2, 22.55, 31] - c.insert(22.54) - genc = c.in_order() - c_list = [item for item in genc] - assert c_list == [-94, -6, -2, -1, 0, 2, 22.54, 22.55, 31] diff --git a/src/test_insertion_sort.py b/src/test_insertion_sort.py new file mode 100644 index 0000000..2afb2d5 --- /dev/null +++ b/src/test_insertion_sort.py @@ -0,0 +1,12 @@ +"""Test for the insertion sort.""" +from insertion_sort import insertion_sort +import random + + +def test_insertion_sort(): + """Test that any given numerical iterable is returned as a min first list.""" + assert insertion_sort(random.sample(range(100), 100)) == list(range(100)) + assert insertion_sort(random.sample(range(100), 100)) == list(range(100)) + assert insertion_sort(random.sample(range(100), 100)) == list(range(100)) + assert insertion_sort(random.sample(range(100), 100)) == list(range(100)) + assert insertion_sort(random.sample(range(100), 100)) == list(range(100)) diff --git a/tox.ini b/tox.ini index 36db6d0..c17d845 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27, py36 +envlist = py27 py36 [testenv] commands = py.test src --cov=src --cov-report term-missing