From 6cea5d003ab527cd9a3837706476d218684757bd Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Wed, 24 Jun 2015 18:23:27 -0400 Subject: [PATCH] Reworked notebook: Added more detail to clarifying questions and test cases. Reworked algorithm discussion, code, and unit test. --- arrays-strings/replace_char.ipynb | 102 ++++++++++++++++++------------ 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/arrays-strings/replace_char.ipynb b/arrays-strings/replace_char.ipynb index 4bfb436..2ed6818 100644 --- a/arrays-strings/replace_char.ipynb +++ b/arrays-strings/replace_char.ipynb @@ -17,7 +17,8 @@ "* [Test Cases](#Test-Cases)\n", "* [Algorithm](#Algorithm)\n", "* [Code](#Code)\n", - "* [Pythonic-Code: Not In-Place](#Pythonic-Code:-Not-In-Place)" + "* [Pythonic-Code: Not In-Place](#Pythonic-Code:-Not-In-Place)\n", + "* [Unit Test](#Unit-Test)" ] }, { @@ -26,8 +27,11 @@ "source": [ "## Clarifying Questions\n", "\n", - "* Is the string ASCII (extended)? Or Unicode?\n", - " * ASCII extended, which is 256 characters\n", + "*Problem statements are sometimes intentionally ambiguous. Asking clarifying questions, identifying constraints, and stating assumptions help to ensure you code the intended solution.*\n", + "\n", + "* Can I assume the string is ASCII?\n", + " * Yes\n", + " * Note: Unicode strings could require special handling depending on your language\n", "* Is there enough space in the data structure for this operation?\n", " * Yes" ] @@ -38,49 +42,21 @@ "source": [ "## Test Cases\n", "\n", + "*Identifying and running through general and edge cases are important. You generally will not be asked to write a unit test like what is shown below.*\n", + "\n", "* NULL->NULL\n", "* ' ' -> '%20'\n", "* ' foo bar ' -> '%20foo%20bar%20'\n", "* 'foo' -> 'foo'" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "from nose.tools import assert_equal\n", - "\n", - "class Test(object):\n", - " def test_replace_char(self, func):\n", - " str0 = None\n", - " str1 = bytearray(' ||')\n", - " str2 = bytearray(' foo bar ||||||')\n", - " str3 = bytearray('foo')\n", - " func(str0, 0)\n", - " func(str1, 1)\n", - " func(str2, 9)\n", - " func(str3, 3)\n", - " assert_equal(str0, None)\n", - " assert_equal(str1, '%20')\n", - " assert_equal(str2, '%20foo%20bar%20')\n", - " assert_equal(str3, 'foo')\n", - "\n", - "def run_tests(func):\n", - " test = Test()\n", - " test.test_replace_char(func)" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Algorithm\n", "\n", - "Since Python strings are immutable, we'll use a bytearray instead to exercise in-place string manipulation as you would get with a C string (which is null terminated, as seen in the diagram below). For the python bytearray we will not use a null terminator.\n", + "Since Python strings are immutable, we'll use a bytearray instead to exercise in-place string manipulation as you would get with a C string (which is null terminated, as seen in the diagram below). Python does not use a null-terminator.\n", "\n", "![alt text](https://raw.githubusercontent.com/donnemartin/algorithms-data-structures/master/images/replace_string.jpg)\n", "\n", @@ -110,7 +86,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "collapsed": false }, @@ -124,14 +100,12 @@ " for i in xrange(length-1, -1, -1):\n", " if chr(string[i]) == ' ':\n", " string[new_length] = '0'\n", - " string[new_length - 1] = '2'\n", - " string[new_length - 2] = '%'\n", + " string[new_length-1] = '2'\n", + " string[new_length-2] = '%'\n", " new_length -= 3\n", " else:\n", " string[new_length] = string[i]\n", - " new_length -= 1\n", - "\n", - "run_tests(encode_spaces)" + " new_length -= 1" ] }, { @@ -145,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "collapsed": false }, @@ -159,6 +133,52 @@ "def encode_spaces_alt2(string):\n", " return string.replace(' ', '%20')" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success: test_replace_char\n" + ] + } + ], + "source": [ + "from nose.tools import assert_equal\n", + "\n", + "class Test(object):\n", + " def test_replace_char(self, func):\n", + " str0 = None\n", + " str1 = bytearray(' ||')\n", + " str2 = bytearray(' foo bar ||||||')\n", + " str3 = bytearray('foo')\n", + " func(str0, 0)\n", + " func(str1, 1)\n", + " func(str2, 9)\n", + " func(str3, 3)\n", + " assert_equal(str0, None)\n", + " assert_equal(str1, '%20')\n", + " assert_equal(str2, '%20foo%20bar%20')\n", + " assert_equal(str3, 'foo')\n", + " print('Success: test_replace_char')\n", + "\n", + "if __name__ == '__main__':\n", + " test = Test()\n", + " test.test_replace_char(encode_spaces)" + ] } ], "metadata": {