diff --git a/README.md b/README.md index 3406eb5..022952b 100644 --- a/README.md +++ b/README.md @@ -20,3 +20,28 @@ Available methods include: * pop() See the doc strings for implementation details. + +##Parenthetics +Contains the parenthetical function which checks the validity of parenthetical usage. + +The function will examine a unicode string as its sole argument and return as follows: + +* Return 1 if the string is "open" (there are open parens that are not closed) +* Return 0 if the string is "balanced" (there are an equal number of open and closed parentheses in the string) +* Return -1 if the string is "broken" (a closing parens has not been proceeded by one that opens) + +###Examples + +Open Case: +* '( ()' + +Balanced Case: +* '(())' + +Broken Case: +* ') ()' + +###Notes +This function was written with inspiration from the work of: +* [Jason Tyler](https://github.com/jay-tyler) +* [Jim Grant](https://github.com/MigrantJ) diff --git a/linked_list.py b/linked_list.py index f482d72..63e0763 100644 --- a/linked_list.py +++ b/linked_list.py @@ -29,6 +29,10 @@ def __repr__(self): node = node.next return "({})".format(output.rstrip(' ,')) + def __len__(self): + """Return the length of the LinkedList.""" + return self.size() + def insert(self, val): """Insert value at head of LinkedList. diff --git a/parenthetics.py b/parenthetics.py new file mode 100644 index 0000000..4b48daf --- /dev/null +++ b/parenthetics.py @@ -0,0 +1,27 @@ +from __future__ import unicode_literals + +from stack import Stack + + +def parenthetical(string): + """Examine string for valid use of parentheses. + args: + string: the unicode string to Examine + returns: + 1 if the string is "open" -- unclosed parentheses + 0 if the string is "balanced" -- equal number of parentheses + -1 if the string is "broken" -- closing parentheses before opening + """ + open_parens = Stack() + for char in string: + if char == '(': + open_parens.push(char) + elif char == ')': + try: + open_parens.pop() + except IndexError: + return -1 + if len(open_parens) >= 1: + return 1 + else: + return 0 diff --git a/stack.py b/stack.py index 11d387c..eae6825 100644 --- a/stack.py +++ b/stack.py @@ -12,6 +12,9 @@ def __init__(self, iterable=()): def __repr__(self): return repr(self.other) + def __len__(self): + return self.other.size() + def push(self, value): """Add a value to the head of the stack. diff --git a/test_parenthetics.py b/test_parenthetics.py new file mode 100644 index 0000000..41691ec --- /dev/null +++ b/test_parenthetics.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals +import pytest + +from parenthetics import parenthetical + + +def test_open_parens(): + assert parenthetical('(') == 1 + assert parenthetical('( (()) ') == 1 + assert parenthetical(' ()() (') == 1 + assert parenthetical('( other ) characters (') + + +def test_balanced_parens(): + assert parenthetical('((()))') == 0 + assert parenthetical('()()()') == 0 + assert parenthetical('( other ) characters ()') == 0 + + +def test_broken_parens(): + assert parenthetical(')') == -1 + assert parenthetical(') )(()))') == -1 + assert parenthetical(' ()()())') == -1 + assert parenthetical('( other ) characters )') == -1 + + +def test_special_unicode_character_input(): + assert parenthetical(' (パイソン) (') == 1 + assert parenthetical(' (パイソン) ') == 0 + assert parenthetical(') (パイソン) ') == -1 + + +def test_bad_input(): + with pytest.raises(TypeError): + parenthetical(123)