Skip to content

Robin U. Familara - Sprint-Challenge--Data-Structures-Python #434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions names/binary_search_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
class BSTNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None

def insert(self, value):
# Insertion of a key, a new key is always inserted at leaf.
# We start searching a key from root
# till we hit a leaf node. Once a leaf node is found,
# the new node is added as a child of the leaf node.
if value < self.value:
#Go Left
if not self.left:
#add as leaf
self.left = BSTNode(value)
else:
#check again
self.left.insert(value)
else:
#Go Right
if not self.right:
self.right = BSTNode(value)
else:
self.right.insert(value)

def contains(self, target):
# Searching a key
# To search a given key in Binary Search Tree, we first compare it with root,
# if the key is present at root, we return root. If key is greater than root's
# key, we recur for right subtree of root node. Otherwise we recur for left
# subtree.
if self.value == target:
return True
if target < self.value:
if not self.left:
return False
else:
return self.left.contains(target)
else:
if not self.right:
return False
else:
return self.right.contains(target)

def get_max(self):
# Keep going right until you find a node without a child to the right
if not self:
return None
else:
if not self.right:
return self.value
else:
return self.right.get_max()

def for_each(self, callback):
# We need to traverse the tree similar to how the print works in the demo
# For each value append it to the array

# Call the function
callback(self.value)
if self.left:
self.left.for_each(callback)
if self.right:
self.right.for_each(callback)
20 changes: 14 additions & 6 deletions names/names.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import time
from binary_search_tree import BSTNode

start_time = time.time()

Expand All @@ -10,13 +11,20 @@
names_2 = f.read().split("\n") # List containing 10000 names
f.close()

duplicates = [] # Return the list of duplicates in this data structure
duplicates = []

# Replace the nested for loops below with your improvements
for name_1 in names_1:
for name_2 in names_2:
if name_1 == name_2:
duplicates.append(name_1)
bst = BSTNode(names_1[0])

names2_dict = {}

for name in names_2:
names2_dict[name] = 1

for name in names_1:
if names2_dict.get(name) == None:
pass
else:
duplicates.append(name)

end_time = time.time()
print (f"{len(duplicates)} duplicates:\n\n{', '.join(duplicates)}\n\n")
Expand Down
110 changes: 110 additions & 0 deletions names/test_binary_search_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import unittest
import random
import sys
import io
from binary_search_tree import BSTNode

class BSTNOdeTests(unittest.TestCase):
def setUp(self):
self.bst = BSTNode(5)

def test_insert(self):
self.bst.insert(2)
self.bst.insert(3)
self.bst.insert(7)
self.bst.insert(6)
self.assertEqual(self.bst.left.right.value, 3)
self.assertEqual(self.bst.right.left.value, 6)

def test_handle_dupe_insert(self):
self.bst2 = BSTNode(1)
self.bst2.insert(1)
self.assertEqual(self.bst2.right.value, 1)

def test_contains(self):
self.bst.insert(2)
self.bst.insert(3)
self.bst.insert(7)
self.assertTrue(self.bst.contains(7))
self.assertFalse(self.bst.contains(8))

def test_get_max(self):
self.assertEqual(self.bst.get_max(), 5)
self.bst.insert(30)
self.assertEqual(self.bst.get_max(), 30)
self.bst.insert(300)
self.bst.insert(3)
self.assertEqual(self.bst.get_max(), 300)

def test_for_each(self):
arr = []
cb = lambda x: arr.append(x)

v1 = random.randint(1, 101)
v2 = random.randint(1, 101)
v3 = random.randint(1, 101)
v4 = random.randint(1, 101)
v5 = random.randint(1, 101)

self.bst.insert(v1)
self.bst.insert(v2)
self.bst.insert(v3)
self.bst.insert(v4)
self.bst.insert(v5)

self.bst.for_each(cb)

self.assertTrue(5 in arr)
self.assertTrue(v1 in arr)
self.assertTrue(v2 in arr)
self.assertTrue(v3 in arr)
self.assertTrue(v4 in arr)
self.assertTrue(v5 in arr)

def test_print_traversals(self):
# WARNING: Tests are for Print()
# Debug calls to Print() in functions will cause failure

stdout_ = sys.stdout # Keep previous value
sys.stdout = io.StringIO()

self.bst = BSTNode(1)
self.bst.insert(8)
self.bst.insert(5)
self.bst.insert(7)
self.bst.insert(6)
self.bst.insert(3)
self.bst.insert(4)
self.bst.insert(2)

output = sys.stdout.getvalue()
self.assertEqual(output, "1\n2\n3\n4\n5\n6\n7\n8\n")

self.bst.in_order_print(self.bst)

sys.stdout = io.StringIO()
self.bst.bft_print(self.bst)
output = sys.stdout.getvalue()
self.assertTrue(output == "1\n8\n5\n3\n7\n2\n4\n6\n" or
output == "1\n8\n5\n7\n3\n6\n4\n2\n")

sys.stdout = io.StringIO()
self.bst.dft_print(self.bst)
output = sys.stdout.getvalue()
self.assertTrue(output == "1\n8\n5\n7\n6\n3\n4\n2\n" or
output == "1\n8\n5\n3\n2\n4\n7\n6\n")

sys.stdout = io.StringIO()
self.bst.pre_order_dft(self.bst)
output = sys.stdout.getvalue()
self.assertEqual(output, "1\n8\n5\n3\n2\n4\n7\n6\n")

sys.stdout = io.StringIO()
self.bst.post_order_dft(self.bst)
output = sys.stdout.getvalue()
self.assertEqual(output, "2\n4\n3\n6\n7\n5\n8\n1\n")

sys.stdout = stdout_ # Restore stdout

if __name__ == '__main__':
unittest.main()
19 changes: 18 additions & 1 deletion reverse/reverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,21 @@ def contains(self, value):
return False

def reverse_list(self, node, prev):
pass
# use recursion to solve this problem
# check if the list is empty
if node is None:
return "It's an empty list"
# store the node's next points to a new variable
current_next = node.get_next()
# reverse, set the node's next points to his prev
node.set_next(prev)

# if current node is not the tail, continue the recursion,
# and reverse the points: node = current_next, prev = node...
if current_next is not None:
self.reverse_list(current_next,node)
# if the current node is the tail, set it head...
else:
self.head = node


16 changes: 13 additions & 3 deletions ring_buffer/ring_buffer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
class RingBuffer:
def __init__(self, capacity):
pass
self.capacity = capacity # capacity : max number in the buffer
self.data = [] # empty storage for appending data later
self.current_pos = 0 # current position index

def append(self, item):
pass
if len(self.data) < self.capacity:
self.data.append(item)

else:
self.data[self.current_pos] = item # the oldest one's position starting from 0

self.current_pos += 1 # then position plus 1
self.current_pos = self.current_pos % (self.capacity)

def get(self):
pass
# return list of elements in correct order
return self.data