From 6f90d597eb465a1466684ae71a050a8fdf647a16 Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Fri, 26 Jun 2015 05:07:19 -0400 Subject: [PATCH] Reworked notebook: Added more detail to constraints and test cases. Reworked unit test. --- linked-lists/palindrome.ipynb | 125 ++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 36 deletions(-) diff --git a/linked-lists/palindrome.ipynb b/linked-lists/palindrome.ipynb index 3f67c4c..00060c3 100644 --- a/linked-lists/palindrome.ipynb +++ b/linked-lists/palindrome.ipynb @@ -13,21 +13,25 @@ "source": [ "## Problem: Determine if a linked list is a palindrome.\n", "\n", - "* [Clarifying Questions](#Clarifying-Questions)\n", + "* [Constraints and Assumptions](#Constraints-and-Assumptions)\n", "* [Test Cases](#Test-Cases)\n", "* [Algorithm](#Algorithm)\n", "* [Code](#Code)\n", - "* [Pythonic-Code](#Pythonic-Code)" + "* [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 a single character or number a palindrome?\n", - " * No" + " * No\n", + "* Can we assume we already have a linked list class that can be used for this problem?\n", + " * Yes" ] }, { @@ -36,6 +40,7 @@ "source": [ "## Test Cases\n", "\n", + "\n", "* Empty list\n", "* Single element list\n", "* Two element list, not a palindrome\n", @@ -71,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "collapsed": true }, @@ -82,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "collapsed": false }, @@ -95,10 +100,15 @@ " curr = self.head\n", " reversed_list = MyLinkedList()\n", " length = 0\n", + " \n", + " # Reverse the linked list\n", " while curr is not None:\n", " reversed_list.insert_to_front(curr.data)\n", " length += 1\n", " curr = curr.next\n", + " \n", + " # Compare the reversed list with the original list\n", + " # Only need to compare the first half \n", " iterations_to_compare_half = length / 2\n", " curr = self.head\n", " curr_reversed = reversed_list.head\n", @@ -110,42 +120,85 @@ " return True" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 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: Empty list\n", + "Test: Single element list\n", + "Test: Two element list, not a palindrome\n", + "Test: Three element list, not a palindrome\n", + "Test: General case: Palindrome with even length\n", + "Test: General case: Palindrome with odd length\n", + "Success: test_is_palindrome\n" + ] + } + ], "source": [ - "print('Empty list')\n", - "linked_list = MyLinkedList()\n", - "print(linked_list.is_palindrome())\n", - "print('Single element list')\n", - "head = Node(1)\n", - "linked_list = MyLinkedList(head)\n", - "print(linked_list.is_palindrome())\n", - "print('Two element list, not a palindrome')\n", - "linked_list.append(2)\n", - "print(linked_list.is_palindrome())\n", - "print('Three element list, not a palindrome')\n", - "linked_list.append(3)\n", - "print(linked_list.is_palindrome())\n", - "print('General case: Palindrome with even length')\n", - "head = Node('a')\n", - "linked_list = MyLinkedList(head)\n", - "linked_list.append('b')\n", - "linked_list.append('b')\n", - "linked_list.append('a')\n", - "print(linked_list.is_palindrome())\n", - "print('General case: Palindrome with odd length')\n", - "head = Node(1)\n", - "linked_list = MyLinkedList(head)\n", - "linked_list.append(2)\n", - "linked_list.append(3)\n", - "linked_list.append(2)\n", - "linked_list.append(1)\n", - "print(linked_list.is_palindrome())" + "from nose.tools import assert_equal\n", + "\n", + "class Test(object):\n", + " def test_is_palindrome(self):\n", + " print('Test: Empty list')\n", + " linked_list = MyLinkedList()\n", + " assert_equal(linked_list.is_palindrome(), False)\n", + "\n", + " print('Test: Single element list')\n", + " head = Node(1)\n", + " linked_list = MyLinkedList(head)\n", + " assert_equal(linked_list.is_palindrome(), False)\n", + "\n", + " print('Test: Two element list, not a palindrome')\n", + " linked_list.append(2)\n", + " assert_equal(linked_list.is_palindrome(), False)\n", + "\n", + " print('Test: Three element list, not a palindrome')\n", + " linked_list.append(3)\n", + " assert_equal(linked_list.is_palindrome(), False)\n", + "\n", + " print('Test: General case: Palindrome with even length')\n", + " head = Node('a')\n", + " linked_list = MyLinkedList(head)\n", + " linked_list.append('b')\n", + " linked_list.append('b')\n", + " linked_list.append('a')\n", + " assert_equal(linked_list.is_palindrome(), True)\n", + "\n", + " print('Test: General case: Palindrome with odd length')\n", + " head = Node(1)\n", + " linked_list = MyLinkedList(head)\n", + " linked_list.append(2)\n", + " linked_list.append(3)\n", + " linked_list.append(2)\n", + " linked_list.append(1)\n", + " assert_equal(linked_list.is_palindrome(), True)\n", + " \n", + " print('Success: test_is_palindrome')\n", + "\n", + "if __name__ == '__main__':\n", + " test = Test()\n", + " test.test_is_palindrome()" ] } ],