Skip to content
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
33 changes: 17 additions & 16 deletions linked_list.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
from __future__ import unicode_literals


class Node(object):
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 + ")"
23 changes: 23 additions & 0 deletions parenthetics.py
Original file line number Diff line number Diff line change
@@ -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
29 changes: 0 additions & 29 deletions stack.py

This file was deleted.

69 changes: 24 additions & 45 deletions test_linked_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
34 changes: 34 additions & 0 deletions test_parenthetics.py
Original file line number Diff line number Diff line change
@@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see a couple more test cases that could possibly break your code. You don't test an empty string, and you don't test anything more complex like (()()))(). It might seem silly to test these because you know that your code will breeze through them, but your tests shouldn't assume anything about your code. When you're working with code, it could change completely over time and if you don't have exhaustive test cases, it could break without you realizing.

52 changes: 0 additions & 52 deletions test_stack.py

This file was deleted.