From 9490979fe55801ec30a1d1578518f9a56b1e1324 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Fri, 26 Jun 2015 05:08:48 -0400 Subject: [PATCH] Reworked notebook: Added more detail to constraints and test cases. Reworked unit test. --- linked-lists/remove-duplicates.ipynb | 150 +++++++++++++++------------ 1 file changed, 85 insertions(+), 65 deletions(-) diff --git a/linked-lists/remove-duplicates.ipynb b/linked-lists/remove-duplicates.ipynb index 584b08b..76ad22c 100644 --- a/linked-lists/remove-duplicates.ipynb +++ b/linked-lists/remove-duplicates.ipynb @@ -13,26 +13,31 @@ "source": [ "## Problem: Remove duplicates from a linked list\n", "\n", - "* [Clarifying Questions](#Clarifying-Questions)\n", + "* [Constraints and Assumptions](#Constraints-and-Assumptions)\n", "* [Test Cases](#Test-Cases)\n", "* [Algorithm: Hash Map Lookup](#Algorithm:-Hash-Map-Lookup)\n", "* [Code: Hash Map Lookup](#Code:-Hash-Map-Lookup)\n", "* [Algorithm: In-Place](#Algorithm:-In-Place)\n", - "* [Code: In-Place](#Code:-In-Place)" + "* [Code: In-Place](#Code:-In-Place)\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", "* Can you insert NULL values in the list?\n", " * No\n", "* Can you use additional data structures?\n", - " * Implement both solutions" + " * Implement both solutions\n", + "* Can we assume we already have a linked list class that can be used for this problem?\n", + " * Yes" ] }, { @@ -77,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "collapsed": true }, @@ -88,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "collapsed": false }, @@ -108,36 +113,6 @@ " curr = curr.next" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Empty linked list\n", - "linked_list = MyLinkedList(None)\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()\n", - "# One element linked list\n", - "head = Node(2)\n", - "linked_list = MyLinkedList(head)\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()\n", - "# Multiple elements\n", - "# One or more duplicates\n", - "linked_list.insert_to_front(1)\n", - "linked_list.insert_to_front(3)\n", - "linked_list.insert_to_front(1)\n", - "linked_list.insert_to_front(1)\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()\n", - "# No duplicates\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -169,14 +144,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "class MyLinkedList(LinkedList):\n", - " \n", + "class MyLinkedListAlt(LinkedList):\n", " def remove_dupes(self):\n", " curr = self.head\n", " while curr is not None:\n", @@ -190,33 +164,79 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "cell_type": "markdown", + "metadata": {}, "source": [ - "# Empty linked list\n", - "linked_list = MyLinkedList(None)\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()\n", - "# One element linked list\n", - "head = Node(2)\n", - "linked_list = MyLinkedList(head)\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()\n", - "# Multiple elements\n", - "# One or more duplicates\n", - "linked_list.insert_to_front(1)\n", - "linked_list.insert_to_front(3)\n", - "linked_list.insert_to_front(1)\n", - "linked_list.insert_to_front(1)\n", - "linked_list.remove_dupes()\n", - "linked_list.print_list()\n", - "# No duplicates\n", - "linked_list.remove_dupes()\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": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test: Empty list\n", + "Test: One element list\n", + "Test: General case, duplicates\n", + "Test: General case, no duplicates\n", + "Success: test_remove_dupes\n", + "\n", + "Test: Empty list\n", + "Test: One element list\n", + "Test: General case, duplicates\n", + "Test: General case, no duplicates\n", + "Success: test_remove_dupes\n", + "\n" + ] + } + ], + "source": [ + "from nose.tools import assert_equal\n", + "\n", + "class Test(object):\n", + " def test_remove_dupes(self, linked_list):\n", + " print('Test: Empty list')\n", + " linked_list.remove_dupes()\n", + " assert_equal(linked_list.get_all_data(), [])\n", + "\n", + " print('Test: One element list')\n", + " linked_list.insert_to_front(2)\n", + " linked_list.remove_dupes()\n", + " assert_equal(linked_list.get_all_data(), [2])\n", + "\n", + " print('Test: General case, duplicates')\n", + " linked_list.insert_to_front(1)\n", + " linked_list.insert_to_front(3)\n", + " linked_list.insert_to_front(1)\n", + " linked_list.insert_to_front(1)\n", + " linked_list.remove_dupes()\n", + " assert_equal(linked_list.get_all_data(), [1, 3, 2])\n", + "\n", + " print('Test: General case, no duplicates')\n", + " linked_list.remove_dupes()\n", + " assert_equal(linked_list.get_all_data(), [1, 3, 2])\n", + " \n", + " print('Success: test_remove_dupes\\n')\n", + "\n", + "if __name__ == '__main__':\n", + " test = Test()\n", + " linked_list = MyLinkedList(None)\n", + " test.test_remove_dupes(linked_list)\n", + " linked_list_alt = MyLinkedListAlt(None)\n", + " test.test_remove_dupes(linked_list_alt)" ] } ],