diff --git a/README.md b/README.md index 16f4b85..5cc2692 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,6 @@ We created a linked list method where the list knows about the first element, an We also created a stack where an element can be added to the top of the stack, and popped from the top. But they are not linked and you can only manipulate the top of the stack. +I created a function to test for proper parenthetics in a given input. If there are too many opening parentheses, the function will return 1. If there are closed parentheses before opening parentheses, it will return -1. Otherwise, the function returns 0 to show the input is balanced. + This repository is a collaboration between Jake Anderson and James Warren while attending the Code Fellows Python Development Accelerator in Winter 2015. \ No newline at end of file diff --git a/linked_list.py b/linked_list.py index c782093..06917e7 100644 --- a/linked_list.py +++ b/linked_list.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import unicode_literals class Node(object): @@ -7,32 +8,33 @@ def __init__(self, data, nextNode=None): self.nextNode = nextNode def __str__(self): - return self.data + return str(self.data) def __repr__(self): - return self.data + return repr(self.data) class LinkedList(object): def __init__(self, firstNode=None): self.firstNode = firstNode - def insert(self, newNode): - # insert newNode at beginning of list + def insert(self, val): + # insert val at beginning of list + self.newNode = Node(val) if not self.firstNode: - self.firstNode = newNode + self.firstNode = self.newNode else: - newNode.nextNode = self.firstNode - self.firstNode = newNode + self.newNode.nextNode = self.firstNode + self.firstNode = self.newNode def pop(self): # pops first value from list and returns it if self.size() == 0: - return "THE LIST! IT'S EMPTY!!" + raise ValueError("The list is empty") else: obsoleteNode = self.firstNode self.firstNode = self.firstNode.nextNode - return obsoleteNode.data + return obsoleteNode.data.encode('utf-8') def size(self): # returns length of list @@ -46,6 +48,8 @@ def size(self): def search(self, val): # return node containing 'val' in list, if present (else None) currentNode = self.firstNode + if currentNode.data is None: + raise ValueError() while currentNode.data != val: if currentNode.nextNode is None: return None @@ -56,15 +60,12 @@ def search(self, val): def remove(self, node): # remove node from list, wherever it might be if self.size() == 0: - return "THE LIST! IT'S EMPTY!!" + raise ValueError("The list is empty") else: prevNode = None currentNode = self.firstNode - foundNode = False - while not foundNode: - if currentNode == node: - foundNode = True - elif currentNode is None: + while currentNode is not node: + if currentNode is None: raise ValueError() else: prevNode = currentNode @@ -80,6 +81,6 @@ def display(self): display = "(" currentNode = self.firstNode while currentNode is not None: - display += currentNode.data + ", " + display += currentNode.data.encode('utf-8') + ", " currentNode = currentNode.nextNode return display + ")" diff --git a/parenthetics.py b/parenthetics.py new file mode 100644 index 0000000..26eb945 --- /dev/null +++ b/parenthetics.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + + +def parenthetics(inp): + """Checks for balanced parenthetic usage in a given input + + Returns 1 if the string has open parenthetics that are not properly closed. + Returns 0 if the string is balanced. + Returns -1 if the string has closing parentheses before opening. + + """ + count = 0 + for char in inp: + if char == "(": + count += 1 + if char == ")": + count -= 1 + if count < 0: + return -1 + if count >= 1: + return 1 + else: + return 0 diff --git a/stack.py b/stack.py deleted file mode 100644 index 171e056..0000000 --- a/stack.py +++ /dev/null @@ -1,29 +0,0 @@ -class StackItem(object): - def __init__(self, data, next_item=None): - self.data = data - self.next_item = next_item - - def __str__(self): - return self.data - - -class StackFrame(object): - def __init__(self, first_item=None): - self.first_item = first_item - - def push(self, new_item): - # push new_item to beginning of list - if not self.first_item: - self.first_item = new_item - else: - new_item.next_item = self.first_item - self.first_item = new_item - - def pop(self): - # poops first value from list and returns it - if self.first_item is None: - raise ValueError("No items in stack!") - else: - obsolete_item = self.first_item - self.first_item = self.first_item.next_item - return obsolete_item.data diff --git a/test_linked_list.py b/test_linked_list.py index b70ecf2..08b5da1 100644 --- a/test_linked_list.py +++ b/test_linked_list.py @@ -3,105 +3,84 @@ import pytest -def test_node_data(): - newNode = Node("Bob") - assert newNode.data == "Bob" - - def test_node_add(): - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) + newList.insert("Bob") assert newList.firstNode.data == "Bob" def test_next_node_none(): - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) + newList.insert("Bob") assert newList.firstNode.nextNode is None def test_add_second_node(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) + newList.insert("Bob") + newList.insert("Joe") assert newList.firstNode.nextNode.data == "Bob" def test_pop(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) + newList.insert("Bob") + newList.insert("Joe") assert newList.pop() == "Joe" def test_pop_size(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) + newList.insert("Bob") + newList.insert("Joe") newList.pop() assert newList.size() == 1 def test_size(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) + newList.insert("Bob") + newList.insert("Joe") assert newList.size() == 2 def test_search_fail(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) + newList.insert("Bob") + newList.insert("Joe") assert newList.search("Fred") is None def test_search_success(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) - assert newList.search("Bob") == bob + newList.insert("Bob") + newList.insert("Joe") + assert newList.search("Bob") is not None def test_remove(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) - newList.remove(bob) + newList.insert("Bob") + newList.insert("Joe") + newList.remove(newList.search("Bob")) assert newList.search("Bob") is None def test_remove_empty(): newList = LinkedList() - assert newList.remove("Bob") == "THE LIST! IT'S EMPTY!!" + with pytest.raises(ValueError): + newList.remove("Bob") def test_pop_empty(): newList = LinkedList() - assert newList.pop() == "THE LIST! IT'S EMPTY!!" + with pytest.raises(ValueError): + newList.pop() def test_remove_fail(): - joe = Node("Joe") - bob = Node("Bob") newList = LinkedList() - newList.insert(bob) - newList.insert(joe) + newList.insert("Bob") + newList.insert("Joe") with pytest.raises(ValueError): newList.remove("Fred") diff --git a/test_parenthetics.py b/test_parenthetics.py new file mode 100644 index 0000000..e46bc7f --- /dev/null +++ b/test_parenthetics.py @@ -0,0 +1,34 @@ +import pytest +from parenthetics import parenthetics + + +def test_single_open(): + assert parenthetics("(") == 1 + + +def test_single_close(): + assert parenthetics(")") == -1 + + +def test_single_balanced(): + assert parenthetics("()") == 0 + + +def test_multi_open_close_1(): + assert parenthetics("(()") == 1 + + +def test_multi_open_close_2(): + assert parenthetics("())") == -1 + + +def test_broken(): + assert parenthetics("))((") == -1 + + +def test_text(): + assert parenthetics("This is a silly test!") == 0 + + +def test_text_parens(): + assert parenthetics("This is a silly test (but not really that silly)!") == 0 diff --git a/test_stack.py b/test_stack.py deleted file mode 100644 index b581f3e..0000000 --- a/test_stack.py +++ /dev/null @@ -1,52 +0,0 @@ -from stack import StackItem -from stack import StackFrame -import pytest - - -def test_item_data(): - # Tests that "Bacon" is returned when calling .data on item - bacon = StackItem("Bacon") - assert bacon.data == "Bacon" - - -def test_create_stack_frame(): - # Tests that an empty stack can be created - new_stack = StackFrame() - assert new_stack - - -def test_stack_push(): - # Tests that "Bacon" is first item when pushed to stack - bacon = StackItem("Bacon") - new_stack = StackFrame() - new_stack.push(bacon) - assert new_stack.first_item.data == "Bacon" - - -def test_stack_push_multi(): - # Tests that we can push multiple items to stack, then get expected results from pop - bacon = StackItem("Bacon") - steak = StackItem("Steak") - grilled_cheese = StackItem("Grilled Cheese") - new_stack = StackFrame() - new_stack.push(bacon) - new_stack.push(steak) - new_stack.push(grilled_cheese) - new_stack.pop() - new_stack.pop() - assert new_stack.first_item.data == "Bacon" - - -def test_stack_pop(): - # Tests that "Bacon" is returned when it is popped from stack - bacon = StackItem("Bacon") - new_stack = StackFrame() - new_stack.push(bacon) - assert new_stack.pop() == "Bacon" - - -def test_empty_stack_pop(): - # Tests that pop() on empty stack returns ValueError - new_stack = StackFrame() - with pytest.raises(ValueError): - new_stack.pop()