diff --git a/README.md b/README.md index 0da5632..b6c8d6d 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,8 @@ - **Tests**: `test_grouped_by_commas.py` - **URL**: [challenge url](https://www.codewars.com/kata/grouped-by-commas) +**Proper Parenthetics (5th Kyu)** + +- **Module**: `parenthetics.py` +- **Tests**: `test_parenthetics.py` +- **URL**: [challenge URL](https://www.codewars.com/kata/valid-parentheses/train/python) \ No newline at end of file diff --git a/src/parenthetics.py b/src/parenthetics.py new file mode 100644 index 0000000..1a0e8da --- /dev/null +++ b/src/parenthetics.py @@ -0,0 +1,112 @@ +"""Use Linked List to determine proper parenthetics.""" + + +class Node(object): + """Creates a node object.""" + + def __init__(self, data, next_node): + """Constructor for the Node object.""" + self.data = data + self.next = next_node + + +class LinkedList(object): + """Class for containing object called LinkedList.""" + + def __init__(self, iterable=()): + """Constructor for the Linked List object.""" + self.head = None + self._counter = 0 + if hasattr(iterable, '__iter__') or isinstance(iterable, str): + for item in iterable: + self.push(item) + + def push(self, val): + """Add a new value to the head of the linked list.""" + new_head = Node(val, self.head) + self.head = new_head + self._counter += 1 + + def pop(self): + """Remove & return the value of the head of the Linked List.""" + if not self.head: + raise IndexError("The list is empty, so there's nothing to pop.") + output = self.head.data + self.head = self.head.next + self._counter -= 1 + return output + + def size(self): + """Return the size of our list.""" + return self._counter + + def __len__(self): + """Work with len() function to find length of linked list.""" + return self._counter + + def search(self, val): + """Search for a given node value and returns it.""" + curr = self.head + if not curr: + return + while curr: + if curr.data == val: + return curr + curr = curr.next + return + + def remove(self, val): + """Search for a given value and remove it from the linked list.""" + curr = self.head + while curr: + if curr.next == val: + curr.next = curr.next.next + self._counter -= 1 + return + curr = curr.next + + def display(self): + """Will return a string representing the list. + + as if it were a Python tuple literal: "(12, ‘sam’, 37, ‘tango’)" + """ + if self.head is None: + return + curr = self.head + output = "(" + while curr: + if isinstance(curr.data, (int, float)): + output += "{}, ".format(str(curr.data)) + else: + output += "'{}', ".format(str(curr.data)) + curr = curr.next + output = output[:-2] + output += ")" + return output + + def __repr__(self): + """Print the list to the screen using built in print().""" + return self.display() + + +def proper_parenthetics(string): + """Determine if input string has matched parentheses.""" + new_ll = LinkedList(string) + newlist = [] + for num in range(new_ll.size()): + newlist.append(new_ll.pop()) + newlist.reverse() + open_count = 0 + for char in newlist: + if open_count == 0 and char == ")": + return -1 + elif char == "(": + open_count += 1 + elif char == ")": + open_count -= 1 + + if open_count < 0: + return -1 + elif open_count > 0: + return 1 + return 0 diff --git a/src/test_parenthetics.py b/src/test_parenthetics.py new file mode 100644 index 0000000..9dd765b --- /dev/null +++ b/src/test_parenthetics.py @@ -0,0 +1,33 @@ +"""Test proper_parenthetics for proper output.""" + +from parenthetics import proper_parenthetics + + +def test_parenthetics_with_open_condition_single_entry(): + """Test that open parenthetics returns 1.""" + assert proper_parenthetics("(") == 1 + + +def test_parenthetics_with_broken_condition(): + """Test that broken parenthetics returns -1.""" + assert proper_parenthetics(")(()))") == -1 + + +def test_parenthetics_with_open_condition(): + """Test that broken parenthetics returns -1.""" + assert proper_parenthetics("()()())((") == -1 + + +def test_parenthetics_with_balanced_condition(): + """Test that balanced parenthectics returns 0.""" + assert proper_parenthetics("(())((()())())") == 0 + + +def test_parentthetics_with_open_condition(): + """Test that open condition returns 1.""" + assert proper_parenthetics("((())((())((())") == 1 + + +def test_parentthetics_with_ta_suggestion(): + """Test that open condition returns 1.""" + assert proper_parenthetics("()))((()") == -1