diff --git a/linked-lists/linked-list.ipynb b/linked-lists/linked-list.ipynb index bd508ef..f640629 100644 --- a/linked-lists/linked-list.ipynb +++ b/linked-lists/linked-list.ipynb @@ -13,17 +13,20 @@ "source": [ "## Problem: Implement a linked list with insert, append, find, delete, length, and print methods\n", "\n", - "* [Clarifying Questions](#Clarifying-Questions)\n", + "* [Constraints and Assumptions](#Constraints-and-Assumptions)\n", "* [Test Cases](#Test-Cases)\n", "* [Algorithm](#Algorithm)\n", - "* [Code](#Code)" + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Clarifying Questions\n", + "## Constraints and Assumptions\n", + "\n", + "*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n", "\n", "* Is this a singly or doubly linked list?\n", " * Singly\n", @@ -163,11 +166,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting linked_list.py\n" + ] + } + ], "source": [ "%%writefile linked_list.py\n", "\n", @@ -200,6 +211,7 @@ " else:\n", " node.next = self.head\n", " self.head = node\n", + " return node\n", " \n", " def append(self, data, next_node=None):\n", " if data is None:\n", @@ -212,6 +224,7 @@ " while curr_node.next is not None:\n", " curr_node = curr_node.next\n", " curr_node.next = node\n", + " return node\n", " \n", " def find(self, data):\n", " if data is None:\n", @@ -224,6 +237,7 @@ " return curr_node\n", " else:\n", " curr_node = curr_node.next\n", + " return\n", " \n", " def delete(self, data):\n", " if data is None:\n", @@ -244,14 +258,22 @@ " curr_node = self.head\n", " while curr_node is not None:\n", " print(curr_node.data)\n", - " curr_node = curr_node.next" + " curr_node = curr_node.next\n", + "\n", + " def get_all_data(self):\n", + " data = []\n", + " curr_node = self.head\n", + " while curr_node is not None:\n", + " data.append(curr_node.data)\n", + " curr_node = curr_node.next\n", + " return data" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ @@ -259,139 +281,170 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], + "cell_type": "markdown", + "metadata": {}, "source": [ - "# Test insert_to_front\n", - "# Insert in an empty list\n", - "linked_list = LinkedList(None)\n", - "linked_list.insert_to_front(10)\n", - "linked_list.print_list()\n", - "# Insert a NULL\n", - "linked_list.insert_to_front(None)\n", - "linked_list.print_list()\n", - "# Insert in a list with one element or more elements\n", - "linked_list.insert_to_front('a')\n", - "linked_list.insert_to_front('bc')\n", - "linked_list.print_list()" + "## Unit Test" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test: insert_to_front on an empty list\n", + "Test: insert_to_front on a NULL\n", + "Test: insert_to_front general case\n", + "Success: test_insert_to_front\n", + "\n", + "Test: append on an empty list\n", + "Test: append a NULL\n", + "Test: append general case\n", + "Success: test_append\n", + "\n", + "Test: find on an empty list\n", + "Test: find a NULL\n", + "Test: find general case with matches\n", + "Test: find general case with no matches\n", + "Success: test_find\n", + "\n", + "Test: delete on an empty list\n", + "Test: delete a NULL\n", + "Test: delete general case with matches\n", + "Test: delete general case with no matches\n", + "Success: test_delete\n", + "\n", + "Test: len on an empty list\n", + "Test: len general case\n", + "Success: test_len\n", + "\n" + ] + } + ], "source": [ - "# Test append\n", - "# Insert in an empty list\n", - "linked_list = LinkedList(None)\n", - "linked_list.append(10)\n", - "linked_list.print_list()\n", - "# Insert a NULL\n", - "linked_list.append(None)\n", - "linked_list.print_list()\n", - "# Insert in a list with one element or more elements\n", - "linked_list.append('a')\n", - "linked_list.append('bc')\n", - "linked_list.print_list()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Test find\n", - "# Find in an empty list\n", - "linked_list = LinkedList(None)\n", - "node = linked_list.find('a')\n", - "print(node)\n", - "# Find a NULL\n", - "head = Node(10)\n", - "linked_list = LinkedList(head)\n", - "node = linked_list.find(None)\n", - "print(node)\n", - "# Find in a list with one element or more matching elements\n", - "head = Node(10)\n", - "linked_list = LinkedList(head)\n", - "linked_list.insert_to_front('a')\n", - "linked_list.insert_to_front('bc')\n", - "node = linked_list.find('a')\n", - "print(node)\n", - "# Find in a list with no matches\n", - "node = linked_list.find('aaa')\n", - "print(node)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Test delete\n", - "# Delete in an empty list\n", - "linked_list = LinkedList(None)\n", - "linked_list.delete('a')\n", - "linked_list.print_list()\n", - "# Delete a NULL\n", - "head = Node(10)\n", - "linked_list = LinkedList(head)\n", - "linked_list.delete(None)\n", - "linked_list.print_list()\n", - "# Delete in a list with one element or more matching elements\n", - "head = Node(10)\n", - "linked_list = LinkedList(head)\n", - "linked_list.insert_to_front('a')\n", - "linked_list.insert_to_front('bc')\n", - "linked_list.delete('a')\n", - "linked_list.print_list()\n", - "# Delete in a list with no matches\n", - "linked_list.delete('aa')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Test length\n", - "# Zero elements\n", - "linked_list = LinkedList(None)\n", - "print(len(linked_list))\n", - "# One or more elements\n", - "head = Node(10)\n", - "linked_list = LinkedList(head)\n", - "linked_list.insert_to_front('a')\n", - "linked_list.insert_to_front('bc')\n", - "print(len(linked_list))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Test empty print\n", - "linked_list = LinkedList(None)\n", - "linked_list.print_list()" + "from nose.tools import assert_equal\n", + "\n", + "class Test(object):\n", + " def test_insert_to_front(self):\n", + " print('Test: insert_to_front on an empty list')\n", + " linked_list = LinkedList(None)\n", + " linked_list.insert_to_front(10)\n", + " assert_equal(linked_list.get_all_data(), [10])\n", + "\n", + " print('Test: insert_to_front on a NULL')\n", + " linked_list.insert_to_front(None)\n", + " assert_equal(linked_list.get_all_data(), [10])\n", + "\n", + " print('Test: insert_to_front general case')\n", + " linked_list.insert_to_front('a')\n", + " linked_list.insert_to_front('bc')\n", + " assert_equal(linked_list.get_all_data(), ['bc', 'a', 10])\n", + " \n", + " print('Success: test_insert_to_front\\n')\n", + " \n", + " def test_append(self):\n", + " print('Test: append on an empty list')\n", + " linked_list = LinkedList(None)\n", + " linked_list.append(10)\n", + " assert_equal(linked_list.get_all_data(), [10])\n", + "\n", + " print('Test: append a NULL')\n", + " linked_list.append(None)\n", + " assert_equal(linked_list.get_all_data(), [10])\n", + "\n", + " print('Test: append general case')\n", + " linked_list.append('a')\n", + " linked_list.append('bc')\n", + " assert_equal(linked_list.get_all_data(), [10, 'a', 'bc'])\n", + " \n", + " print('Success: test_append\\n')\n", + " \n", + " def test_find(self):\n", + " print('Test: find on an empty list')\n", + " linked_list = LinkedList(None)\n", + " node = linked_list.find('a')\n", + " assert_equal(node, None)\n", + "\n", + " print('Test: find a NULL')\n", + " head = Node(10)\n", + " linked_list = LinkedList(head)\n", + " node = linked_list.find(None)\n", + " assert_equal(node, None)\n", + "\n", + " print('Test: find general case with matches')\n", + " head = Node(10)\n", + " linked_list = LinkedList(head)\n", + " linked_list.insert_to_front('a')\n", + " linked_list.insert_to_front('bc')\n", + " node = linked_list.find('a')\n", + " assert_equal(str(node), 'a')\n", + "\n", + " print('Test: find general case with no matches')\n", + " node = linked_list.find('aaa')\n", + " assert_equal(node, None)\n", + " \n", + " print('Success: test_find\\n')\n", + " \n", + " def test_delete(self):\n", + " print('Test: delete on an empty list')\n", + " linked_list = LinkedList(None)\n", + " linked_list.delete('a')\n", + " assert_equal(linked_list.get_all_data(), [])\n", + "\n", + " print('Test: delete a NULL')\n", + " head = Node(10)\n", + " linked_list = LinkedList(head)\n", + " linked_list.delete(None)\n", + " assert_equal(linked_list.get_all_data(), [10])\n", + "\n", + " print('Test: delete general case with matches')\n", + " head = Node(10)\n", + " linked_list = LinkedList(head)\n", + " linked_list.insert_to_front('a')\n", + " linked_list.insert_to_front('bc')\n", + " linked_list.delete('a')\n", + " assert_equal(linked_list.get_all_data(), ['bc', 10])\n", + "\n", + " print('Test: delete general case with no matches')\n", + " linked_list.delete('aa')\n", + " assert_equal(linked_list.get_all_data(), ['bc', 10])\n", + " \n", + " print('Success: test_delete\\n')\n", + " \n", + " def test_len(self):\n", + " print('Test: len on an empty list')\n", + " linked_list = LinkedList(None)\n", + " assert_equal(len(linked_list), 0)\n", + "\n", + " print('Test: len general case')\n", + " head = Node(10)\n", + " linked_list = LinkedList(head)\n", + " linked_list.insert_to_front('a')\n", + " linked_list.insert_to_front('bc')\n", + " assert_equal(len(linked_list), 3)\n", + " \n", + " print('Success: test_len\\n')\n", + "\n", + "if __name__ == '__main__':\n", + " test = Test()\n", + " test.test_insert_to_front()\n", + " test.test_append()\n", + " test.test_find()\n", + " test.test_delete()\n", + " test.test_len()" ] } ], diff --git a/linked-lists/linked_list.py b/linked-lists/linked_list.py index e27e97b..f6406a8 100644 --- a/linked-lists/linked_list.py +++ b/linked-lists/linked_list.py @@ -28,6 +28,7 @@ class LinkedList(object): else: node.next = self.head self.head = node + return node def append(self, data, next_node=None): if data is None: @@ -40,6 +41,7 @@ class LinkedList(object): while curr_node.next is not None: curr_node = curr_node.next curr_node.next = node + return node def find(self, data): if data is None: @@ -52,6 +54,7 @@ class LinkedList(object): return curr_node else: curr_node = curr_node.next + return def delete(self, data): if data is None: @@ -72,4 +75,12 @@ class LinkedList(object): curr_node = self.head while curr_node is not None: print(curr_node.data) - curr_node = curr_node.next \ No newline at end of file + curr_node = curr_node.next + + def get_all_data(self): + data = [] + curr_node = self.head + while curr_node is not None: + data.append(curr_node.data) + curr_node = curr_node.next + return data \ No newline at end of file