From facb0d91969f0e6c65978d05db31768df6d13e7c Mon Sep 17 00:00:00 2001 From: Ali Date: Sun, 25 Jul 2021 19:47:24 -0400 Subject: [PATCH 01/31] updated python material --- python/01. Basics/05 Variables.ipynb | 2 +- ...mposite Data Types: Lists and Tuples.ipynb | 2 +- .../09 Composite Data Types: Dictionary.ipynb | 48 +- .../10 Composite Data Types: Sets.ipynb | 12 +- .../11 Python Program Lexical Structure.ipynb | 72 +- .../12 Conditional Statements in Python.ipynb | 86 +- ...hile\" Loops (Indefinite Iteration).ipynb" | 13039 +++++++++++++++- ... \"for\" Loops (Definite Iteration).ipynb" | 2 +- python/01. Basics/List Comprehension.ipynb | 902 ++ python/01. Basics/tmp/14 IO Operations.ipynb | 4 +- .../03 Inheritance.ipynb | 2 +- .../04 Composition.ipynb | 20 +- .../05 Overriding.ipynb | 30 +- .../06 Data Types Methods.ipynb | 175 +- .../07. Reading and Writing Files.ipynb | 1297 ++ .../images/fileformat.webp | Bin 0 -> 3022 bytes .../images/python.png | Bin 0 -> 37296 bytes .../myfile.txt | 7 + .../myfile_reversed.txt | 6 + python/04. Advanced/09. Error Handling.ipynb | 2 +- python/05. Modules/19. openpyxl.ipynb | 4 +- .../01. Data Types + Functions + IO.ipynb | 2 +- ...es + Functions + IO (with Solutions).ipynb | 2 +- .../03. OOP (With Solutions).ipynb | 2 +- .../04. OOP + Modularization.ipynb | 4 +- python/XX. Practice Sessions/05. Review.ipynb | 4 +- python/XX. Practice Sessions/Untitled.ipynb | 102 + python/XX. Practice Sessions/file.txt | 142 + 28 files changed, 15784 insertions(+), 186 deletions(-) create mode 100644 python/01. Basics/List Comprehension.ipynb create mode 100644 python/02. Object Oriented Programming/07. Reading and Writing Files.ipynb create mode 100644 python/02. Object Oriented Programming/images/fileformat.webp create mode 100644 python/02. Object Oriented Programming/images/python.png create mode 100644 python/02. Object Oriented Programming/myfile.txt create mode 100644 python/02. Object Oriented Programming/myfile_reversed.txt create mode 100644 python/XX. Practice Sessions/Untitled.ipynb create mode 100644 python/XX. Practice Sessions/file.txt diff --git a/python/01. Basics/05 Variables.ipynb b/python/01. Basics/05 Variables.ipynb index 6a6dbc1..c3e999b 100755 --- a/python/01. Basics/05 Variables.ipynb +++ b/python/01. Basics/05 Variables.ipynb @@ -1100,7 +1100,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb b/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb index 2bd8ae5..9a0251f 100755 --- a/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb +++ b/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb @@ -4166,7 +4166,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/01. Basics/09 Composite Data Types: Dictionary.ipynb b/python/01. Basics/09 Composite Data Types: Dictionary.ipynb index 26116da..66d64a9 100755 --- a/python/01. Basics/09 Composite Data Types: Dictionary.ipynb +++ b/python/01. Basics/09 Composite Data Types: Dictionary.ipynb @@ -207,18 +207,18 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 18, "metadata": {}, "outputs": [ { - "ename": "KeyError", - "evalue": "1", + "ename": "NameError", + "evalue": "name 'MLB_team' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: 1" + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/1469821463.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined" ] } ], @@ -385,21 +385,19 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 26, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers'}" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" + "ename": "NameError", + "evalue": "name 'MLB_team' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3737734966.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mdel\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Seattle'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined" + ] } ], "source": [ @@ -650,7 +648,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -660,7 +658,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3015485889.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'd' is not defined" ] } @@ -696,7 +694,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 118, "metadata": {}, "outputs": [ { @@ -705,7 +703,7 @@ "dict" ] }, - "execution_count": 26, + "execution_count": 118, "metadata": {}, "output_type": "execute_result" } @@ -1064,7 +1062,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 139, "metadata": {}, "outputs": [ { @@ -1073,7 +1071,7 @@ "3" ] }, - "execution_count": 41, + "execution_count": 139, "metadata": {}, "output_type": "execute_result" } @@ -1394,7 +1392,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/01. Basics/10 Composite Data Types: Sets.ipynb b/python/01. Basics/10 Composite Data Types: Sets.ipynb index b5698b1..95d2b14 100755 --- a/python/01. Basics/10 Composite Data Types: Sets.ipynb +++ b/python/01. Basics/10 Composite Data Types: Sets.ipynb @@ -550,7 +550,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 107, "metadata": {}, "outputs": [], "source": [ @@ -559,7 +559,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 108, "metadata": {}, "outputs": [ { @@ -568,7 +568,7 @@ "3" ] }, - "execution_count": 25, + "execution_count": 108, "metadata": {}, "output_type": "execute_result" } @@ -599,7 +599,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 243, "metadata": {}, "outputs": [ { @@ -608,7 +608,7 @@ "False" ] }, - "execution_count": 28, + "execution_count": 243, "metadata": {}, "output_type": "execute_result" } @@ -643,7 +643,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/01. Basics/11 Python Program Lexical Structure.ipynb b/python/01. Basics/11 Python Program Lexical Structure.ipynb index 1d7fe0c..66b89c9 100755 --- a/python/01. Basics/11 Python Program Lexical Structure.ipynb +++ b/python/01. Basics/11 Python Program Lexical Structure.ipynb @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -91,7 +91,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -100,7 +100,7 @@ "True" ] }, - "execution_count": 7, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -186,15 +186,15 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 15, "metadata": {}, "outputs": [ { "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", + "evalue": "invalid syntax (1911760183.py, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + "\u001b[0;36m File \u001b[0;32m\"/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_50053/1911760183.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -234,7 +234,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -249,7 +249,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -262,7 +262,7 @@ " [21, 22, 23, 24, 25]]" ] }, - "execution_count": 12, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -369,7 +369,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -425,6 +425,13 @@ "- Tuple definition" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": 17, @@ -612,7 +619,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -631,7 +638,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -640,7 +647,7 @@ "[[['foo', 'bar'], [1, 2, 3]], {1, 3, 5}, {'a': 1, 'b': 2}]" ] }, - "execution_count": 27, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -752,7 +759,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -763,7 +770,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -772,7 +779,7 @@ "21" ] }, - "execution_count": 35, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -860,7 +867,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 57, "metadata": {}, "outputs": [], "source": [ @@ -869,7 +876,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 58, "metadata": {}, "outputs": [ { @@ -964,7 +971,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 59, "metadata": {}, "outputs": [ { @@ -973,7 +980,7 @@ "'foobar # I am *not* a comment.'" ] }, - "execution_count": 54, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1212,7 +1219,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 67, "metadata": {}, "outputs": [ { @@ -1261,7 +1268,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Although this works (and was once put forth as a Python programming tip by Guido himself), PEP 8 actually recommends against it. The reason for this appears to be because of a special Python construct called the **docstring***. A docstring is a special comment at the beginning of a user-defined function that documents the function’s behavior. Docstrings are typically specified as triple-quoted string comments, so PEP 8 recommends that other [block comments](https://www.python.org/dev/peps/pep-0008/?#block-comments) in Python code be designated the usual way, with a hash character at the start of each line." + "Although this works (and was once put forth as a Python programming tip by Guido himself), PEP 8 actually recommends against it. The reason for this appears to be because of a special Python construct called the **docstring**. A docstring is a special comment at the beginning of a user-defined function that documents the function’s behavior. Docstrings are typically specified as triple-quoted string comments, so PEP 8 recommends that other [block comments](https://www.python.org/dev/peps/pep-0008/?#block-comments) in Python code be designated the usual way, with a hash character at the start of each line." ] }, { @@ -1307,6 +1314,16 @@ "There are other somewhat outdated ASCII whitespace characters such as line feed and form feed, as well as some very esoteric Unicode characters that provide whitespace. But for present purposes, whitespace usually means a space, tab, or newline." ] }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "x = 3\n", + "x=2" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1475,6 +1492,15 @@ "Most people would likely find that the added whitespace in the second example makes it easier to read. On the other hand, you could probably find a few who would prefer the first example. To some extent, it is a matter of personal preference. But there are standards for [whitespace in expressions and statements](https://www.python.org/dev/peps/pep-0008/?#whitespace-in-expressions-and-statements) put forth in PEP 8, and you should strongly consider adhering to them as much as possible." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = (1,)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1810,7 +1836,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/01. Basics/12 Conditional Statements in Python.ipynb b/python/01. Basics/12 Conditional Statements in Python.ipynb index 47ada3f..cd8ae37 100755 --- a/python/01. Basics/12 Conditional Statements in Python.ipynb +++ b/python/01. Basics/12 Conditional Statements in Python.ipynb @@ -237,7 +237,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -290,6 +290,13 @@ "Virtually all programming languages provide the capability to define blocks, but they don’t all provide it in the same way. Let’s see how Python does it." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -403,7 +410,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -732,7 +739,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -742,7 +749,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvar\u001b[0m \u001b[0;31m# Not defined\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_10923/504837137.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvar\u001b[0m \u001b[0;31m# Not defined\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'var' is not defined" ] } @@ -883,7 +890,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -939,7 +946,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -983,6 +990,26 @@ "```" ] }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], + "source": [ + "if x < 5:\n", + " print('True')\n", + "else:\n", + " print('False')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1024,7 +1051,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 78, "metadata": {}, "outputs": [ { @@ -1042,7 +1069,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 79, "metadata": {}, "outputs": [ { @@ -1263,14 +1290,7 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 35, + "execution_count": 80, "metadata": {}, "outputs": [ { @@ -1279,7 +1299,7 @@ "'foo'" ] }, - "execution_count": 35, + "execution_count": 80, "metadata": {}, "output_type": "execute_result" } @@ -1290,7 +1310,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 81, "metadata": {}, "outputs": [ { @@ -1299,7 +1319,7 @@ "'bar'" ] }, - "execution_count": 36, + "execution_count": 81, "metadata": {}, "output_type": "execute_result" } @@ -1377,6 +1397,32 @@ "Occasionally, you may find that you want to write what is called a code stub: a placeholder for where you will eventually put a block of code that you haven’t implemented yet." ] }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n" + ] + } + ], + "source": [ + "name = 'Ali'\n", + "\n", + "if name == 'Ali':\n", + " # TODO: add name to database\n", + " pass\n", + "else:\n", + " # TODO: warn user about registeration\n", + " pass\n", + "\n", + "print('here')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1487,7 +1533,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git "a/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" "b/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" index 8c1a068..73dfd95 100755 --- "a/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" +++ "b/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" @@ -106,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -202,6 +202,13025 @@ "When a list is evaluated in Boolean context, it is truthy if it has elements in it and falsy if it is empty. In this example, a is true as long as it has elements in it. Once all the items have been removed with the `.pop()` method and the list is empty, `a` is false, and the loop terminates." ] }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n" + ] + } + ], + "source": [ + "x = 5\n", + "if x < 5:\n", + " print('here')" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n", + "here\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_65870/2171307792.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'here'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/ipykernel/iostream.py\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, string)\u001b[0m\n\u001b[1;32m 517\u001b[0m \u001b[0mis_child\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_is_master_process\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 518\u001b[0m \u001b[0;31m# only touch the buffer in the IO thread to avoid races\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 519\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpub_thread\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mschedule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_buffer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 520\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_child\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 521\u001b[0m \u001b[0;31m# mp.Pool cannot be trusted to flush promptly (or ever),\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/ipykernel/iostream.py\u001b[0m in \u001b[0;36mschedule\u001b[0;34m(self, f)\u001b[0m\n\u001b[1;32m 212\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_events\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 213\u001b[0m \u001b[0;31m# wake event thread (message content is ignored)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 214\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_event_pipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mb''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 215\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 216\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/zmq/sugar/socket.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, data, flags, copy, track, routing_id, group)\u001b[0m\n\u001b[1;32m 503\u001b[0m )\n\u001b[1;32m 504\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroup\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 505\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSocket\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mflags\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrack\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtrack\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 506\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 507\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0msend_multipart\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmsg_parts\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrack\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket.Socket.send\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket.Socket.send\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket._send_copy\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/zmq/backend/cython/checkrc.pxd\u001b[0m in \u001b[0;36mzmq.backend.cython.checkrc._check_rc\u001b[0;34m()\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "x = 5\n", + "while x < 5:\n", + " print('here')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -209,6 +13228,22 @@ "## The Python `break` and `continue` Statements" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 5\n", + "\n", + "if x == 5:\n", + " print('x is 5')\n", + "elif x > 6:\n", + " print('x is greater than 6')\n", + "else:\n", + " print('else')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -914,7 +13949,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git "a/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" "b/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" index 2f0d0b5..8e3bf96 100755 --- "a/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" +++ "b/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" @@ -1649,7 +1649,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/01. Basics/List Comprehension.ipynb b/python/01. Basics/List Comprehension.ipynb new file mode 100644 index 0000000..b52c006 --- /dev/null +++ b/python/01. Basics/List Comprehension.ipynb @@ -0,0 +1,902 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3152c34f", + "metadata": {}, + "source": [ + "# When to Use a List Comprehension in Python" + ] + }, + { + "cell_type": "markdown", + "id": "d5c912c3", + "metadata": {}, + "source": [ + "Python is famous for allowing you to write code that’s elegant, easy to write, and almost as easy to read as plain English. One of the language’s most distinctive features is the list comprehension, which you can use to create powerful functionality within a single line of code. However, many developers struggle to fully leverage the more advanced features of a list comprehension in Python. Some programmers even use them too much, which can lead to code that’s less efficient and harder to read." + ] + }, + { + "cell_type": "markdown", + "id": "42856702", + "metadata": {}, + "source": [ + "## How to Create Lists in Python" + ] + }, + { + "cell_type": "markdown", + "id": "0bf3ef32", + "metadata": {}, + "source": [ + "There are a few different ways you can create lists in Python. To better understand the trade-offs of using a list comprehension in Python, let’s first see how to create lists with these approaches." + ] + }, + { + "cell_type": "markdown", + "id": "a35b647d", + "metadata": {}, + "source": [ + "### Using for Loops" + ] + }, + { + "cell_type": "markdown", + "id": "b0396622", + "metadata": {}, + "source": [ + "The most common type of loop is the for loop. You can use a for loop to create a list of elements in three steps:\n", + "\n", + "- Instantiate an empty list.\n", + "- Loop over an iterable or range of elements.\n", + "- Append each element to the end of the list." + ] + }, + { + "cell_type": "markdown", + "id": "cf24ed22", + "metadata": {}, + "source": [ + "If you want to create a list containing the first ten perfect squares, then you can complete these steps in three lines of code:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1af99275", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "squares = []\n", + "for i in range(10):\n", + " squares.append(i * i)\n", + "squares" + ] + }, + { + "cell_type": "markdown", + "id": "5d8f3589", + "metadata": {}, + "source": [ + "Here, you instantiate an empty list, squares. Then, you use a for loop to iterate over `range(10)`. Finally, you multiply each number by itself and append the result to the end of the list." + ] + }, + { + "cell_type": "markdown", + "id": "f424261b", + "metadata": {}, + "source": [ + "### Using `map()` Objects" + ] + }, + { + "cell_type": "markdown", + "id": "52cf9b0e", + "metadata": {}, + "source": [ + "`map()` provides an alternative approach that’s based in functional programming. You pass in a function and an iterable, and `map()` will create an object. This object contains the output you would get from running each iterable element through the supplied function." + ] + }, + { + "cell_type": "markdown", + "id": "cd846d98", + "metadata": {}, + "source": [ + "As an example, consider a situation in which you need to calculate the price after tax for a list of transactions:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "168e613c", + "metadata": {}, + "outputs": [], + "source": [ + "txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", + "TAX_RATE = .08" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d6a2685c", + "metadata": {}, + "outputs": [], + "source": [ + "def get_price_with_tax(txn):\n", + " return txn * (1 + TAX_RATE)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "9b16cb16", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final_prices = map(get_price_with_tax, txns)\n", + "list(final_prices)" + ] + }, + { + "cell_type": "markdown", + "id": "11913fae", + "metadata": {}, + "source": [ + "Here, you have an iterable txns and a function `get_price_with_tax()`. You pass both of these arguments to `map()`, and store the resulting object in final_prices. You can easily convert this map object into a list using `list()`." + ] + }, + { + "cell_type": "markdown", + "id": "94098bf1", + "metadata": {}, + "source": [ + "### Using List Comprehensions" + ] + }, + { + "cell_type": "markdown", + "id": "5e282d8d", + "metadata": {}, + "source": [ + "List comprehensions are a third way of making lists. With this elegant approach, you could rewrite the for loop from the first example in just a single line of code:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "eda83deb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "squares = [i * i for i in range(10)]\n", + "squares" + ] + }, + { + "cell_type": "markdown", + "id": "c0d36b13", + "metadata": {}, + "source": [ + "Rather than creating an empty list and adding each element to the end, you simply define the list and its contents at the same time by following this format:\n", + "\n", + "```python\n", + "new_list = [expression for member in iterable]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "04f33f21", + "metadata": {}, + "source": [ + "Every list comprehension in Python includes three elements:\n", + "\n", + "- **expression** is the member itself, a call to a method, or any other valid expression that returns a value. In the example above, the expression `i * i` is the square of the member value.\n", + "- **member** is the object or value in the list or iterable. In the example above, the member value is `i`.\n", + "- **iterable** is a list, set, sequence, generator, or any other object that can return its elements one at a time. In the example above, the iterable is `range(10)`." + ] + }, + { + "cell_type": "markdown", + "id": "72432652", + "metadata": {}, + "source": [ + "Because the expression requirement is so flexible, a list comprehension in Python works well in many places where you would use `map()`. You can rewrite the pricing example with its own list comprehension:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "fa6be321", + "metadata": {}, + "outputs": [], + "source": [ + "txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", + "TAX_RATE = .08" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "06156a8c", + "metadata": {}, + "outputs": [], + "source": [ + "def get_price_with_tax(txn):\n", + " return txn * (1 + TAX_RATE)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "610da982", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final_prices = [get_price_with_tax(i) for i in txns]\n", + "final_prices" + ] + }, + { + "cell_type": "markdown", + "id": "6b39f2fc", + "metadata": {}, + "source": [ + "The only distinction between this implementation and `map()` is that the list comprehension in Python returns a list, not a map object." + ] + }, + { + "cell_type": "markdown", + "id": "11dd1048", + "metadata": {}, + "source": [ + "## Benefits of Using List Comprehensions" + ] + }, + { + "cell_type": "markdown", + "id": "425f9373", + "metadata": {}, + "source": [ + "List comprehensions are often described as being more Pythonic than loops or `map()`. But rather than blindly accepting that assessment, it’s worth it to understand the benefits of using a list comprehension in Python when compared to the alternatives. Later on, you’ll learn about a few scenarios where the alternatives are a better choice." + ] + }, + { + "cell_type": "markdown", + "id": "f2de596e", + "metadata": {}, + "source": [ + "One main benefit of using a list comprehension in Python is that it’s a single tool that you can use in many different situations. In addition to standard list creation, list comprehensions can also be used for mapping and filtering. You don’t have to use a different approach for each scenario." + ] + }, + { + "cell_type": "markdown", + "id": "d7ec12f5", + "metadata": {}, + "source": [ + "This is the main reason why list comprehensions are considered **Pythonic**, as Python embraces simple, powerful tools that you can use in a wide variety of situations. As an added side benefit, whenever you use a list comprehension in Python, you won’t need to remember the proper order of arguments like you would when you call `map()`." + ] + }, + { + "cell_type": "markdown", + "id": "ba63943f", + "metadata": {}, + "source": [ + "List comprehensions are also more **declarative** than loops, which means they’re easier to read and understand. Loops require you to focus on how the list is created. You have to manually create an empty list, loop over the elements, and add each of them to the end of the list. With a list comprehension in Python, you can instead focus on what you want to go in the list and trust that Python will take care of how the list construction takes place." + ] + }, + { + "cell_type": "markdown", + "id": "51cf28dd", + "metadata": {}, + "source": [ + "## How to Supercharge Your Comprehensions" + ] + }, + { + "cell_type": "markdown", + "id": "84ab2dd0", + "metadata": {}, + "source": [ + "In order to understand the full value that list comprehensions can provide, it’s helpful to understand their range of possible functionality. You’ll also want to understand the changes that are coming to the list comprehension in Python 3.8." + ] + }, + { + "cell_type": "markdown", + "id": "c409196a", + "metadata": {}, + "source": [ + "### Using Conditional Logic" + ] + }, + { + "cell_type": "markdown", + "id": "1b355f60", + "metadata": {}, + "source": [ + "Earlier, you saw this formula for how to create list comprehensions:\n", + "\n", + "```python\n", + "new_list = [expression for member in iterable]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "f2dfaa43", + "metadata": {}, + "source": [ + "While this formula is accurate, it’s also a bit incomplete. A more complete description of the comprehension formula adds support for optional **conditionals**. The most common way to add conditional logic to a list comprehension is to add a conditional to the end of the expression:\n", + "\n", + "```python\n", + "new_list = [expression for member in iterable (if conditional)]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "42e59dd9", + "metadata": {}, + "source": [ + "Here, your conditional statement comes just before the closing bracket." + ] + }, + { + "cell_type": "markdown", + "id": "7ef6bfee", + "metadata": {}, + "source": [ + "Conditionals are important because they allow list comprehensions to filter out unwanted values, which would normally require a call to `filter()`:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "765c5292", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['e', 'o', 'e', 'a', 'e', 'a', 'o', 'a']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sentence = 'the rocket came back from mars'\n", + "vowels = [i for i in sentence if i in 'aeiou']\n", + "vowels" + ] + }, + { + "cell_type": "markdown", + "id": "1cf721a4", + "metadata": {}, + "source": [ + "In this code block, the conditional statement filters out any characters in sentence that aren’t a vowel." + ] + }, + { + "cell_type": "markdown", + "id": "32cc82ec", + "metadata": {}, + "source": [ + "The conditional can test any valid expression. If you need a more complex filter, then you can even move the conditional logic to a separate function:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "91b9be41", + "metadata": {}, + "outputs": [], + "source": [ + "sentence = 'The rocket, who was named Ted, came back \\\n", + "from Mars because he missed his friends.'" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "86730e6a", + "metadata": {}, + "outputs": [], + "source": [ + "def is_consonant(letter):\n", + " vowels = 'aeiou'\n", + " return letter.isalpha() and letter.lower() not in vowels" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "55c04cd2", + "metadata": {}, + "outputs": [], + "source": [ + "consonants = [i for i in sentence if is_consonant(i)]" + ] + }, + { + "cell_type": "markdown", + "id": "9226fd8b", + "metadata": {}, + "source": [ + "Here, you create a complex filter `is_consonant()` and pass this function as the conditional statement for your list comprehension. Note that the member value `i` is also passed as an argument to your function." + ] + }, + { + "cell_type": "markdown", + "id": "ce74e165", + "metadata": {}, + "source": [ + "You can place the conditional at the end of the statement for simple filtering, but what if you want to change a member value instead of filtering it out? In this case, it’s useful to place the conditional near the beginning of the expression:\n", + "\n", + "```python\n", + "new_list = [expression (if conditional) for member in iterable]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "80d084a8", + "metadata": {}, + "source": [ + "With this formula, you can use conditional logic to select from multiple possible output options. For example, if you have a list of prices, then you may want to replace negative prices with 0 and leave the positive values unchanged:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "20d87c8d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.25, 0, 10.22, 3.78, 0, 1.16]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "original_prices = [1.25, -9.45, 10.22, 3.78, -5.92, 1.16]\n", + "prices = [i if i > 0 else 0 for i in original_prices]\n", + "prices" + ] + }, + { + "cell_type": "markdown", + "id": "63971998", + "metadata": {}, + "source": [ + "Here, your expression `i` contains a conditional statement, if `i > 0` else `0`. This tells Python to output the value of `i` if the number is positive, but to change `i` to `0` if the number is negative. If this seems overwhelming, then it may be helpful to view the conditional logic as its own function:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "38542932", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.25, 0, 10.22, 3.78, 0, 1.16]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def get_price(price):\n", + " return price if price > 0 else 0\n", + "prices = [get_price(i) for i in original_prices]\n", + "prices" + ] + }, + { + "cell_type": "markdown", + "id": "eb89d56e", + "metadata": {}, + "source": [ + "Now, your conditional statement is contained within `get_price()`, and you can use it as part of your list comprehension expression." + ] + }, + { + "cell_type": "markdown", + "id": "5f3535ca", + "metadata": {}, + "source": [ + "### Using Set and Dictionary Comprehensions" + ] + }, + { + "cell_type": "markdown", + "id": "f2dfa5a8", + "metadata": {}, + "source": [ + "While the list comprehension in Python is a common tool, you can also create set and dictionary comprehensions. A **set** comprehension is almost exactly the same as a list comprehension in Python. The difference is that set comprehensions make sure the output contains no duplicates. You can create a set comprehension by using curly braces instead of brackets:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "23b11126", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a', 'e', 'i', 'u'}" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "quote = \"life, uh, finds a way\"\n", + "unique_vowels = {i for i in quote if i in 'aeiou'}\n", + "unique_vowels" + ] + }, + { + "cell_type": "markdown", + "id": "e16921e4", + "metadata": {}, + "source": [ + "Your set comprehension outputs all the unique vowels it found in `quote`. Unlike lists, sets don’t guarantee that items will be saved in any particular order. This is why the first member of the set is `a`, even though the first vowel in quote is `i`." + ] + }, + { + "cell_type": "markdown", + "id": "0ecfa4a2", + "metadata": {}, + "source": [ + "**Dictionary comprehensions** are similar, with the additional requirement of defining a key:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "8e4c4e43", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "squares = {i: i * i for i in range(10)}\n", + "squares" + ] + }, + { + "cell_type": "markdown", + "id": "d85016e5", + "metadata": {}, + "source": [ + "To create the squares dictionary, you use curly braces (`{}`) as well as a key-value pair (`i: i * i`) in your expression." + ] + }, + { + "cell_type": "markdown", + "id": "ff9324d5", + "metadata": {}, + "source": [ + "## When Not to Use a List Comprehension in Python" + ] + }, + { + "cell_type": "markdown", + "id": "52ed3727", + "metadata": {}, + "source": [ + "List comprehensions are useful and can help you write elegant code that’s easy to read and debug, but they’re not the right choice for all circumstances. They might make your code run more slowly or use more memory. If your code is less performant or harder to understand, then it’s probably better to choose an alternative." + ] + }, + { + "cell_type": "markdown", + "id": "6b639e31", + "metadata": {}, + "source": [ + "### Watch Out for Nested Comprehensions" + ] + }, + { + "cell_type": "markdown", + "id": "9acecef6", + "metadata": {}, + "source": [ + "Comprehensions can be **nested** to create combinations of lists, dictionaries, and sets within a collection. For example, say a climate laboratory is tracking the high temperature in five different cities for the first week of June. The perfect data structure for storing this data could be a Python list comprehension nested within a dictionary comprehension:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "8dc1543c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Austin': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Tacoma': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Topeka': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Sacramento': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Charlotte': [0, 0, 0, 0, 0, 0, 0]}" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cities = ['Austin', 'Tacoma', 'Topeka', 'Sacramento', 'Charlotte']\n", + "temps = {city: [0 for _ in range(7)] for city in cities}\n", + "temps" + ] + }, + { + "cell_type": "markdown", + "id": "60f08db0", + "metadata": {}, + "source": [ + "You create the outer collection temps with a dictionary comprehension. The expression is a key-value pair, which contains yet another comprehension. This code will quickly generate a list of data for each city in `cities`." + ] + }, + { + "cell_type": "markdown", + "id": "e33bfa5b", + "metadata": {}, + "source": [ + "Nested lists are a common way to create **matrices**, which are often used for mathematical purposes. Take a look at the code block below:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "c35b13e4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4]]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matrix = [[i for i in range(5)] for _ in range(6)]\n", + "matrix" + ] + }, + { + "cell_type": "markdown", + "id": "cec3d619", + "metadata": {}, + "source": [ + "The outer list comprehension `[... for _ in range(6)]` creates six rows, while the inner list comprehension `[i for i in range(5)]` fills each of these rows with values." + ] + }, + { + "cell_type": "markdown", + "id": "5b40eff6", + "metadata": {}, + "source": [ + "So far, the purpose of each nested comprehension is pretty intuitive. However, there are other situations, such as **flattening** nested lists, where the logic arguably makes your code more confusing. Take this example, which uses a nested list comprehension to flatten a matrix:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "028db7cb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flat = [num for row in matrix for num in row]\n", + "flat" + ] + }, + { + "cell_type": "markdown", + "id": "fcc225d7", + "metadata": {}, + "source": [ + "The code to flatten the matrix is concise, but it may not be so intuitive to understand how it works. On the other hand, if you were to use `for` loops to flatten the same matrix, then your code will be much more straightforward:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "3808359a", + "metadata": {}, + "outputs": [], + "source": [ + "matrix = [\n", + " [0, 0, 0],\n", + " [1, 1, 1],\n", + " [2, 2, 2],\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "300850a3", + "metadata": {}, + "outputs": [], + "source": [ + "flat = []\n", + "for row in matrix:\n", + " for num in row:\n", + " flat.append(num)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "84440358", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 0, 0, 1, 1, 1, 2, 2, 2]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flat" + ] + }, + { + "cell_type": "markdown", + "id": "fed06ea0", + "metadata": {}, + "source": [ + "Now you can see that the code traverses one row of the matrix at a time, pulling out all the elements in that row before moving on to the next one.\n", + "\n", + "While the single-line nested list comprehension might seem more Pythonic, what’s most important is to write code that your team can easily understand and modify. When you choose your approach, you’ll have to make a judgment call based on whether you think the comprehension helps or hurts readability." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/01. Basics/tmp/14 IO Operations.ipynb b/python/01. Basics/tmp/14 IO Operations.ipynb index 5c004b2..9beba8f 100755 --- a/python/01. Basics/tmp/14 IO Operations.ipynb +++ b/python/01. Basics/tmp/14 IO Operations.ipynb @@ -827,7 +827,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -841,7 +841,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/python/02. Object Oriented Programming/03 Inheritance.ipynb b/python/02. Object Oriented Programming/03 Inheritance.ipynb index 90f2fcf..492f057 100755 --- a/python/02. Object Oriented Programming/03 Inheritance.ipynb +++ b/python/02. Object Oriented Programming/03 Inheritance.ipynb @@ -786,7 +786,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/02. Object Oriented Programming/04 Composition.ipynb b/python/02. Object Oriented Programming/04 Composition.ipynb index 168746d..9ec98bb 100755 --- a/python/02. Object Oriented Programming/04 Composition.ipynb +++ b/python/02. Object Oriented Programming/04 Composition.ipynb @@ -39,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "incorporate-coupon", "metadata": {}, "outputs": [], @@ -67,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 40, "id": "virtual-margin", "metadata": {}, "outputs": [], @@ -81,7 +81,7 @@ " self.width = width\n", " self.height = height\n", " \n", - " def area(self,):\n", + " def area(self):\n", " return self.width * self.height\n", " \n", " def perimeter(self,):\n", @@ -100,7 +100,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 41, "id": "shared-nickel", "metadata": {}, "outputs": [ @@ -108,7 +108,6 @@ "name": "stdout", "output_type": "stream", "text": [ - "Shape constructor called!\n", "Rectangle constructor called!\n" ] } @@ -246,7 +245,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 59, "id": "aware-pride", "metadata": {}, "outputs": [], @@ -263,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 60, "id": "premium-evaluation", "metadata": {}, "outputs": [], @@ -281,7 +280,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 61, "id": "southeast-radical", "metadata": {}, "outputs": [ @@ -307,7 +306,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 62, "id": "annual-radiation", "metadata": {}, "outputs": [ @@ -315,13 +314,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Shape constructor called!\n", "Rectangle constructor called!\n" ] } ], "source": [ - "r = Rectangle(3, 4, color=red_color)" + "r = Rectangle(3, 4, color=Color(\"Red\", \"D33817\", (211, 56, 23)))" ] }, { diff --git a/python/02. Object Oriented Programming/05 Overriding.ipynb b/python/02. Object Oriented Programming/05 Overriding.ipynb index 57b5ce6..13a090a 100755 --- a/python/02. Object Oriented Programming/05 Overriding.ipynb +++ b/python/02. Object Oriented Programming/05 Overriding.ipynb @@ -202,7 +202,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 1, "id": "satisfied-portugal", "metadata": {}, "outputs": [], @@ -211,14 +211,14 @@ " def __init__(self, cart, customer):\n", " self.cart = list(cart)\n", " self.customer = customer\n", - "\n", + " \n", " def __len__(self):\n", " return len(self.cart)" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 2, "id": "registered-plaza", "metadata": {}, "outputs": [ @@ -228,7 +228,7 @@ "3" ] }, - "execution_count": 22, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -259,7 +259,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0morder\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mOrder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'banana'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'apple'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mango'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Real Python'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0morder\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Calling len when no __len__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_10963/3617644781.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0morder\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mOrder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'banana'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'apple'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'mango'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Real Python'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0morder\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Calling len when no __len__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: object of type 'Order' has no len()" ] } @@ -363,7 +363,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 4, "id": "driving-harvey", "metadata": {}, "outputs": [], @@ -379,7 +379,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 5, "id": "rolled-garage", "metadata": {}, "outputs": [ @@ -389,7 +389,7 @@ "5.0" ] }, - "execution_count": 43, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -760,7 +760,7 @@ }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 218, "id": "blessed-norwegian", "metadata": {}, "outputs": [], @@ -838,6 +838,16 @@ "order[:2]" ] }, + { + "cell_type": "code", + "execution_count": 219, + "id": "48eaf91e", + "metadata": {}, + "outputs": [], + "source": [ + "o = Order([], \"\")" + ] + }, { "cell_type": "markdown", "id": "recent-johnson", @@ -889,7 +899,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/02. Object Oriented Programming/06 Data Types Methods.ipynb b/python/02. Object Oriented Programming/06 Data Types Methods.ipynb index 7bdcc54..5f28629 100755 --- a/python/02. Object Oriented Programming/06 Data Types Methods.ipynb +++ b/python/02. Object Oriented Programming/06 Data Types Methods.ipynb @@ -81,15 +81,6 @@ "`is_integer()` checks if a float number is actually an integer." ] }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "float_num = 1.0" - ] - }, { "cell_type": "code", "execution_count": 29, @@ -119,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -128,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -137,7 +128,7 @@ "(1-3j)" ] }, - "execution_count": 32, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -155,22 +146,22 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(1.0, 0.0)" + "(1.0, 3.0)" ] }, - "execution_count": 33, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "x.real, x.imag" + "complex_num.real, complex_num.imag" ] }, { @@ -689,16 +680,16 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "8" + "0" ] }, - "execution_count": 51, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -709,7 +700,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -718,7 +709,7 @@ "-1" ] }, - "execution_count": 53, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1046,7 +1037,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -1055,7 +1046,7 @@ "True" ] }, - "execution_count": 64, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -1086,7 +1077,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -1095,7 +1086,7 @@ "False" ] }, - "execution_count": 66, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1274,16 +1265,16 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "False" + "True" ] }, - "execution_count": 74, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -3413,6 +3404,44 @@ "`a.append()` appends object `` to the end of list `a`:" ] }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "x = [1, 2, 3]" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [], + "source": [ + "x.append(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 3, 3]" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x" + ] + }, { "cell_type": "code", "execution_count": 148, @@ -3708,7 +3737,7 @@ }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 100, "metadata": {}, "outputs": [], "source": [ @@ -3718,7 +3747,7 @@ }, { "cell_type": "code", - "execution_count": 166, + "execution_count": 101, "metadata": {}, "outputs": [ { @@ -3727,7 +3756,7 @@ "3.14159" ] }, - "execution_count": 166, + "execution_count": 101, "metadata": {}, "output_type": "execute_result" } @@ -3738,7 +3767,7 @@ }, { "cell_type": "code", - "execution_count": 167, + "execution_count": 102, "metadata": {}, "outputs": [ { @@ -3747,7 +3776,7 @@ "['foo', 'bar', 'baz', 3.14159, 'qux', 'quux', 'corge']" ] }, - "execution_count": 167, + "execution_count": 102, "metadata": {}, "output_type": "execute_result" } @@ -4066,7 +4095,7 @@ }, { "cell_type": "code", - "execution_count": 188, + "execution_count": 118, "metadata": {}, "outputs": [], "source": [ @@ -4075,7 +4104,7 @@ }, { "cell_type": "code", - "execution_count": 189, + "execution_count": 119, "metadata": {}, "outputs": [ { @@ -4084,7 +4113,7 @@ "3" ] }, - "execution_count": 189, + "execution_count": 119, "metadata": {}, "output_type": "execute_result" } @@ -4095,7 +4124,7 @@ }, { "cell_type": "code", - "execution_count": 190, + "execution_count": 120, "metadata": {}, "outputs": [ { @@ -4104,7 +4133,7 @@ "2" ] }, - "execution_count": 190, + "execution_count": 120, "metadata": {}, "output_type": "execute_result" } @@ -4124,7 +4153,7 @@ }, { "cell_type": "code", - "execution_count": 195, + "execution_count": 121, "metadata": {}, "outputs": [], "source": [ @@ -4133,7 +4162,7 @@ }, { "cell_type": "code", - "execution_count": 196, + "execution_count": 122, "metadata": {}, "outputs": [ { @@ -4142,7 +4171,7 @@ "2" ] }, - "execution_count": 196, + "execution_count": 122, "metadata": {}, "output_type": "execute_result" } @@ -4153,7 +4182,7 @@ }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 123, "metadata": {}, "outputs": [ { @@ -4163,7 +4192,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Bark!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Bark!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: 'Bark!' is not in list" ] } @@ -4211,7 +4240,7 @@ }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 124, "metadata": {}, "outputs": [], "source": [ @@ -4220,7 +4249,7 @@ }, { "cell_type": "code", - "execution_count": 201, + "execution_count": 125, "metadata": {}, "outputs": [ { @@ -4229,7 +4258,7 @@ "{'a': 10, 'b': 20, 'c': 30}" ] }, - "execution_count": 201, + "execution_count": 125, "metadata": {}, "output_type": "execute_result" } @@ -4240,7 +4269,7 @@ }, { "cell_type": "code", - "execution_count": 202, + "execution_count": 126, "metadata": {}, "outputs": [], "source": [ @@ -4249,7 +4278,7 @@ }, { "cell_type": "code", - "execution_count": 203, + "execution_count": 127, "metadata": {}, "outputs": [ { @@ -4258,7 +4287,7 @@ "{}" ] }, - "execution_count": 203, + "execution_count": 127, "metadata": {}, "output_type": "execute_result" } @@ -4641,7 +4670,7 @@ }, { "cell_type": "code", - "execution_count": 218, + "execution_count": 152, "metadata": {}, "outputs": [], "source": [ @@ -4650,7 +4679,7 @@ }, { "cell_type": "code", - "execution_count": 219, + "execution_count": 153, "metadata": {}, "outputs": [ { @@ -4659,7 +4688,7 @@ "20" ] }, - "execution_count": 219, + "execution_count": 153, "metadata": {}, "output_type": "execute_result" } @@ -4670,7 +4699,7 @@ }, { "cell_type": "code", - "execution_count": 220, + "execution_count": 154, "metadata": {}, "outputs": [ { @@ -4679,7 +4708,7 @@ "{'a': 10, 'c': 30}" ] }, - "execution_count": 220, + "execution_count": 154, "metadata": {}, "output_type": "execute_result" } @@ -5004,7 +5033,7 @@ }, { "cell_type": "code", - "execution_count": 236, + "execution_count": 160, "metadata": {}, "outputs": [], "source": [ @@ -5013,7 +5042,7 @@ }, { "cell_type": "code", - "execution_count": 237, + "execution_count": 161, "metadata": {}, "outputs": [], "source": [ @@ -5022,7 +5051,7 @@ }, { "cell_type": "code", - "execution_count": 238, + "execution_count": 162, "metadata": {}, "outputs": [ { @@ -5031,7 +5060,7 @@ "{'a': 10, 'b': 200, 'c': 30, 'd': 400}" ] }, - "execution_count": 238, + "execution_count": 162, "metadata": {}, "output_type": "execute_result" } @@ -5050,7 +5079,7 @@ }, { "cell_type": "code", - "execution_count": 239, + "execution_count": 163, "metadata": {}, "outputs": [], "source": [ @@ -5059,7 +5088,7 @@ }, { "cell_type": "code", - "execution_count": 240, + "execution_count": 164, "metadata": {}, "outputs": [], "source": [ @@ -5068,7 +5097,7 @@ }, { "cell_type": "code", - "execution_count": 241, + "execution_count": 165, "metadata": {}, "outputs": [ { @@ -5077,7 +5106,7 @@ "{'a': 10, 'b': 200, 'c': 30, 'd': 400}" ] }, - "execution_count": 241, + "execution_count": 165, "metadata": {}, "output_type": "execute_result" } @@ -5184,7 +5213,7 @@ }, { "cell_type": "code", - "execution_count": 245, + "execution_count": 175, "metadata": {}, "outputs": [], "source": [ @@ -5196,7 +5225,7 @@ }, { "cell_type": "code", - "execution_count": 246, + "execution_count": 179, "metadata": {}, "outputs": [ { @@ -5205,7 +5234,7 @@ "{1, 2, 3, 4, 5, 6, 7}" ] }, - "execution_count": 246, + "execution_count": 179, "metadata": {}, "output_type": "execute_result" } @@ -5216,7 +5245,7 @@ }, { "cell_type": "code", - "execution_count": 247, + "execution_count": 182, "metadata": {}, "outputs": [ { @@ -5225,7 +5254,7 @@ "{1, 2, 3, 4, 5, 6, 7}" ] }, - "execution_count": 247, + "execution_count": 182, "metadata": {}, "output_type": "execute_result" } @@ -6828,7 +6857,7 @@ }, { "cell_type": "code", - "execution_count": 317, + "execution_count": 195, "metadata": {}, "outputs": [], "source": [ @@ -6837,7 +6866,7 @@ }, { "cell_type": "code", - "execution_count": 318, + "execution_count": 196, "metadata": {}, "outputs": [ { @@ -6846,7 +6875,7 @@ "{'bar', 'foo'}" ] }, - "execution_count": 318, + "execution_count": 196, "metadata": {}, "output_type": "execute_result" } @@ -6858,7 +6887,7 @@ }, { "cell_type": "code", - "execution_count": 319, + "execution_count": 197, "metadata": {}, "outputs": [ { @@ -6867,7 +6896,7 @@ "{'bar', 'foo'}" ] }, - "execution_count": 319, + "execution_count": 197, "metadata": {}, "output_type": "execute_result" } @@ -7104,7 +7133,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/02. Object Oriented Programming/07. Reading and Writing Files.ipynb b/python/02. Object Oriented Programming/07. Reading and Writing Files.ipynb new file mode 100644 index 0000000..c101371 --- /dev/null +++ b/python/02. Object Oriented Programming/07. Reading and Writing Files.ipynb @@ -0,0 +1,1297 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0997b15e", + "metadata": {}, + "source": [ + "# Reading and Writing Files" + ] + }, + { + "cell_type": "markdown", + "id": "f2de8858", + "metadata": {}, + "source": [ + "One of the most common tasks that you can do with Python is reading and writing files. Whether it’s writing to a simple text file, reading a complicated server log, or even analyzing raw byte data, all of these situations require reading or writing a file." + ] + }, + { + "cell_type": "markdown", + "id": "e7ba00a3", + "metadata": {}, + "source": [ + "## What Is a File?\n", + "Before we can go into how to work with files in Python, it’s important to understand what exactly a file is and how modern operating systems handle some of their aspects." + ] + }, + { + "cell_type": "markdown", + "id": "cfa2aa1e", + "metadata": {}, + "source": [ + "At its core, a file is a contiguous set of bytes [used to store data](https://en.wikipedia.org/wiki/Computer_file). This data is organized in a specific format and can be anything as simple as a text file or as complicated as a program executable. In the end, these byte files are then translated into binary 1 and 0 for easier processing by the computer." + ] + }, + { + "cell_type": "markdown", + "id": "cb6ff149", + "metadata": {}, + "source": [ + "Files on most modern file systems are composed of three main parts:\n", + "\n", + "- **Header**: metadata about the contents of the file (file name, size, type, and so on)\n", + "- **Data**: contents of the file as written by the creator or editor\n", + "- **End of file (EOF)**: special character that indicates the end of the file" + ] + }, + { + "cell_type": "markdown", + "id": "705c2371", + "metadata": {}, + "source": [ + "\"file" + ] + }, + { + "cell_type": "markdown", + "id": "fc3fca71", + "metadata": {}, + "source": [ + "What this data represents depends on the format specification used, which is typically represented by an extension. For example, a file that has an extension of `.gif` most likely conforms to the [Graphics Interchange Format](https://en.wikipedia.org/wiki/GIF) specification. There are hundreds, if not thousands, of file extensions out there. For this section, you’ll only deal with `.txt` file extensions." + ] + }, + { + "cell_type": "markdown", + "id": "863944db", + "metadata": {}, + "source": [ + "### File Paths\n", + "When you access a file on an operating system, a file path is required. The file path is a string that represents the location of a file. It’s broken up into three major parts:\n", + "\n", + "1. **Folder Path:** the file folder location on the file system where subsequent folders are separated by a forward slash `/` (Unix) or backslash `\\` (Windows)\n", + "2. **File Name:** the actual name of the file\n", + "3. **Extension:** the end of the file path pre-pended with a period (`.`) used to indicate the file type" + ] + }, + { + "cell_type": "markdown", + "id": "add1a0f9", + "metadata": {}, + "source": [ + "Here’s a quick example. Let’s say you have a file located within a file structure like this:\n", + "\n", + "```\n", + "/\n", + "│\n", + "├── path/\n", + "| │\n", + "│ ├── to/\n", + "│ │ └── cats.gif\n", + "│ │\n", + "│ └── dog_breeds.txt\n", + "|\n", + "└── animals.csv\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "9b75945d", + "metadata": {}, + "source": [ + "Let’s say you wanted to access the `cats.gif` file, and your current location was in the same folder as path. In order to access the file, you need to go through the path folder and then the to folder, finally arriving at the `cats.gif` file. The Folder Path is `path/to/`. The File Name is `cats`. The File Extension is `.gif`. So the full path is `path/to/cats.gif`." + ] + }, + { + "cell_type": "markdown", + "id": "5b9b7f5f", + "metadata": {}, + "source": [ + "Now let’s say that your current location or current working directory (cwd) is in the to folder of our example folder structure. Instead of referring to the `cats.gif` by the full path of `path/to/cats.gif`, the file can be simply referenced by the file name and extension `cats.gif`.\n", + "\n", + "```\n", + "/\n", + "│\n", + "├── path/\n", + "| │\n", + "| ├── to/ ← Your current working directory (cwd) is here\n", + "| │ └── cats.gif ← Accessing this file\n", + "| │\n", + "| └── dog_breeds.txt\n", + "|\n", + "└── animals.csv\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "145af880", + "metadata": {}, + "source": [ + "But what about `dog_breeds.txt`? How would you access that without using the full path? You can use the special characters double-dot (`..`) to move one directory up. This means that `../dog_breeds.txt` will reference the `dog_breeds.txt` file from the directory of to:\n", + "\n", + "```\n", + "/\n", + "│\n", + "├── path/ ← Referencing this parent folder\n", + "| │\n", + "| ├── to/ ← Current working directory (cwd)\n", + "| │ └── cats.gif\n", + "| │\n", + "| └── dog_breeds.txt ← Accessing this file\n", + "|\n", + "└── animals.csv\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "d3cf3cd5", + "metadata": {}, + "source": [ + "The double-dot (`..`) can be chained together to traverse multiple directories above the current directory. For example, to access `animals.csv` from the to folder, you would use `../../animals.csv`." + ] + }, + { + "cell_type": "markdown", + "id": "d0289b8c", + "metadata": {}, + "source": [ + "### Line Endings\n", + "One problem often encountered when working with file data is the representation of a new line or line ending. The line ending has its roots from back in the Morse Code era, [when a specific pro-sign was used to communicate the end of a transmission or the end of a line](https://en.wikipedia.org/wiki/Prosigns_for_Morse_code#Official_International_Morse_code_procedure_signs)." + ] + }, + { + "cell_type": "markdown", + "id": "ed8994e4", + "metadata": {}, + "source": [ + "Later, this [was standardized for teleprinters](https://en.wikipedia.org/wiki/Newline#History) by both the International Organization for Standardization (ISO) and the American Standards Association (ASA). ASA standard states that line endings should use the sequence of the Carriage Return (CR or \\r) and the Line Feed (LF or \\n) characters (CR+LF or \\r\\n). The ISO standard however allowed for either the CR+LF characters or just the LF character." + ] + }, + { + "cell_type": "markdown", + "id": "067965e0", + "metadata": {}, + "source": [ + "[Windows uses the CR+LF characters](https://unix.stackexchange.com/a/411830) to indicate a new line, while Unix and the newer Mac versions use just the LF character. This can cause some complications when you’re processing files on an operating system that is different than the file’s source. Here’s a quick example. Let’s say that we examine the file `dog_breeds.txt` that was created on a Windows system:\n", + "\n", + "```\n", + "Pug\\r\\n\n", + "Jack Russell Terrier\\r\\n\n", + "English Springer Spaniel\\r\\n\n", + "German Shepherd\\r\\n\n", + "Staffordshire Bull Terrier\\r\\n\n", + "Cavalier King Charles Spaniel\\r\\n\n", + "Golden Retriever\\r\\n\n", + "West Highland White Terrier\\r\\n\n", + "Boxer\\r\\n\n", + "Border Terrier\\r\\n\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "73ac4fbb", + "metadata": {}, + "source": [ + "This same output will be interpreted on a Unix device differently:\n", + "\n", + "```Pug\\r\n", + "\\n\n", + "Jack Russell Terrier\\r\n", + "\\n\n", + "English Springer Spaniel\\r\n", + "\\n\n", + "German Shepherd\\r\n", + "\\n\n", + "Staffordshire Bull Terrier\\r\n", + "\\n\n", + "Cavalier King Charles Spaniel\\r\n", + "\\n\n", + "Golden Retriever\\r\n", + "\\n\n", + "West Highland White Terrier\\r\n", + "\\n\n", + "Boxer\\r\n", + "\\n\n", + "Border Terrier\\r\n", + "\\n\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "747c93b9", + "metadata": {}, + "source": [ + "### Character Encodings\n", + "Another common problem that you may face is the encoding of the byte data. An encoding is a translation from byte data to human readable characters. This is typically done by assigning a numerical value to represent a character. The two most common encodings are the [ASCII](https://www.ascii-code.com/) and [UNICODE](https://unicode.org/) Formats. [ASCII can only store 128 characters](https://en.wikipedia.org/wiki/ASCII), while [Unicode can contain up to 1,114,112 characters](https://en.wikipedia.org/wiki/Unicode)." + ] + }, + { + "cell_type": "markdown", + "id": "e4247222", + "metadata": {}, + "source": [ + "ASCII is actually a subset of [Unicode](https://realpython.com/python-encodings-guide/) (UTF-8), meaning that ASCII and Unicode share the same numerical to character values. It’s important to note that parsing a file with the incorrect character encoding can lead to failures or misrepresentation of the character. For example, if a file was created using the UTF-8 encoding, and you try to parse it using the ASCII encoding, if there is a character that is outside of those 128 values, then an error will be thrown." + ] + }, + { + "cell_type": "markdown", + "id": "bee97daa", + "metadata": {}, + "source": [ + "## Opening and Closing a File in Python" + ] + }, + { + "cell_type": "markdown", + "id": "68751b59", + "metadata": {}, + "source": [ + "When you want to work with a file, the first thing to do is to open it. This is done by invoking the `open()` built-in function. `open()` has a single required argument that is the path to the file. `open()` has a single return, the file object:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "bf9ef4c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing myfile.txt\n" + ] + } + ], + "source": [ + "%%writefile myfile.txt\n", + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1396e21d", + "metadata": {}, + "outputs": [], + "source": [ + "file = open('myfile.txt')" + ] + }, + { + "cell_type": "markdown", + "id": "6284f411", + "metadata": {}, + "source": [ + "After you open a file, the next thing to learn is how to close it." + ] + }, + { + "cell_type": "markdown", + "id": "cae964f2", + "metadata": {}, + "source": [ + "> **Warning:** You should always make sure that an open file is properly closed." + ] + }, + { + "cell_type": "markdown", + "id": "87e761fc", + "metadata": {}, + "source": [ + "It’s important to remember that it’s your responsibility to close the file. In most cases, upon termination of an application or script, a file will be closed eventually. However, there is no guarantee when exactly that will happen. This can lead to unwanted behavior including resource leaks. It’s also a best practice within Python (Pythonic) to make sure that your code behaves in a way that is well defined and reduces any unwanted behavior." + ] + }, + { + "cell_type": "markdown", + "id": "87e6315c", + "metadata": {}, + "source": [ + "When you’re manipulating a file, there are two ways that you can use to ensure that a file is closed properly, even when encountering an error. The first way to close a file is to use the `try-finally` block:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "b6f50f81", + "metadata": {}, + "outputs": [], + "source": [ + "reader = open('myfile.txt')\n", + "try:\n", + " # Further file processing goes here\n", + " pass\n", + "finally:\n", + " reader.close()" + ] + }, + { + "cell_type": "markdown", + "id": "dce9264e", + "metadata": {}, + "source": [ + "> The `try-finally` block is covered in Error Handling section later." + ] + }, + { + "cell_type": "markdown", + "id": "db6d97e2", + "metadata": {}, + "source": [ + "The second way to close a file is to use the `with statement`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "11b23508", + "metadata": {}, + "outputs": [], + "source": [ + "with open('myfile.txt') as reader:\n", + " # Further file processing goes here\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "22c32869", + "metadata": {}, + "source": [ + "The with statement automatically takes care of closing the file once it leaves the with block, even in cases of error. I highly recommend that you use the with statement as much as possible, as it allows for cleaner code and makes handling any unexpected errors easier for you." + ] + }, + { + "cell_type": "markdown", + "id": "30e8f003", + "metadata": {}, + "source": [ + "Most likely, you’ll also want to use the second positional argument, mode. This argument is a string that contains multiple characters to represent how you want to open the file. The default and most common is `'r'`, which represents opening the file in read-only mode as a text file:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "39a508f8", + "metadata": {}, + "outputs": [], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " # Further file processing goes here\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "213056fe", + "metadata": {}, + "source": [ + "Other options for modes are [fully documented online](https://docs.python.org/3/library/functions.html#open), but the most commonly used ones are the following:\n", + "\n", + "|Character | Meaning|\n", + "|:--|:--|\n", + "|`'r'` | Open for reading (default)|\n", + "|`'w'` | Open for writing, truncating (overwriting) the file first|\n", + "|`'rb'` or `'wb'` | Open in binary mode (read/write using byte data)|" + ] + }, + { + "cell_type": "markdown", + "id": "a39ef1e8", + "metadata": {}, + "source": [ + "Let’s talk a little about file objects. A file object is:\n", + "\n", + "> \"an object exposing a file-oriented API (with methods such as read() or write()) to an underlying resource.\" ([Source](https://docs.python.org/3/glossary.html#term-file-object))" + ] + }, + { + "cell_type": "markdown", + "id": "36313915", + "metadata": {}, + "source": [ + "There are three different categories of file objects:\n", + "\n", + "- Text files\n", + "- Buffered binary files\n", + "- Raw binary files" + ] + }, + { + "cell_type": "markdown", + "id": "4ec0998e", + "metadata": {}, + "source": [ + "Each of these file types are defined in the `io` module. " + ] + }, + { + "cell_type": "markdown", + "id": "97ffda2b", + "metadata": {}, + "source": [ + "### Text File Types" + ] + }, + { + "cell_type": "markdown", + "id": "710127dc", + "metadata": {}, + "source": [ + "A text file is the most common file that you’ll encounter. Here are some examples of how these files are opened:\n", + "\n", + "```python\n", + "open('abc.txt')\n", + "\n", + "open('abc.txt', 'r')\n", + "\n", + "open('abc.txt', 'w')\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "700c72fd", + "metadata": {}, + "source": [ + "With these types of files, `open()` will return a `TextIOWrapper` file object:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3c875aa1", + "metadata": {}, + "outputs": [], + "source": [ + "file = open('myfile.txt')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4d5bf597", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "_io.TextIOWrapper" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(file)" + ] + }, + { + "cell_type": "markdown", + "id": "03a60f0c", + "metadata": {}, + "source": [ + "This is the default file object returned by `open()`." + ] + }, + { + "cell_type": "markdown", + "id": "cc07e624", + "metadata": {}, + "source": [ + "### Buffered Binary File Types" + ] + }, + { + "cell_type": "markdown", + "id": "b3622ae3", + "metadata": {}, + "source": [ + "A buffered binary file type is used for reading and writing binary files. Here are some examples of how these files are opened:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "958e06b4", + "metadata": {}, + "outputs": [], + "source": [ + "file = open('myfile.txt', 'rb')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "96a08c0c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "_io.BufferedReader" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "de48545d", + "metadata": {}, + "outputs": [], + "source": [ + "file = open('myfile.txt', 'wb')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "95de360b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "_io.BufferedWriter" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(file)" + ] + }, + { + "cell_type": "markdown", + "id": "804d2fc6", + "metadata": {}, + "source": [ + "With these types of files, `open()` will return either a `BufferedReader` or `BufferedWriter` file object:" + ] + }, + { + "cell_type": "markdown", + "id": "47305e25", + "metadata": {}, + "source": [ + "### Raw File Types" + ] + }, + { + "cell_type": "markdown", + "id": "252ddcab", + "metadata": {}, + "source": [ + "A raw file type is:\n", + "\n", + "> “generally used as a low-level building-block for binary and text streams.” ([Source](https://docs.python.org/3.7/library/io.html#raw-i-o))" + ] + }, + { + "cell_type": "markdown", + "id": "2d2fccc0", + "metadata": {}, + "source": [ + "It is therefore not typically used." + ] + }, + { + "cell_type": "markdown", + "id": "ad2da113", + "metadata": {}, + "source": [ + "Here’s an example of how these files are opened:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "1319583d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<_io.FileIO name='myfile.txt' mode='rb' closefd=True>" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open('myfile.txt', 'rb', buffering=0)" + ] + }, + { + "cell_type": "markdown", + "id": "d6514386", + "metadata": {}, + "source": [ + "With these types of files, `open()` will return a `FileIO` file object:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "46ecb126", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "_io.FileIO" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file = open('myfile.txt', 'rb', buffering=0)\n", + "type(file)" + ] + }, + { + "cell_type": "markdown", + "id": "d47d9552", + "metadata": {}, + "source": [ + "## Reading and Writing Opened Files" + ] + }, + { + "cell_type": "markdown", + "id": "f357f312", + "metadata": {}, + "source": [ + "Once you’ve opened up a file, you’ll want to read or write to the file. First off, let’s cover reading a file. There are multiple methods that can be called on a file object to help you out:\n", + "\n", + "|Method |What It Does|\n", + "|:--|:--|\n", + "|`.read(size=-1)` | This reads from the file based on the number of `size` bytes. If no argument is passed or `None` or `-1` is passed, then the entire file is read. |\n", + "|`.readline(size=-1)` | This reads at most size number of characters from the line. This continues to the end of the line and then wraps back around. If no argument is passed or `None` or `-1` is passed, then the entire line (or rest of the line) is read. |\n", + "|`.readlines()` | This reads the remaining lines from the file object and returns them as a list. |" + ] + }, + { + "cell_type": "markdown", + "id": "592765d0", + "metadata": {}, + "source": [ + "Using the same `myfile.txt` file you used above, let’s go through some examples of how to use these methods. Here’s an example of how to open and read the entire file using `.read()`:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "b630d758", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting myfile.txt\n" + ] + } + ], + "source": [ + "%%writefile myfile.txt\n", + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "1dec4e23", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6\n", + "\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " # Read & print the entire file\n", + " print(reader.read())" + ] + }, + { + "cell_type": "markdown", + "id": "8c77d06a", + "metadata": {}, + "source": [ + "Here’s an example of how to read 5 bytes of a line each time using the Python `.readline()` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "3caf950e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this \n", + "is li\n", + "ne 1\n", + "\n", + "this \n", + "is li\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " # Read & print the first 5 characters of the line 5 times\n", + " print(reader.readline(5))\n", + "\n", + " # Notice that line is greater than the 5 chars and continues\n", + " # down the line, reading 5 chars each time until the end of the\n", + " # line and then \"wraps\" around\n", + " print(reader.readline(5))\n", + " print(reader.readline(5))\n", + " print(reader.readline(5))\n", + " print(reader.readline(5))" + ] + }, + { + "cell_type": "markdown", + "id": "20ef9193", + "metadata": {}, + "source": [ + "Here’s an example of how to read the entire file as a list using the Python `.readlines()` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "6ca7b61c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['this is line 1\\n',\n", + " 'this is line 2\\n',\n", + " 'this is line 3\\n',\n", + " 'this is line 4\\n',\n", + " 'this is line 5\\n',\n", + " 'this is line 6\\n']" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f = open('myfile.txt')\n", + "f.readlines() # Returns a list object" + ] + }, + { + "cell_type": "markdown", + "id": "dff763ff", + "metadata": {}, + "source": [ + "The above example can also be done by using `list()` to create a list out of the file object:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "156f3fcd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['this is line 1\\n',\n", + " 'this is line 2\\n',\n", + " 'this is line 3\\n',\n", + " 'this is line 4\\n',\n", + " 'this is line 5\\n',\n", + " 'this is line 6\\n']" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f = open('myfile.txt')\n", + "list(f)" + ] + }, + { + "cell_type": "markdown", + "id": "9cb92565", + "metadata": {}, + "source": [ + "### Iterating Over Each Line in the File" + ] + }, + { + "cell_type": "markdown", + "id": "c82ede65", + "metadata": {}, + "source": [ + "A common thing to do while reading a file is to iterate over each line. Here’s an example of how to use the Python `.readline()` method to perform that iteration:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "f9b5440a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " # Read and print the entire file line by line\n", + " line = reader.readline()\n", + " while line != '': # The EOF char is an empty string\n", + " print(line, end='')\n", + " line = reader.readline()" + ] + }, + { + "cell_type": "markdown", + "id": "db543f09", + "metadata": {}, + "source": [ + "Another way you could iterate over each line in the file is to use the Python `.readlines()` method of the file object. Remember, `.readlines()` returns a list where each element in the list represents a line in the file:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "124fe6a7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " for line in reader.readlines():\n", + " print(line, end='')" + ] + }, + { + "cell_type": "markdown", + "id": "99b386da", + "metadata": {}, + "source": [ + "However, the above examples can be further simplified by iterating over the file object itself:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "1c3d366b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " # Read and print the entire file line by line\n", + " for line in reader:\n", + " print(line, end='')" + ] + }, + { + "cell_type": "markdown", + "id": "6c76699a", + "metadata": {}, + "source": [ + "This final approach is more Pythonic and can be quicker and more memory efficient. Therefore, it is suggested you use this instead." + ] + }, + { + "cell_type": "markdown", + "id": "0bba575c", + "metadata": {}, + "source": [ + "> Note: Some of the above examples contain `print('some text', end='')`. The `end=''` is to prevent Python from adding an additional newline to the text that is being printed and only print what is being read from the file." + ] + }, + { + "cell_type": "markdown", + "id": "4b33648e", + "metadata": {}, + "source": [ + "Now let’s dive into writing files. As with reading files, file objects have multiple methods that are useful for writing to a file:\n", + "\n", + "|Method\t|What It Does|\n", + "|:--|:--|\n", + "|`.write(string)`\t|This writes the string to the file.|\n", + "|`.writelines(seq)`\t|This writes the sequence to the file. No line endings are appended to each sequence item. It’s up to you to add the appropriate line ending(s).|" + ] + }, + { + "cell_type": "markdown", + "id": "2bc758b0", + "metadata": {}, + "source": [ + "Here’s a quick example of using `.write()` and `.writelines()`:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "de298247", + "metadata": {}, + "outputs": [], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " # Note: readlines doesn't trim the line endings\n", + " lines = reader.readlines()\n", + "\n", + "with open('myfile_reversed.txt', 'w') as writer:\n", + " # Alternatively you could use\n", + " # writer.writelines(reversed(dog_breeds))\n", + "\n", + " # Write the dog breeds to the file in reversed order\n", + " for line in reversed(lines):\n", + " writer.write(line)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e18535e4", + "metadata": {}, + "outputs": [], + "source": [ + "with open('myfile_reversed.txt', 'r') as reader:\n", + " # Note: readlines doesn't trim the line endings\n", + " lines = reader.readlines()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a649dc35", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['this is line 6\\n',\n", + " 'this is line 5\\n',\n", + " 'this is line 4\\n',\n", + " 'this is line 3\\n',\n", + " 'this is line 2\\n',\n", + " 'this is line 1\\n']" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lines" + ] + }, + { + "cell_type": "markdown", + "id": "6cb236bb", + "metadata": {}, + "source": [ + "### Appending to a File" + ] + }, + { + "cell_type": "markdown", + "id": "8c7cd96a", + "metadata": {}, + "source": [ + "Sometimes, you may want to append to a file or start writing at the end of an already populated file. This is easily done by using the `'a'` character for the mode argument:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a9a21a1d", + "metadata": {}, + "outputs": [], + "source": [ + "with open('myfile.txt', 'a') as a_writer:\n", + " a_writer.write('this is line 7')" + ] + }, + { + "cell_type": "markdown", + "id": "80b1d137", + "metadata": {}, + "source": [ + "When you examine `myfile.txt` again, you’ll see that the beginning of the file is unchanged and Beagle is now added to the end of the file:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "d1f260ed", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "this is line 1\n", + "this is line 2\n", + "this is line 3\n", + "this is line 4\n", + "this is line 5\n", + "this is line 6\n", + "this is line 7\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'r') as reader:\n", + " print(reader.read())" + ] + }, + { + "cell_type": "markdown", + "id": "01a60cf0", + "metadata": {}, + "source": [ + "### Working With Two Files at the Same Time" + ] + }, + { + "cell_type": "markdown", + "id": "8f87750f", + "metadata": {}, + "source": [ + "There are times when you may want to read a file and write to another file at the same time. If you use the example that was shown when you were learning how to write to a file, it can actually be combined into the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "9e7d3de9", + "metadata": {}, + "outputs": [], + "source": [ + "d_path = 'myfile.txt'\n", + "d_r_path = 'myfile_reversed.txt'\n", + "with open(d_path, 'r') as reader, open(d_r_path, 'w') as writer:\n", + " dog_breeds = reader.readlines()\n", + " writer.writelines(reversed(dog_breeds))" + ] + }, + { + "cell_type": "markdown", + "id": "b8cbaa67", + "metadata": {}, + "source": [ + "### Working With Bytes" + ] + }, + { + "cell_type": "markdown", + "id": "6392c296", + "metadata": {}, + "source": [ + "Sometimes, you may need to work with files using byte strings. This is done by adding the `'b'` character to the mode argument. All of the same methods for the file object apply. However, each of the methods expect and return a bytes object instead:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "f80e42a6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "b'this is line 1\\n'\n" + ] + } + ], + "source": [ + "with open('myfile.txt', 'rb') as reader:\n", + " print(reader.readline())" + ] + }, + { + "cell_type": "markdown", + "id": "ee0a2bab", + "metadata": {}, + "source": [ + "Opening a text file using the `b` flag isn’t that interesting. Let’s say we have this picture of python logo (`python.png`):" + ] + }, + { + "cell_type": "markdown", + "id": "725100d2", + "metadata": {}, + "source": [ + "\"python\"" + ] + }, + { + "cell_type": "markdown", + "id": "c07d42f3", + "metadata": {}, + "source": [ + "You can actually open that file in Python and examine the contents! Since the `.png` file format is well defined, the header of the file is 8 bytes broken up like this:" + ] + }, + { + "cell_type": "markdown", + "id": "f75bcca6", + "metadata": {}, + "source": [ + "|Value\t|Interpretation|\n", + "|:--|:--|\n", + "|`0x89`\t|A “magic” number to indicate that this is the start of a PNG|\n", + "|`0x50 0x4E 0x47`\t|PNG in ASCII|\n", + "|`0x0D 0x0A`\t|A DOS style line ending `\\r\\n`|\n", + "|`0x1A`\t|A DOS style EOF character|\n", + "|`0x0A`\t|A Unix style line ending `\\n`|" + ] + }, + { + "cell_type": "markdown", + "id": "5d7e78f0", + "metadata": {}, + "source": [ + "Sure enough, when you open the file and read these bytes individually, you can see that this is indeed a `.png` header file:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d8eb4d7a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "b'\\x89'\n", + "b'PNG'\n", + "b'\\r\\n'\n", + "b'\\x1a'\n", + "b'\\n'\n" + ] + } + ], + "source": [ + "with open('./images/python.png', 'rb') as byte_reader:\n", + " print(byte_reader.read(1))\n", + " print(byte_reader.read(3))\n", + " print(byte_reader.read(2))\n", + " print(byte_reader.read(1))\n", + " print(byte_reader.read(1))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/02. Object Oriented Programming/images/fileformat.webp b/python/02. Object Oriented Programming/images/fileformat.webp new file mode 100644 index 0000000000000000000000000000000000000000..f15eda34b5a57d6fbdce33f57c9dec2b06fe646e GIT binary patch literal 3022 zcmZ{k_dnE+1IOPIAu}N(dmNuQ5<2sU6D}*`V~5VXlPw~$LiWfw`%rdvS9E8V5xQ*7 zIZi4wWMtg;^L>1O`Tp?zJ|C|iUeABvX>I_64O|8QYdsxPE7RNXcmI5_>9a(3t`~Fd zC~?J;M-fy@X)%`zyNU}Qro%LDHg!A>_8l#YF9f`)W5cr)UH&(y`SyP=fYt_j&I36d zJsmraBkl0C1P03^2%(n)MsX=w1W-L4oWHXl^$HF_6xyYlRRx->CWsqkz{Z9jh;1Ko zg%?JXZ6p(D@KvaNs#*jl=1!kmx&-^(3H|vSFds2#|DuZ3jkjY{@p9ZY?#iv779X zIeRtNvnT)Sh@!_=PwppJ+&fRvKii)&#Pt({@YOXoEZ-RYQS(*@l%SaR|KSOx^21+# zCMN5x7Lgy47O%@3sqXVGOP5VO-{JDCKBx8)i$;sKgm}Qb&es6w?85=1m=V=V(A1>0;rCZ++~FO@qeG z{-d=xNH4Qn#OC+bCaXFtre8gT)E$vP&8Z%uzeU4ZQ%a0rmj5EbN^oUjgL z|3ELU(i~xK3UIz1rjaVhK-juuzAZ)S1iUrNsXI9H zA|3KFhZ@&>xh{Rdvm_Kj75GztEeUYc(h2Ok30-1WN_UPs*4=;F%PcC`;6T{CPlra@ zRu0tW!0J_7?@eM;%_s%AY>YZQ@eyh;VfcgCEmL?5d4{c5k zN%#=sTcg*PUL(9(S&ah-<`E+h>!y1(f#suS&=(8ek98##`OCa2WT;siTPve#7CB`l zY7FCH(?NBNBMkuy{NcfGYdBjHt_|(q%UOu0NU_{kvYODG;WkRjiXL-w==R-Ey=C;7 z!4k$;x6Kh7oaACn_Jj5=RHy%D?F?O`0~$|DTuPLy39IuLqR8g#tc|`*l&}OcO<SGU%VPWXnoaE!R)*G_#u&ef2SN z8i%py7w`iOJ#=%`i-lxA(9FoFq0i?P)6tIPZy4Ib`b&yHWq}(srFr?Lr&8yf)I@4u zFC-TA<*ctA+G{K)Xzssx zdv{NyxNBvRRX+s2-fgBuw_v*oJKxvF%jOr_wU){S`H8P>5yc;r`E(0mEGR@Y8xE6W zXC)H$zT?sm7IELk#uIP71{n(KkeixI&`^(_p1#85x*PZCH=|JT)h}5p!r}TE^PX)% z^k0riVk%Cxqn-pFaxP?X>W88NjS5&a;Eq;16HwgA9MvZWj7K;+Fo1!mS@Ct6p=B2; z>y8(JHp{zZ>w!5|~OVrwoNGbOx<8lN4)Wzxeg?q%Bz zuz4ZMu`;=FU$b9Y+8`|K{WkF16M8*^K0e2pPN;O!X)-Cyzt=*y>uiXt14IjN(}wqT47BgGPrzuRcLnhjj6oIOEFLO+WE(x?4F*y6XY2 znG4j#$$2#ma@RAvSm1ttkHnN5#8|f|W5S@#f)1K;DR5&0>Dpg@RoY&60;6AVMFnRX ze$@JeZuVKM+3~?o7_+WY3e<&vfO6VH{R{?GwPRhI&ukubo=(^PZkx(hXAm4;1S1@A z`0C?{m0zpKyKu!{d;V<9dv$DI0-WNdDZ(I1i(s5Co=17h6N%gDFAfSn-TZtIPeh~p zLXt} z89(r2ETViZzV8-iOL$p?Tt}%7Ple$&Z6q%naJs3776(>c4(NBf5>d|Giv!h0lFgsq9B2E!~ah(5fpk6-=jn zet41)v}8`U*p*_gfa{!lVp==`(e`QUbRj%g{{TMvm{+4gHn$;l0v_*}dB z@TSnwhM!W$t!VcNW&iZ;qx*2(zPyEB6|e1bFdXF8DJcia>*gA-9?!PXf3n1)s4(f& z@Fz{HfhzFXO|QWIDh0=3w@Z9F%ihfGj=nT(wo7btnJKuj>tGjD*Tj!|u}(7RTQD{k zLSiElQ078?JoSwaXOjnGkU!cgGJs{7=#JUb)2L>1> zmG@P=cE|1LB!N#qJ9uZ?5HOa@avha%N2w=l<4hx zNj=lbYFrSX>MN!tchU=m2;(*{Q@ttIHJJid3KY?L&0~b|=PivJ#0Jg6@bVjm#iC;jXvuH^VO9ier2~*QX|KlG#_b4a`)QT@Y21o0%BfxiOX=RZJ*~WU=v_@WxzJnEcw0B+Ze*=eVF=3Hs&(94Ma_!K6_N%<~8ogC3U33 zDcdg7FS8s4gFTzuj?4Afq{(#0x&}>(=YZc7$_CG~{ermFEkB?B%_qNa!%F|7*}^pvHpOGxT?I7e+T54l*$_VL!*#-<9#)kTAEP1O4ve&f_P M27T8pKMT(O4 z=8}0XGbi&roby}jqvt-)_h0zk*XtV2XMgry!+X8g+G}s!Ff!P)Xu-+_gpftLd;d5< z$UOLQ4w=Ub-_G;B`-2d!eP<3Gbv?RYU)93#tjtME$5W?eJkC17b3)X$Je*Ei*qwHj zICa|kjDyCSzVz%h5@#$m))*`9m)q~O>$J_8y%(HMAG~02$l`*Xg^J}GEzJe$9;z_G z+0(8kB|OgBJGiKNXsn^;RfV7NW7#zl)DTxYjWs)PL5ZXLjU;wCI-izMl-a(;LS8{x zLP$c4jTjk`p%gU+9%5U2uC$B1}qADjZ@$0`enhPY9rjJtx2qqDWFyo!p7tlU=Fty{Oih%GLj4z4FXwm7(~#VKaz_~W#T zh4UFF*E5a|5;*6{Q;z3dHP)<=#YJR)tpe)F{;MDS@~?$XJAhf7L4OI|SE__a5Zym^ z9P$WdHT-!!Y%F;FxKyv7jeK;CUh(D!|45(Mm;cYA1+mKy4!zBjco@9S%xKrc_Voif z_V-1Scxo2*M4g)fi@cvwlo|RjiuT;`1{W`nn z?UvVnXqWic%JbY_=ltyRAH>C$sdUh@Tzs_T{MXf8aJ6vlzR2ziq1^fZ{TKbaviAj0 z%VERAN=dp_S|cC7>9%Win5%r9nplz?Fg@(z;}A7ABsg7t!FuAG7DmCaG`_%`7u#*6 z8NuJ)$6?bS@?D!4-5}#<8WQIJJ%ZTpZaM5bLnqt0{BrXXeNx@6^wvnyDVP!dyGu z*Nw-_HZ8`86q}vXtuyQG^jOx#S7QfnMQ{DH+(dK3y!yH|3GZO>%|Y`CVa$JuGm^3A z-B#Q4?Zrd~o2KNepWk-f$K}`-;LI4}hKKxt_?0YuKK6*dyFCV znrB~rWC9Y0QMu_|Udcq+>p zmL;6nwiq7rMB@veiJ&8=R7Z<@_Y8Vgn)YG%^YEX9JH>be~G zQjO;&2#L9P#L-J)SMnq zrYa{nfBH{+ILG+<_CfDE#;p>ZmOp}eJ7VCuF?(NPrFeDbPe~yQHF(1OLc#EEYl|`a zmhOX=`&wVu1 zR$O?8c*KIEeVffUuL3_u7E==C)?eJk(dxdqP%buksQEeL=j(GYzLtU=jeo@?kHwEu zfrx82ef&z(7lw}vR=|(Vi>V1rioS>k85O_>MDQ_w{j&8cn+PgLw8~bg6$6Pi5AG~ z_~16^Ag4~Lx%O#nNR6xcM7FuDYv5Y*;0 zs4aF%bo~ux-(iH}Nq@dcXRO)Y0vV3TU8PjG3a0Dwe*J@<Z;8UC=zBuD6PtFdNXm}Q6{OzrtzkjJ5oN%&_7ZCD z6F>&44VO6YB$G~mBXVmhf2hMNa@>^CZjmYN^mPqFoXTmQez}lyV(>_MFV5M#@X&dM zh~6*sXs2bQ)@$QNg!fN5H0QpOQg2oyOs zHGS_v@IcySPR(mwBCKGi`)H(OaN>gs=p|1vm3~I7!_#jk1~_{BY%bxK#jb`tp|YW% znD8$2GxJmTB6jIhwebiUQ9efg>)D4_mU{bM(GSkp5$Jx+PK*@8RVndk`%$4&`GcTK5ZT7ls-Rp4bh)(o$wWJdGcQ z-B|-4B`l=msFok+qZNhDe#A5TksN+BJF0&!^_c(5~=49 z1$EJv;iIS>XkD9Cm+54@+Ra~F((?pz7=<#ED1e}(bwGx{Wtx*H5nhL?P?RD!2?nC& zC4bXc=#+&xrj1ie-h)`t^EbeUO4|dxjd7~=w-9`C{(uQR_kJx?c4XglqtCU*E&QA&P<*=M5Q3t0xkkjxrqPEXwx}IH=*x6^eF>>0sMvZHq#Srek08%OJYptRBy(|)oT%Z zv}Ro2y@FbwA^Ro_2*Au7RCp)=V_1Ha3Py(;UP^XJ2Fr-fCDreWB}X8wpX!nTV3kl= zg$D@YR9ZY+2qh5vXyX46X^7!QIb$+5r8hgk65$_7&l0f)%g|b>*Dg|ena`Mx36d6T z1q=x0-h-%;nCW4qp{}e+^UbiLaK>BZh4A58T{L)gQezs&MYrSu4Cilf2UEr07k~%e zJE^Bo1U&G6nVUu@L6#w14m`7_xQ=Qh>;nRUATZy&at>fZ=-U=<`-cMXB!G3J3|?l8 zKI?9OE7|v{Uz~V+IpCii*KHMz7zwi64zH6tkb1pA%Z`1ZgHEGKS{>QGumj$^L3zph z6~tgb=sxFU*X1Pgd{%nnF`qbBh~Xef$`88^pHB+veL=-AV|m?P@S+adP;Nej13r%t zLBh{C3k%83pd1rZMM*?gKrLB)74r%VAEn%&Iwr ztdv3Jbjnrk>7=XLB)@SMMG4N4XP}3 zvX68^ds8gs851i~cN4rWXb%q=@|c$XW5(*}x2`E%_RC8^#<-J!IO6-fvGCnK`Ds2< zdq%$DEZK+Au5DTkkB9}Nt1d~QvYCHW2vb=(;)xjrR1hVK%BQ(|`>xd6`gcJnkx6@n z{9vHTSsTZOQcM3?v0tj;A?GRwUVpTIOp!p8J$=CWCr~ARe-uq_=LI`k z*&GOm$cXlU>9dEGZlN=n5)^W-KkI%P(7JQh+PPm`{UN+Uw;&36bLPX_(pU$$@^NnA z()u@tbZw=;%EC$rUn3)oZvl?=!aZChXq$*`$xA4}u)1ORoI_+SfMmNaKU$d0LjvU@ zTEn1fn0<ykXSe{A^{LQd;Ty@SB4p^PR@*- zK&UaUE+h@BoKZc64uHfqYI}R)DOB@8f7bOR%XT!EY8ufDPp?HE; zKjKheb{$ZlEuxR;4xv0oOQGP+1&b@@>vf63WcmNvyLtm5d;dpXA?LNQdZS3@C)P9_TCe2A%yW=`^9z_$3|xZrE)3WFi{Isp`pt|8RqT zO!^@GIS?4R+C2>{A6>Q@N*EusTEd>p@0@7KA!HS!PbU5ffTf>kbqPu^4e*#|{uRk2 zbhlBZj(^8}cu9CJ_3A$ARf>@0mLz}M!ex&lGcCRTafLxPK-x!6jSCXyWw1{7?@%sB z3ZuQMA2;^X6(L%QccrVp`vtny9Ku*bMF1Z_;E5Up2SfICEcixygZai)@QTif!%8o7 zkLUp}M;^vRRu#Pqv_FO~HM>A63H?H?8*cy{$c#cn>w$P1P?^Vq2WA|mCLI5; znUKp+S{Gr}gb5`#08xf{hVi(@U`%v25%`Kr!KXnUP*CLJqwhiRh!JoQ=ApQFX&fL8 zWsp0r2Lt*4#u(Lq2_|~$3becafeZXTe18#sDhb{vI!wxF+X3WxRw&QXJe+s&a2a^k zy9)$)6M}*)#SmvKehOw}TA(v&rzlmqaTylH^h+PdhEzyyiiRba0@4u22~y}-UkzNx zWG}=!;{*swXfIcwkxo%>-o(i*3UPAzNSxdc?I`yEsZMw;HH1pc79f_*WuB?Aw&x!e zplOg8@3ZdU)R@L#gjadC!d~NedjC7EF?MmBw`)f)kCvNVkDJ5A@fUYE?9s4v&%X9b z<{+1^{5qIh3`+z?B48=dd9d@nWd5b5iNQRcDMP_N!xD{Sl6BJQ*%D54m1gQiA@TK| z9*IzOZGgA>uOLK(MUailHiYpA%U-j3>TF}xed#?r^CTz1yvZ=_+I{Zc-{(1;Z77M0 ztGlw4oBs;#j3f3@iyC1CSy86Ka8vahZqDOjd+~5~nNLWmY*RR_x-#80{x_$1iGI+c zezM=VM1ZvDpw+HHvyeoN@N+JOr7Bfxsf@MeHI4m6e_d}bkoxw#THnl%T^(~7+Yf>% zn-x$(8^w?G=5GS5riU>CrRs8>@QP*EQQriwn7OamtcUOLCC-msB0P*_BYcSq{q*L+ zcP%GQ0;l?Wu=+?v{LwnYrsJ9H9gW%V?vFV*05?UkCV(SN5EH&sYB0&~7hnG^KZ?(V z^};+KzAu{E@S}S~(0Rl;H_#8tF2eaz9JEzVBKd7}1qhP%rPS5b&o zm|0&L3B=@mzj$um3^+pJU~~)fOMRA0iYf1SNJO0g;V;ukTgRXnOjr{K>psEt;T?YB`Q_}3@b2DJ@1Hu2lOYiugKtF&h;}x$iZu12$zi2$U0Kr+vSD+p zSM8!#tDGh@5(rbSr?voVAp~kWTEAXa$&|D16uk4jcvF?jgriS*%Bu$HRda2!ZvmAm zP&`F#%Y9$QIv}C=W`Nl6&ckmDT__X@_};E_?`?G?DQkO$0n23{!dm0w zV_1{9_dgkk+2PeYelL{$aF0v(_`R|}X{=1T%O7ssb4Zs%}%b|Il3d9!MA+MKm79 zH+;S$n;r5(YwC2Dw6+&Ag|7-_Bb~!an{mZuvzi9zN8CV z(VsE%2#e|F--OBW0c09&IyLMN_(_+&{VK;O@V%BV%+$Pids)Mr1ghqt_FCHV|4DMp zC;wMB9%rDPtg#kO=&W+g&Kl^ZaC|UiX4^tJht9if$UoI3Dt80J(=qIVYLn)O>(kM` zO{@5X|9VlS^|?nVzBMz%6igM>_HTOaywilKi;)jyjIBTDNn3)U6VH+5sFq%A>8Tkz zExz#N0ntan1;O<5oB2lj3h6WHoCoRI?EPJPnKnV3S_SJY*P)-c?66SiAID5j>x@lP z33+l*l~4Z>dbUC+qWF2s9=$zW3(_xkIH-ak0Hb|-xODRN0s4jzef=I31wx1Ki2ut6 zC0qgR5Nm_ow@OXM1l5}%_y;q^XU+rt$*h_yyeNCNF5)JPOp5t!p#C*<-jMIwwOMXM z#w4Fu8<6b8cSD~?;^sanuFE1beoB^Z0zkZZh>2I--GQoixd0%huRUCzImzet zX*-FuUJIN;)oZLqN9;5+$6r82m(K~dOmGFT4*4-x0tG0FFCs;4Q?Z%&~6)LZM4qDJqjALfW7W-oG)9PEc({a*%x zg_?m;GX}yO+u=K4_ko(5$NJLgM&luKI=cxa+OUdG+JbFY8ak04;%HuvbtEHf>OdDv z;~W34p__+49Pf_4qW`nWSapG%jziPCkdmBDzXHM;YdmU`%PgUm{|(Als5@N+g6714 z-r%4Ieq6qZ*{Rd$*FZn6z{D_z`ONizspU>!Yep8D4>oyyfhF86y$FRu*-+_KJi;z{ z^s(&H$HC7tTxKrU&x|I7|WsNYu{xWPPQZe+P62M5vfJM(s?sr=YwJY2Eornwg^V9 zwXo%6{f`5`KQef20!`;G38*M4sRNwG6Qm9|9G#lKs~_Cm{-x*;$Z==5 z{CluB=T3wyxH79E*1>8YY!M?Vflg2na|Otx{^C^mH0W^-^s_+dU%d7i9B#;C!>gAEEcAELNC~ZLZzG#4=++=K;=awU!kIYrT zqF3k~0J`uaQ_~ceo{#2jGa;rEoh1#|*a~?9rLA9#*}CD*`$SE8kiSwm16pmBl|Lc4 zzsF*;=^-?mbj_<_Q-@8LVv40txd%L|fFKEniQF1(yey@-|Gz10K`woE_tx_za z!0hVo)7N*BH$`oBN`u)m!CD5)Ig>L~g97EGs-e<~^oEI)#7S{phfs5ld6wH+NA|-A zEN>=9o74dsju97BLBmje#)I*1TIuCg96=HXI}0q{D8dZ*0Xr68|0gG4f6AXjh56&Y z#tdf-t?7J2zSpBupo^=FS-v2B@Eh7|r0lOX#5Xl*-$JiiHrJb4@Us6y>~97w%RY>8 z81+0hq{{#0GC!`R-vM?Q_+|2w?U)T>Uf8|sk7z3V$t5`1%bry7IvA$J-Uy|T!&lM1hWdi+nLC^fj%M%7 zw(<2l!QSI`TmI7Kd)~RQBcQtfnr9XB?Sc3RqqI0Qkk2f?$lCXKn70^m&S2cZ3{HPFZ!Kw){ ze$`Q-l^sgubm@ozwyb6mR9~LGBIdHI=8gwq3WvHA!*-0%+^fCF6qHQGmIX5vn^z1; zY8#3%MrCciJ=IA{@yEp{j7QIYo)_?WISH~6x?r6L`cQGx3*D3LQgV_2cuQcwGWpR~ z@TiHxQDbh#*WsTB4IlcEK>4s5#zm+&2o z>`IOpEmZxy$9k{@=1zqswLQGhi9w>%e}?Vk&1ltbM6rg0P|R1Jj{sS^u^y!D7yzjE$H9__8{b$m7p zr656`1Dn$X(U7@8uv80dozq?aejF6oB=zP!ls9FI8DD?EW2Ouy7+)nwDjMk{-{bZ6 z2rrN#G*_@~#MUsVmgf-d5Hz&!1{jieeyXIQZ1L3}QS|XVm_p1N_UlJs$BK0aY_DOQ z@UBe7;3FKKJ8c@WEtgiSVWywQv~fmxu2J#?R6zf}2W*HcZ!6Y$zk<;AP*3!s$p|g{ z4w$AhDhaC?^+#w|;jXxx<6FXbgaz|5KFz(#sy5C(04AtaMK1G2n=uBQWnj^ZTNPKQ zqzX=#Jlwa3Tv*@6QDcS|8~>^?sE#;If4K5wIL;*=uvOUIMU%)J!K= zt^Z;S54EsO!A%m>O2WB_w*Wqq|6+Ps#axw7&c|=R_IzgXIbsu*^DDCp??#w!sWPQc zKn24LQpGmJJf8D3PS%YYS8`Tdhg? zhSN|B)273)Bk=bnPX}MRBavI}y`Gz-;(0ynkSPX`V;gV^qY&F&S5#i)az)OxzerO7 zY9P#K=u4Z&u@3DmjqBtjp=(h@5%X|EilN2{SoMo|#|4oxh|_SKQ0GOw zpo+TU)o5N4WK_TeLm!sT4rRP)Mg^8{|be&r53oAP#%z_GMcM(L`59+;k zN(MZXja-$%=F=$v&1Wl37ACpprbmuKtsVj$dnR6xBf{sX8Zz05pHXVFYyN*WQdY57 zq!vQI^7YY*;saR0eWVh|2T;pk5WDIT9cJ^Jnezmy4P}ek=$rtpZPRe1eH!}da_10a zI;K*%MIq*`kb)b>OO#w}tYTdQ?_@$rd#}j=vO>MRW7JAG6Q|<$PuNSXKei!+n`RxZ zsve*P6Ba@9XIb$%s5u>{<7HdhgbbDya}i%(;|n1b;F7;EMmtTmtRgfeuxsHMXMAG% znwC%2=j{w^g-}yKiF=K0$3xcIsbXL+#qy3e2TuU8YG!C)JuWjnMGt^Cw;Va2l!|vsV9!dsOWAhsVWr-K+!j5M3$xC5cX{`ef7A8Hd|G)e zd(uOJiG|fyt!WGYRv;~ZP{$eg0JyKcC7X|U@W0SyU&C667x71X1F(i8GNv3R7{gWJ z1CQWr@<9y{44ip%VB=jlP)d&v0QF*Ql5@Wdt~-$2>UWLSve4pv0>8+qst!zw!%TOr zzBOd_O@?MC2`U-c zo(O*a9mft*WJ~lVLaJf0C>#k#R=232hH3xUlnfuW=ztoLn`Hr1q+lSJAI|@g6t8&9 zK-FXvicmj_?R4q9eM@mpj5pFLg!97**0CE9=1^bL5>p;8f)+5!UeHhJ<2vrkOMK_z zz|}pOY&fR^3@{8SRj5zD550zVA8mO2B`$m^I0mu@KWC@5)V5ST1TRFj8$_O?T_ z{D_&)tkTTi;-HwrBV}d`dP-eWRtvtZFRj753z{fJv;44`H@2lfg)dtkf-CyZpn`Yu zZUHtJ`P)q4hyvX(HuV!M&49F0>TFNTikIik%INau2JqBx1UFR`Oza9 zkUzHPpQ=IieHoA}o?^1ti@%O`AMb*1K(9$?RO+fkdZkxQ;;ci~ep~@KmqfF(8V@Y# zSp{OJS|`Vf>^?^#F+njJlGs223`4JIR~Uq!oS?E55*|z&4h0L<7FmygVD_f=0IZlD zi7-%F4<@5s!_4yf0OkI*b~p*`HQJX|uQw~$o339a&wA`zGE0uN;S5pAtN6&WC>WT) zgKdD|*%Adyn9pS33 zE73s*=5L-~&~W+0j{%!M17AK}y*o?tH^jv=U)pMcj&##{}%{ZS3 z>9(~gvHresGIYv|1N0SG;uT@GfsZ)R5YOSIB6w?oRVi)_(KK=je(v|ChvG4*_L+AF z1cvWM#g0*~Qd@TJYJM%&V!r15~ zyM`^P#!a5_0k9Y`Q!OkaeKYHb!lX&Du!>vjLe9it--|;d8nHZt@j*=;WNQ2{+sh;$v)89;D&E@^AKXFe!#jm5%U4b!ab9+=`yjmSQc zJ*UnjRY{Q168a*r3@rkc^)BfwFUr3z{JEErS?2O=@zNN-oZv(yjbT3G_N1mW_bBIr z?@0WfPg0i|Jv}q>9NGB1kr8&Qs`T3cRDa>OfU(!R2%{VJ?PPpS9_Qfvk9$ndS+R

;-6lig^Mb$SS%8^Ya98Xv zO)cK)&TSSxnOd*dLm`P@&z1eg`eKPuJ@pyBG#`Y8!2sV`0@b%~9L)PspDrajBuGSq zvaF;^M6*{}`!%uc=Ow(U2??9K+uhmKw!IbnTg>{6L_R{avg7-#_?U%*&EiD*uSE8U zaF6+&+Xf0UoF9J_y%MmJ+Hr5c&fj3y1X*gdEGV^d?d8mKy$wtKCi%#M==ho&3;XJ? zyEtwU;btaf3N1cZvzTZr&gi%S-WMygBVKpfDYoR%C*x9G+3p%}Sz$p>{%_6J^l@YP zvh?6Ep4|!%2`*dF4(p{rBJU3aoMnyg+zmg~Bq~LDKD!qN`<=BHiw%xXmb^V$%ep-# zWRRnmem`u^?(ZwXbLPs(983K;F$p@nUM<#~pISNawg+6L2rS#%XEi;XPG5R3>ekn9 zomL&%i^l~P5Y|F4c;u)k$MDY)QQJ@DUNJw)CYo+TSg7%l=KEnPK59Or*XX~;OjRWv zlnAjylw)KzkJA^}0J3~0t+R!!a~q4GtgSv+tfS;J{PRvrUK6|e3@LB01kH^!Fvk7N zp3q7%z1HCPjyO7rEX$p&YWY`n?ql9i2aQ61gBaO?{Ch75DE=s;dn(~O0GDR%Z6Xb+ z!(n#vifKV%+$-RQ5@D&J=)EBNYJTyvIi>76`ptV5dtO5&BTygQlF~x=8FTz6z9!$` z(&ctEk0Ap4e8=bAW&1-_mut-=HQj1|tmC$TXg_*t1psr?vlM$~@j1}+ewSaLs7~5Smz)@^ z#v`4ww9YK#lrIJSeXq~o_LA8aT6^2YlLR1kd=!}JL$ zf^;4G5r#jD{`x#PV6pt&h8;7gry++mcB<266Idm(U+03-ZSw4Lz$-A^=uNbqabrR= za}kV-9?BNE7-xm*o#B65t3%2!q4zYyI z&4vVX10?JU8V)Uq*|RBJza&ye9RTZb9$YMQvE$KVa(JW>DB?S79*LYr@>6wwvxYAh z?td^chb-qbtCEej>S~Zxwa`m`Ss|;mH4umiW4`2>T+?ALhA}c-c|pvcjegedMi+s* z2cooAjP;8Xnm8r!p?lxD$**Cz#Sc}x!;o`b(|tPTFM=TwjE))V5Tn)C_QY5jSnVOC zjhe5xi$!9g^*R|RtXf-80`|)Q=gMTbtX1O~Eu#SG0D#nPQ08J>JpbLxG4FHY+8RK{ zTcDzq9gQX>C5+6i;gDzokwlF|BE+ISl+!PFKLX+c9xcQv!(5~sb3ZlPy798EP<)4h z?n%Mx$4~lbG4S^B@y0r8T1CY);g4|uAJ&xt7MLP~GS-BH8>uL-vdz82u~b*%A(54j zZaYkO)`{;ij0y?kjxTUGCbTLXY9bu=NJVt9RFc}Wr{bJ^k8OgAuN45C@w0UExrAY? zNQwIp#TD}7Sexr-x^KMdmyE;4%YmswHGI_6c+7IXe|^4!#|{3-1m{gt4qK%?g6Rcm znFSwZwN6FdlCQV5wr0MNI|W3a0}gt23#5*X?l4*_x*KiLn*8Rt8-WFh)VkBo?MJ<7VaqtDDe{lwbG2{$cZNf?0921ZQkCv$$e-&Dih}D#dY|F_awdGP?KX!P$si&s;0>ci zSVD|6K1W5}x<05Wyh#wtJoiABzF zR#O~Av z8Vjh%SX4HpFWbGK4hp~DE2~(_a~WG#lnTJM^*t>4Y@@s6Ydc^d{ZQ2hVO)f%8M5+( zZ@7+<8jsrt_v6s@L=?uZEER~%pjaO4zyo$@DN^dS1gU22MMLGV76E&;wfzKkxuD`T zoeaudz688@3F&7XC)%hQyh_{Ca|*m-2B8GS3BcH3{1y1-E(XT#UL8y04A>MK8Dfwd zFv9vz2oaCfsLD-LMM@BG(fu5v3YeJ1?{SZcR%&j&iD83JAM;lP8kIiQ30>u-fM}I8 z;EJ4c9HyR~U$LczEAZQ==N4bp%Mqm#y5>ns;pDPrMgMUqOj>Fd5$!}|h{G;xz!j=3 zs7tNO0q_7f3hx`RT5?+XgUFp7Nu&g9hGdv6c zvIDICmk3(@W-&hGcVGP)dEZx5%^$3;y(6^O{0?RH@V5T{;QcrSEwHeWCVJTbY@q$G z(S|6?=bT2%-$?(>^9-Qxv=o?7&N}-Xz%@M2-JCQ-djpKF0!Dua4qjfo>o$hW0;^{g ze&3G(+l1%*J4$bs!FXy`1r~myi{f%wmS@f@sBx`X^TQWh`HC`iDusuB-Z`?-5bT)A z0lCu8zRmR1%EPikFq2)m_{|}beC|BFVJFk~EFNEqOD&}O+ z&eanF{6zge4!r;(z`n!Djjs)8mH9rLE%2 zKWYUoFHIaQ+ykiCx%T3#*hnYd*AS1VP#HZtgpRc0fl&R}|Mkc$7c#7sKeuoiT1s93Q)9hY!jJ{T%7cG3Env>T8bq6%Gixun zykB&mo!{XYb>F?xk(9d1sP0xuUEwLgnVR{8=>nzxR+Sm_!}wN^mPDXv1@@F5VAf?J zONsPSDPp88g@XS;G!!5~{}5ThDu(C?Z|S}4W`EXQkTq1_RPw@hd)jPP?pS2WM@Y^| z6bhMI8#u8Uctkq+vd>g@e1|dLq~{^HAS^9x{O_u^xT>&bZ2>j!}uT#qx-VtG4UkdI^g-|(aqEW5%`~+MIgzG|cU6rwn<3*x;+4xx?avZ}2HzQm` zeOGQBhZkX)O`Q?}j7ei>}WLVW}^lT6(W`u`R6s|MI)C#a&xfOuo z+sgH8bvqF9U*#VsHSAa6V(u~>E!f-i5p0-28Csaa)k;bLAU<-XZJb`<@WdTxM6+~* zC(-@`VX|(Us$$EvMQ)Z@A#)LrtAg!)qT|*pNy5X)N2`qWj3lpNGCxHrZG+3YP!R}` zan#ePf6suR8aqOxU2pzPOF)u(Iv4qDjpn|$6mmr#he!L|iTxf^T5JB9sLM8(I38>F zr0=8~w>KW160}et8!n^dbc};jo|d>NwL3N#PT0FACsl=R-0@zxkcXgUHcb3^S;!fY z@QwAu#QtnYeMn;!>xs8aMcV?hp#3%r(nka$RR@r|ECSsU^xBWpcgA%QZ1Q3MH@wZ6 zcT4{=cuKT2aamso0qJC@JSf(&5~?~C6*lx+V@NGah@LF{TTB}lweUM%gJOP5B_r>P z@fWwCd2SX~J@}^S1xnOfA3V#p|5Ji8k2gwL!*9t4BOwt1?AHZ5a`ybe@3k-F;*Zkh zySIXsp&|8*+Jf0n2fbhT4%E3RHT07+FYiqfee#j#$K@UiVqltLOnRqV^7zd@{|+j_ zHHj@TSu;&lERVf~S@JTEX};}Tk?oXoftR%hsEMMI8g7H{>3f-h>!6I@&+k@QiXAB+~l_i(HZ(c z!EKgr=NZ?AuO(S7bIIJTcOikaVxG~naJ9`1;m`Pz0RCF`q0O!^@oS0J@{3TUsa;y> z^nb<{w8HiyrwZx=Xh+qWns^Btcl23W|MABs3g@=W4NI5Z7yu!#79jVxPOHVAmLl45 zzqfUAqzu%c`2%Ox3qE;>5!)gdARPcKdb4ys+@0?EabM($@}$;}0I!;m+YWBLiYH-! z_F{|(qZQDk09rD#6EAAI(Ua0^ZS8G!%4Q3Qx58}^$&tt0)k-l`>mLxj#4rUo{i)XR zqLT5yWjg6gwWe>~Nm9t7rB*-{&u2>oWVpv# z;Ec}{d)@$LwBNfXrw@FLD9WjHQ&MYND9S0_(Q{^5PXw3kS&4r~=I4VxXDt(y0GYPY zfPkTgnm6zB<)ly54{$`^JU%kORspR009N3?>ib=SLJKGQ=}+9h!QR_x0h#+>RrF4R zTk1F&M!%YWwW%I$Iz=+ehk`EVaRP8JPAn;uKspDPRM|pS(cZFb;yc|iN+f0#N3gtp zmS4%;k1&>@2dNCbW+FZKk#qezbcbwIuZBsky(pNpwD|_|lSG~)ZiQHPHxZ9lnDpk5 zXK#Q3WX#?zu5xTBHSm0u)RY>4%yl;xzDO@bj+X4QcW;@FzH_Q=M`E9ncvpifpW5@Q zGZRtDR8A9xI3$O5{!&6OZ7On=)_DGL`!{Me8)Uc1AF6*b{~2GEp^*f|1o#)4k(*)b zZe%|jwTDWkN4m$~-utlyuPTWz5&xSevaNyJy3JqSPMEl{u=_{ar3F=>I+onODNlC#d zqYJPF!&tM~XD8S)__pn+NkfrAjRN%CfM5>6c3|`{ObIEGf@1&*()M*ozq9nVI&AP;3ZE2h`-e4LWiBMLiCJs=g%iZ74Np zFCqoDVP9%`b0Mc356fOE^3%YrBX9fq5Mvar}ZHD;giBgVRIIzMFppisir&pYB7dFRfyeuAI zmns0X#`Xw7^&bsgBj{*{gmG~+0bR--vo_HU7wzG+?&qjxw{f_HASxr}- zf6akDacK!WmHr*$j~|-_)ux7G{yN^ybJDy@HU!|zBiZzsob0jnobX4&$8Rg-Il}Jr z)yTGKpgIN><$;aRG;-taR{^)#t4~%4H8TAA?=GtjhKe~AM1gI=x?SeLneo8lwrxT`Q7O*LM)s!ZV$PqC5Q;f~Sx`o{K%Sipfz-Rb;i1S7aIjw}t zmWhAx#mKZkVYG|jSrR9;`>~c&Bz6nI4wMTN-+t}=gaB|mw*~eU-aG=8*o_8Jy`UpV z60U&=jGZF5%Wxpi9?fF>R&+%%Ygyz|psW_`!zj?2h85KyxJWtvlNm;?$a#n5(^Hp2 zMUkgdw`;ycDTHlHeLn2D6XH>;&!Xy5GuAB?UJvy$YuwjHi5c){_M#IG~ zez%M{tB;7K8jF0!_BdhS79Gmj5qL9*?F5}6i8X6V#IjdG^J2783*K6T0AToI0^!pN zp0ySOPIi1zH=ufG>q29na;}~wR6NuDvYLKzXC14#-$7HM1$uJwWp=)h){U0UF7^F0 zJ#wDwEy%gF833x!AD082Q)uV2;7?+S8%0Es4CEm}pRFB# zFKlLlo6n`uHP&CP%=iiLFgifVH`fJNqQrbsIypJ>{6dzj;0(wSi#t-_DL~ukK}g-e zu<~VNa=3es?+RQD%WuTWhDcw(?Uwfut`v?as-cge-~v+(KR`p~PzW1h^Rl!9@!J2K1?sbyJ~ozgkL4z!)6B)shiH@;caPf^t1x%7>j2W zqY2{hxOpAg!{|cTS@*REWgv8>o26W8R$P&TaWPG);xMsaKY)aI>_)!?HWu&*F52+$ zma)Spo%DdPd;dUqL1>kVO)81-s>2B4MLDUN6wAEIp_CCQ?+~B710A{!2mGP^EUHc+pT`;Ft?EBCqR5z=mXuTrLCBvQ6>&fHtfB;tYJe*=C(hom<}dPZa#iBYgaTTieDRbBQ|k_Mw9seB$_~8D)gRue?Kv(>!-p%@vDVY8Edu zjX5>;;-C*WE`#&^lw0m56*zXrvg*+yjyFydNHsxtIS*j76*oQjCv0EeLkW<0xa?#B zpdHSuzNgYj^_BFWSauObD|m+_0?x+*jBSE(yyBhQcHIZN*tjDdy5UxT(Hu z4Fk2;1p>E^^++w&)WnuWRb;ey$p1wK3@C;Q4XW=! zWZ*}Hd_?gyOcr=WT-IZ?6uH}mIGX=!lppFUiQHQ7Vc<%J(bqon zm^96x?0~TTLy)+c?@i7@V}s;V;w+0HPG10#JN*nXFF$+RgPnuf{X*|)J|lrm+1`O+ z+QqmlmhuM9`w5ar!U;2Wqke79#~-qwu|J=PzWHYnfj%YL6l*h(g4!b-xaqM>t>Qe8 zG`9MDOMzMjS{&)3#aCDJ6U(Eu%Kp%utj8+Wnd;}AlZD2VblJzFv5t_P+&&1Qv#*-y zz+|7`YR0dke)$+QHm=>?lU-mCsdLkHnp4w~Vgd069eCTbXOeKMIJ@7EJkXoQ&ESD@ zXIXo}4QN5b*=rCW^lfF=c4+7-fa_ea2S2NHz4>Q9`?Kj&p_l)B(!!C&(?QsCI?mDt z)yNTD{#2>~M*ZIPeshH)#}Jy(ix;2kjcXIO{k=sJPUsb&fhUor#iMncu5&KWn+>AC{NvC_q!Ff1`c&kJ>pkm5;W#4a+?YAuPodgJ zBsONAqt(H)yT=vWs3Mq0`;z@TZpIJ%v%PW(gX?`h(e{MG9Hu4>`ZLqN_5ig&?qA_L zi5s{2fFt@=3>Yd>fBO1+KVg#4^xBY&vpY|16PYmn4cd`#jRLl~QQ&NAQsHhg@FXn9~% zv%)l!Q-H2Vw?hNqpOWZEpNfYT46|d#6e{Jrc=#eMqGgo;{bXAF**9t%BD~r~+z)8N zIg&h}K~86g7`Z@F)UFwqzr3pOf@w&1K`J*5S|XE=R6fE#s*>|yyBAvicnHKcvSlE4 zvo^fqqRE~PC35m_+?pfi6IRg)N6ta@|1;ae*Vt&kv>;!YKw{MDFP%f&a^ZSH@rU6j z|EjUkr>OZf>g#{*(I?OpY7##7JGi5^`K)NZ0i#qQh>xJV4-7`}swGn`^h2L2IqZ>3 z^!93zF~MmCE=Cykw=CoY;SYnLc4^(S$jv^gL02U?th>uzd^%(tJk9vg?JDw$MB4a5 zTM_LX_zHRsGLY$#mOf+L=gHz`;)#U)z7Xg;^`C}B1APRFsXosq8G%^W&+$03_Ttq| z#K;n^A3=B)wqqyU8*R5jrSk4WVDQloJIvQXiJHnycDK(V3qBteo9#e#nL!jmoQsZs zG>x@x`5G_4N&-F-wq3=#&jZSyPrH5eObQ&iE`$)i{Yyk|__^=2l948y+UeslU{3o_ z`hrfF>Ob9T&!kIW@uSE2-49**eWG0MZiEa9!2ZC z@ZV{+peX>6sZ-3bZkCyKx)&`%v3$__cXHD<>YML)d}|Xebnj^nRr_mtmaX ztj)8;5j&fnQxShT?-wJ#Ek=uYQbXV*W(7aS(}J^STHq)`{Wb_RJ3x1fzF`R}hgaS% z_^Pq6429MqDV5J|j0hvJB;*RXk4aI>&|1Fqt&VfFcPx4fyg--=^=DH~MSUwOVZ;Rg&oojbVN=x!9_<}a zp;N;)pM|3yX43yG6*o&D1^K|Lhs{gl@m#?=DAQ{*96;HgyfA3y#zTxmsraKTmYkff zLzW%D3l*Scj!w*qO;FPCsuu$dLnHd%fuUg9#lNIGSQI}78YZQ#6eQ!^2yPaF+W->u z*P78}MM7lVMk1P^^01zul$<@p8cOC#cWVHf>d)HLJ0G}gyJ|7)+Lt%o;9|&9&9PoY zu43OxvLF{schh>bHxVM?=`UWKJvlpI8WcW^v&~e_Kw;RtfH0FznD^na;7B9>nB)KS54I8APHN6b3_nXqai_b2B+hXTOMh94Ps&BkQ+oe*r1Jp)NLl4v< z+m``+MLlrQP-ApMHym!Q0*&|&gu$%TinhS9&-|dda@52NDrGTH0=ZZPO1iN%Kg^tYe@}Yba2rkourcPbTfAOV zj0*IOmz38;Ddp1Orosr+w>iK3?{)^*xG-B8jxp1}tI5EZBjg-^DhvS=saj`f&)+5=O%#WVG4qFHaz> zLlzIf)iK*NXmR6B00@tSU11JuW!Td{@$ys%Xpq$e=ijGb-a|E@e#Lp%)Ka$FB}8W@ zM{zbJQ97to$aC4VX3DB>So&PK%lJh zkHgn)or5g`EF3us{FpjEl#--CGu*6i=o8fNpE=L`>siHf?6N&yYkIA~bmd24>aL5k zXHrhRsQYYi3H}`%6oR5dK5A|_Tf+Vj&Yk@9*UeZiuNqFc*sX zx;NQ$;A1uivJ#80=_D891R|^(Xo7Je4LUUS7r&GM#XJjzy?7`m-Q9xHd}da2>bl87 z+}BVjo2;qr&7IgMz5-%{wOWw#Jk<-$_xUb}QzNej8!Ib8V5*D^UTjTj!W}r~m{yOBRgcpT`rnI6BFayxBMr z4|bZg@C-(jApV7@pIiN*GxoHEK1jCG{hP@^GH=fPSyZ>6_c25-0E)u~5TbyHE_aPT zr}Kp5J3vcM!(iA>%T%T8mWqs;Z*Xy(n z<>|G*=9WG?c{rN?c^kUM3549b-{4U=!VlC>0XreVOvbjFK~g_pu#U_IvJq6kwv86x z7<@bKYP)*+wciX(uQ>R4Y(~P{@uvLw^RKZF%kK^Z71*(ADO43f zVdCJxyPl^o>!a99NzEc5THmQ*zqrCY~pQebrsV+fDCP8SY6 ztdct1*$E+QC&#m}UGq;}S5J03Y>^A!k~OPhMuPItOc&U;L0Dx5s6uo%YHc?HTEPJK zaS30NO8G(-wgzf987uK6mpQ^_Q{!tr@sm5J_jgqsARpBra{}S^PbUH6$nTIj!fzN? z0gT7RF5=aW;=(hvoqB0Lv45I40&t@jz=?>{%LqBJ@0t}@!E`SGH)o8w=t0Z^Ms8+C zj#9g=zAGf2VSn#gI69CPMhKjV&__c8&Cmq1S1287t&xcvUjQn;y#o({CPWDlErOFb zF^Yyg{abono?mf3nh^Z*;O?quO}YFZ&```bZCNrq4t}}f& z?SWn9X~n>4T92|Eojc!#5x;l0zE}Jwn9;nOJvFm+daS||y#}*IJ%9c9nl0?sOY^X` z`F3}Lg3RF77p9|Y({k;9;|C;}sF=lS&1tQXSr^+mBEH@}gCEgfW^$>}%72e6v5b6Z zs(f_-q~9;cu&yGv+^F%*g|KKSc(kG8mDTdr8GO-vLrGK2vnv`4mo0EpA1{^kxw(o4 z%Cve~SGkCj?uxDan0lF{uQdx_v&?Lw`#&hysy14PqLatyxf0zq)e8lLu& z;VNb2uX>u~DPg8Q5EV4+;p&X*Yq$fLLt49|G@uZ~9RIGiGv(W2yKh5;VMFP3ScZYL zASmFo^$f%Q$F7Dx`wiW$A1yh|m4y%q*Z=UbBTH;kO)n+sZ+R!m4=(p+&2!iD8?eL^ zSRddtCt*ERB5kE(l8nn);Zb9=ZqDJh%0t)36=F(1#T7=22jYxJbWE-lT8)IN zkhWJ1`c}JL$L{9&_5bm$gc(3v9h9g~g^B#&M!qk8a{ik8>)Mg0rkuW-%N`00=mNmf zJ2-Qm=S-3Q;mG{Yr$40u=_o>30!S9YcA0QAxWew;O^@!%-6SJs`XAWrZe1J#uV~XYSWl_bzUx0J z{;|ZTZMaPSbH9vaB&Jb3G*m56;aOBmq>1ZI7<(r*F)4XVR@Rl>aZt-s^Id*pocjl@ z%OQ-{h5Rt4b@kPpPCVLIlClwxP4ZUe<8eU3v!^e>kM*v$!ToSdc~N|d4Ib8GN5P*0 zr>i;j7HQ6yp(g1Yo1wHeW}Ubf4&epvHav~s*%QLB>KouMp%~A{ z65&5V@l%L8p8pey>8V^28!@`sDVY*FJ)k>Q>r$2NKu-lGr#lz{C^)!;g%lxBE8rRw z$sweTo{g0Lkm~+==`~z%b*+2n{v;?5!4l&=J#mb2-g0C zdVZPqa43|?KaOV?xse@eBQ`+&Ozn0niKbhK9Z<2y>8njh(j%q)6so3-r@^J*xu0Omt*L4zjYxno05}NqRn0~wT=J?RU4KUWXw^BKf)Ih{c+o?3Fwzt!0AEq4ep#7W_&CQ zOE$2dBk_HWaya1#P*O!&Qncjn6NQo2< zt)@d`CJsLLZXGqR#`0bUSpJf`qOM8m&IGG$94r^Rt%B3#bhu8^B3NU6qDoXF5GDvO zqIfet7m3kOUm&!x{{ z(bpWn!}b{z?5(x<8fGJ&!*;;)&`?eve###J*$T23h`(eGUG`W60->$sovH#7LVOX+ z^N0DXp8InEkLfmF zqEp|D)Ng~-uf7+i>&fZqzu&9CF(_}AoIdzLt4Vy!!)#)1`QN|&+tfO^Zj z7ZKyHy7;Em4`JlYdHn-D$Coq(wK&4;=Zqa=I6OnPVCf@}fiwQ( zzT>{@%NI;#eTP^tnTuqD$l=!c4m?Q=66Lxq9qg1iJHy(8#saaP9jl(cmyS%!QF;LO zBU?~4KOsKgsY&+;QFmWP;ekRuHdb_5T?cA35#zjjay1R1b68T^f%qL-OQtX7@jMXN znLq-`-~H>7@4eLas@tX_qPZ_AF{ug!E!jYi@H2P7s~Q0gBcn&4oa&Ps`G5t)DAdi1 zbJPZ{!%{{biZ`>i)nOmy%!Z=wrpH?x-!$#eT+s4M%8zC2z&mzEGJ;zN1MuUtyiP|m z6u{0XiQ$j^s&_bYQ;|X1(9k>wzZ~HF925rUu*ZZTyq0q!?KjY>US=orgY$yAJIYrq ztbbApM;isk_MV;lu}U}B8##!lO%;zkQcTw20mN6wee zB2R9_w9=vjVX-ih89e9`4-#6I^lnQxR*fmFkRj$do1K=}NfRHG->d+qGr;OhKlZWB z;@grQ>9$ff$i29=AOrrQu&U?WD2IwhB)etwV|hu6gue%@HTckmVz;G)m4c*ec~^9K zX%yNIYk{xh7N2Vj1pZ%4&OHkN9Yx~x1^v9 zZ{XZbvw^uXRZ?5rM2{IveQkZe%-^sE!z~10##()IJ}OI-l7d8ORy;ru%S6OZLHeFo z%emjT9SR{2M;nUMp?s7yQ&Dzru!ptnSCvHIxE-F~dtn(Uau7j;x2p@x4>WVO;wsHH zec-b?ph_G-qEH(vIc&uVo1F#C61h7c8MD*^WtbTl8=UgwqQ3)TY2z)c&8yl{qwN9hM8uD!NCuIqcSX>Y)~ zn9@`~I~d5o);tpX^Mk(oDgdWLMGCTDj~(>(mneTnh|1qMbXAV|YyKbe8fxve7cdNB z?HwZ|nQq6o8c7LOyLZQ|hHRiK0<+}L_>|GRGIJcdN6Sp1w3L?_ylkY?x+gMZ#Y*^9 z*M2`?hnB%cnjt!awJ?KCY0gHnUO!TwfG9tzxjwRbp;PU$1+J>V_YQBLiAQt^`AFGk z(D5&8^3noW-yK#~MCA8+@AOocX$J)cW9wtTfOiXkm-U1iD(6-o0G)w2dt`e(Kp#e0 zfSlT>FxaQTAFDx|@o}6e-3_ej)5w5w`#U==LSF!`3mR&V-}ap%yeR%W^v1n=30J|W zsq9nXY7m$+)9!ITLSRf54FR4L$}IUF@bD}E*89A7>Ofg`mxvJWy)MT(ouJa1-uoiA z`EVSN3X^SMb3R!DCN_x5L&uIJ`pO9}Zqez!w?9G*rfT1s_OUou+icW)i-?RFre!m zdpJf;qBW(h{vFsf$i#aoT^S1Jl8g(wy&gMw{LNoz5E( zsXTcy=n6!=#||`2?>8p)X#a(MsyI@8cp>NGBaP7L<=3Vjy_4^9d}Yjtj-+XPFjaJ{ zLsPKU2&@XpC;ppfEYF?0j&xsu&m{1N*y8tmQIu9t-{mSDTng+C%W4`x(Ek4>!(WauC(WZW` z@Yk)pWBu#I!{>c~lESjyR7P+{ph?gpS}I8J*vaA$xEsQU;GLkZ?UMBuEI@_`YZ7(& zu4*a+m5)(@na8@s@Ie=2Z(a0j5-uO!7@nckCE2MBG8et+*lu^EG>EqM1grXi)IAA; zuo!U$pLPAQcE?k&$KEtJJp;hiEz|;4eY7lw!}iyJkNNlM@}I(_uPBW+bw6?$Z$2h5 zCG7Ix_!Mg8?xjAiVO7WA8%t>JBQJdTp#L5J89Y$Ff-40E1H7-a^`gW%rAPZ+(*rS( zCke}}u8aUfku2{0r2{55*Jnw=Pf>#K+;Za`Mp9d!zJ2t@@oPy~YZX8kY$r5h^s!V0b&zS^v$vwriRBEH=vMYh5Y1~dG+zN&3jK=PW}1X z!#8Vy|6B*EU(E4uit%Gwr2vyVqsr1k`#}JVbpmWUG_|0@?~_ijBY^cSOWC2%Q87-~ zOomx}kA5uTe=;A?Iw46E&q9!8L|4A;xmuD0zKunuxF1p*^PqN4FRMxXrX2*S;*3-Y zRMd{jsizhC<{@ccRNdG4Z&dSlTUdXAoM|t+CPmoiY9vhC>ZqLU5L8#31M--BJiO%0 zPtnYGkV0b@vpgSmad;}F5bQs91%wXC>P~IWa|9vC>FHVC8s!N!F{N3mu!tpb>O7Up zS97+5^`v;yDiSoKz;~o$)qx&k@$29SRY{ufJmH(;VyhSnlTT-&Q8`W(J_Ty~YBSRm zKr=v#%%zuN0K=p-PIU(WVQ8o?Ghu@D1(%Lddz8UD_aZ(eheAjir)#o{v%DQ@wR2_1 z+UB?4E|qcUC~G=qab|kk$uclE=b)Ss6oHlWbMZSEH5LeV@T8p`catdB4m8G1*m>OI z_g{>%JjA~6`qi9(6~zHiR8cxFD|h#Ky_esCQHW-7+1Ov3m@{pna-jGe=;rIFPI|vr zSn1d>-STdh$MvmJ#Nmd=^%tlBT}eyUm0Ps9VIJaL_+Zj`jeiX+)z{Z%0aP-C);BQi zzrJ#;@lkW_ZcZf7)9(}Fq@pLG=k~#$0g6_tP$hAO7YA%9L-Bjlw&J+P@@>R~>e-M>?GQQio2iIww6W|bX_n#((E1@7JQS;>>YeD$ASocz5gIL{38@VsT+$+ z{hK8Z2C3hDG;aOhL70r3_Wq&3@46s-Y;efL^MxMsTV$!OCee0kWKUJ(zff&Ni@l8! zh3q{}LB&Vsz0=i5YzELh3K{4Up+Z-}2J_*Yz#4E;!($$#-|HXtQ4s%7Ecw-FMlZ{= z$rz5#tvTNQNs1F;mnZcUAe;fN*9Ye|)#N<$`Hc(AzoSk6IhaGo``L zX3qjKLK7;p4BzG66bLP5B{_YL$^2Xc}1GC=)@%4MFyAb`kWFSz08FQFf_k)eJd zGcjos@>B1&3s^NyP?CKSjZvW&4De~z5i+~Tlb%; zEDJS;W=vj3IsHTYNXc+ZSsS|hpcLX-h&A=CA9!O(eCdLznl1MyHNEf+8rF)52>1~o zER##E?j2f!=C23m9RiL*a%zxNNv;K3iPNCpiN*LxuGKrMYW~HT@q*OI5UFtQ#Ka^% zN=WV)9EXMqg8;VFLUr&`znEPkkIqDapqPq2dUww;6ZB(ll6S~2iNG&pp(PL&eXb}p zkA``L%^=;(v-(BR&h<#du|VM{yebcL^i z^Ml^`n3mYa1VGnB_DfK+&JPAN{3K?fpTnXLbnd4ekK`#I-R<%XR0uhTrb3pVw!LnF%Vxt|OmECV5#XE1U7 zvoit#-zvL$XBrE@O=zdwMJurJ{t?XSlj`SP@OYtWD%1qDd@~t?dZw`Dwbp{E>_-sw!dy>PmsKm| z2g<#Bz;7C;cdL&G5O zC=gp)qi2(ga#mAb*UQDqk)c7HUzY}dXQ65D9nfAmv{%i|I2dW>4fdKHa4=LYl(LlF zL$X~#N}Rv8XDx>nj%}jYw8^sd>ggo=@{T=R-6Bq;PBhd#m$!TjNfMOf=evt;56Nyg zs9Ox&IU08oh=oQlEzfVsI32l=7h9~TaLqHDxphry<20o0=a zN%Ajn!vvbhOy3~yi+~|RpK-Slz?i)wcv{ot-Cf=MhikxiME_2fckF*K)j}Dnvcosf zO&54V`B~VeTnyh;#Eh&j)#|DJM)2#3UfHj}#_Quu^#8)xFE_EWV^CY&Kh9S^w$bC@ zw4-Q+c8CrU%SUJ&WaWl;nM!<-zA%vXiy$ZvyMnPyC_iL|Lp;a;zM*mXu+OM2Us0T$ zvBPNg@*|KBLt`AC2Ec&#v;^#>@Q|rq&*LT|?W~n3yLkKmV<`7rKW$-kJQv=So_)vG zXr49uP8Kt$ik}-kbX<(aUvi&p{56DCG+Gj@&i}}Qrvm|lMr~k!{iSrvh*f~SSN=m03?sb}d;!Qe>4`V%`$SBgCH zTlu0E@kI`e!0zfeN^aiy!ofUa`qa&e?)=DBC__&^wo3@e~P-WdaLRE z{!q@Ch;tpnx3c0@TqQP~He(jydiNqVXcb3M^?lSX>)tfg;wvqtxuP=9h^e!KPpGQc zyGZzpW$j7wM9bJYs(XaQhE>2U8#oyNq*WNAC~$9QmR7_{W7$RUV6+ z8(kzL38sAq77W(N3h#Z%nVQ*Sa3mvSHv9|{utR+|I}Ko6+t>*Zm`{i6q1bB83v*7y zA*rJKn&qM8#do32FQkhKIACWAX~b9f4@N=`X`j(ChSm)FkUJwme_+-t!#Sa0M{%z* zcQgD^B26E`XgJXY028j^E2}K$CYp>f^~~B!T}2yJC}AJe2OVAfn$T@Q5B{r)%VfXgXc~loG&&+ z5ohS_3SDdoy8%*Rv>hi)51}A%f-fyI*T#6Az>>cEHtrSX=6>M(kV`Woy6tJrrcg1M zjf)DBi-MnuH#SX%`~)A6$hd)E1Wag0sH=;lD|n2&E;xqp@>&N*AB2K*uz}FX4Y*Eb zzU&yhUUp}S*KO?A=m2q6M{8T!E0XDgOA`{97MMpj0V4v@L3Z|F6C&XZ{g`yU4g=aF zV|tjxm$OglNXDq_jG<3{GYLBS<*Wf!1(e0Kz&M0&_)~f zE2~2{5|akdU=w=41!%GjSr)b8D8xI@Z-qENU#J#=r$Tr>QU8JKG<`Z4RGq6*Btb`p@T?EO zZHjt z!hwF5nFEug0h4g;Gq1F+fix9TmB7GwJ4UFOFjID@Tj*^C$onzR+Jr?zYbU~rtb=>R z8laiaYu$li`;tGu@CIo?mM7N#0;pf~stWF6W7PWn%L*bSl+*>P=wZQqAQ(9-so_W8 z5n*q2sIe>Zk1_55Ar7$>-Bsq!nvgSyRf7Qjz%KMtnfs8kUe1OUji{zRHb(~RaLexF zrl{2+Mw=D^GPjpz>6we+L5ouj zWXn7Rns$`ZgV8K}(uCS*B^O1ol_-=p**#YuF&U!}{75-N3Ha)|Ri8zuD>iL4zI8kl z&1%~7y5b|%E8JILp)W7ig;e@RC=a7}z}(~jK#s_|qM$0t-jX%6<`mEgssB6X7HIJO zxT1*)-Aq|JF%1SKq@&ycRp9FSrP1)91H22I^j{JhlEU(~f;15P{2ymcbOd3Q0u`n! zc}N@B>%kd;gSe_DEo7~FbZki5)`W&tk*z!Kg6!2SOX7gIoJA?n^&Z@w>JPoL$zn?widrvEK`v$7p53px4N z=9?Ety<(DKg}XgWq9BK+1^YHGhf&HV6%S?LQQ-}QqIu^;d*`t9>&;1$D3Yx1AB3E-S-#_yXYYO9G!-|DR|r+Gxg{X#rmPj%amnFo4slA zJ1Pj_<;K(;jOC$?UvQ8poRwj4M|{-^nkR%P>qm;2w@9I(M#VS*NPenyK%|ZOR!j%_ zfl82AZee+$t-GQ7IWw$UH|P`J*#MLmlh&XYph>Tw`+Az!ZIEcZsi1howlhF5k|&f% zc^1@rQ3wrM{1;H!T#=lt#1?yJ5%skQ72f`_^<1OkLil>@a-b=TLvaXSCM>O$;wKr{ zevA5u&0GfbShflC{ThkbgyJSS&1K3_wc@(JR})swZFcrYP7;zu?DvR(*a%oyot!=h zlc*`=FNf#7g%TU&Of!F6ms!#hkQ533vz+x599LqefemkW;US>NYbJ$&<+dq=wIR7k z2&gD;lAzn^oaAg zX9RY!FQI+6xUaRP94-6KgEC_?SnPqYyzo{F4Cd?vBCop%uP0uYscAn$>AEZkldp;H zu4M&3Ns@wn;GXUloPls5fU8ihOgdUCY6>^f!Kz#rs~)JM!3qs>DJ;(tx994NST!46 zOsm~1Cb5h|(s#gYe^PSPp7c56iki|k{us!dz0U~(& zC$400779n?o)eAd@eI~FJzeF|RBS>?yiDnRSFor`)f2%%hgB_p-(GrE@&e&9X`Qf2 z2D2#aYQG}PZash;of48CIeh~^$y|L8a`tMeB9K*AV)4pWfzuAgzpBgjRFIP86W9Ny z*FlDXmtidEHxKzXM4H((YHp(o3;0bBW&$A@9AkM2@UWs-Ww)ISY;~#*{S3AbwhkdI zN2ERyk0Slb&gp_PgnKjnEv}Qc%OKVsl67VgJAV-FuKST#doC-e5!)c8`D{e|#I6VY z^xyYcB(!TbAQgYdtXey{ObfIffi6WW1<5ZU@Z47YQUabA$+Z=5fpyI6c)V}6ZjJer)oAg-F(Zuucb@UlV2;1rd~$+eMy_96Q7id?&Q|e zL~g_*Z*Cog~ldD5_3nbO%<-U>eff%1_0Ixw$hKB48FZ0JO8$Evytj?UPRK?i6ZX-i zLif;!zjtzHSBK?AG&@LMJObHHs9Q%CgB$`VP4Utu?3(0EvFD!QXM7hukT-%Zs8_ zfQ^)H;61^wC~H}2bN9k+t z*SKk~Rx^{G68XePqeR(N(CeI5e^=_=r~^z^U>fda_IP~$iJ0|effjLMJ(2(W+)qmq z;H}(K2yAjYcKWo+GYr4q&8}$*y3FI+c+R~w3L@=c7*ab0et^sm6@97{ZxL?ov@KyU zcAgkJzrv}tW+3jibt1fNT!?cNECnWpH7&lHC^f6%#}iH!oFZlQf8;+cEdRS~MgB|A zF~_JIJ&|KDRJa%f8ayFer(%^mJYU()!Kc$K=hHFe(T_o{K(PP6|J_+)8~V$mH4U*3 R&G6Ia>$j{+S;PAM{{hjo&7A-M literal 0 HcmV?d00001 diff --git a/python/02. Object Oriented Programming/myfile.txt b/python/02. Object Oriented Programming/myfile.txt new file mode 100644 index 0000000..c57314d --- /dev/null +++ b/python/02. Object Oriented Programming/myfile.txt @@ -0,0 +1,7 @@ +this is line 1 +this is line 2 +this is line 3 +this is line 4 +this is line 5 +this is line 6 +this is line 7 \ No newline at end of file diff --git a/python/02. Object Oriented Programming/myfile_reversed.txt b/python/02. Object Oriented Programming/myfile_reversed.txt new file mode 100644 index 0000000..e330fb3 --- /dev/null +++ b/python/02. Object Oriented Programming/myfile_reversed.txt @@ -0,0 +1,6 @@ +this is line 7this is line 6 +this is line 5 +this is line 4 +this is line 3 +this is line 2 +this is line 1 diff --git a/python/04. Advanced/09. Error Handling.ipynb b/python/04. Advanced/09. Error Handling.ipynb index 73c1953..b3b1237 100755 --- a/python/04. Advanced/09. Error Handling.ipynb +++ b/python/04. Advanced/09. Error Handling.ipynb @@ -1177,7 +1177,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/05. Modules/19. openpyxl.ipynb b/python/05. Modules/19. openpyxl.ipynb index 15941f0..044258e 100755 --- a/python/05. Modules/19. openpyxl.ipynb +++ b/python/05. Modules/19. openpyxl.ipynb @@ -2244,7 +2244,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -2258,7 +2258,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/python/XX. Practice Sessions/01. Data Types + Functions + IO.ipynb b/python/XX. Practice Sessions/01. Data Types + Functions + IO.ipynb index 939539c..e751aae 100755 --- a/python/XX. Practice Sessions/01. Data Types + Functions + IO.ipynb +++ b/python/XX. Practice Sessions/01. Data Types + Functions + IO.ipynb @@ -309,7 +309,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/XX. Practice Sessions/02. Data Types + Functions + IO (with Solutions).ipynb b/python/XX. Practice Sessions/02. Data Types + Functions + IO (with Solutions).ipynb index 0ecb8fc..74c3741 100755 --- a/python/XX. Practice Sessions/02. Data Types + Functions + IO (with Solutions).ipynb +++ b/python/XX. Practice Sessions/02. Data Types + Functions + IO (with Solutions).ipynb @@ -287,7 +287,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.6" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/python/XX. Practice Sessions/03. OOP (With Solutions).ipynb b/python/XX. Practice Sessions/03. OOP (With Solutions).ipynb index bcb7517..82be4c6 100755 --- a/python/XX. Practice Sessions/03. OOP (With Solutions).ipynb +++ b/python/XX. Practice Sessions/03. OOP (With Solutions).ipynb @@ -333,7 +333,7 @@ "metadata": { "hide_code_all_hidden": false, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/python/XX. Practice Sessions/04. OOP + Modularization.ipynb b/python/XX. Practice Sessions/04. OOP + Modularization.ipynb index 8df0a35..8625625 100755 --- a/python/XX. Practice Sessions/04. OOP + Modularization.ipynb +++ b/python/XX. Practice Sessions/04. OOP + Modularization.ipynb @@ -231,7 +231,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -245,7 +245,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/python/XX. Practice Sessions/05. Review.ipynb b/python/XX. Practice Sessions/05. Review.ipynb index 6f02383..3020b8a 100755 --- a/python/XX. Practice Sessions/05. Review.ipynb +++ b/python/XX. Practice Sessions/05. Review.ipynb @@ -117,7 +117,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -131,7 +131,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.9" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/python/XX. Practice Sessions/Untitled.ipynb b/python/XX. Practice Sessions/Untitled.ipynb new file mode 100644 index 0000000..5e8e72f --- /dev/null +++ b/python/XX. Practice Sessions/Untitled.ipynb @@ -0,0 +1,102 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 374, + "id": "00e26a21", + "metadata": {}, + "outputs": [], + "source": [ + "class Point:\n", + " def __init__(self, x, y):\n", + " self.x = x\n", + " self.y = y\n", + "\n", + " def __repr__(self):\n", + " return f\"Point({self.x}, {self.y})\"\n", + " \n", + " def __abs__(self):\n", + " return (self.x ** 2 + self.y ** 2) ** 0.5\n", + " \n", + " def __gt__(self, obj):\n", + " return abs(self) > abs(obj)" + ] + }, + { + "cell_type": "code", + "execution_count": 375, + "id": "4451d5ca", + "metadata": {}, + "outputs": [], + "source": [ + "my_points = [Point(3, 4), Point(6, 8), Point(2, 2), Point(9, 11)]" + ] + }, + { + "cell_type": "code", + "execution_count": 377, + "id": "7a803a94", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Point(2, 2), Point(3, 4), Point(6, 8), Point(9, 11)]" + ] + }, + "execution_count": 377, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sorted(my_points)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac9197f9", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "446c0437", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2f586655", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/XX. Practice Sessions/file.txt b/python/XX. Practice Sessions/file.txt new file mode 100644 index 0000000..7b8715c --- /dev/null +++ b/python/XX. Practice Sessions/file.txt @@ -0,0 +1,142 @@ +Hassan Rouhani +From Wikipedia, the free encyclopedia +Jump to navigationJump to search +"Rouhani" redirects here. For other persons with this surname, see Rouhani (surname). +"Rohani" redirects here. For the village in Iran, see Rohani, Iran. +His Excellency +Hujjat al-Islam +Hassan Rouhani +حسن روحانی +Hassan Rouani 2017 portrait.jpg +Rouhani in 2017 +7th President of Iran +Incumbent +Assumed office +3 August 2013 +Supreme Leader Ali Khamenei +Vice President Eshaq Jahangiri +Preceded by Mahmoud Ahmadinejad +Secretary General of the Non-Aligned Movement +In office +3 August 2013 – 17 September 2016 +Preceded by Mahmoud Ahmadinejad +Succeeded by Nicolás Maduro +Chief Nuclear Negotiator of Iran +In office +6 October 2003 – 15 August 2005 +President Mohammad Khatami +Deputy Hossein Mousavian +Preceded by Position established +Succeeded by Ali Larijani +Secretary of the Supreme National Security Council +In office +14 October 1989 – 15 August 2005 +President Akbar Hashemi Rafsanjani +Mohammad Khatami +Preceded by Position established +Succeeded by Ali Larijani +Member of the Assembly of Experts +Incumbent +Assumed office +19 February 2007 +Constituency Tehran Province +Majority 2,238,166 (53.56%) +In office +18 February 2000 – 18 February 2007 +Constituency Semnan Province +First Deputy Speaker of the Parliament +In office +2 June 1992 – 26 May 2000 +Preceded by Hossein Hashemian +Succeeded by Behzad Nabavi +Member of the Islamic Consultative Assembly +In office +28 May 1984 – 27 May 2000 +Constituency Tehran, Rey, Shemiranat and Eslamshahr +Majority 729,965 (58.3%; 2nd term) +In office +28 May 1980 – 27 May 1984 +Constituency Semnan +Majority 19,017 (62.1%) +Advisor to the President of Iran +President of Center for Strategic Research +In office +August 1999 – 10 June 1997 +President Akbar Hashemi Rafsanjani +Preceded by Mohammad Mousavi Khoeiniha +Succeeded by Position abolished +Member of Expediency Discernment Council +In office +8 May 1991 – 3 August 2013 +Appointed by Ali Khamenei +Chairman Akbar Hashemi Rafsanjani +Succeeded by Mahmoud Ahmadinejad +National Security Advisor of Iran +In office +2000–2005 +President Mohammad Khatami +Preceded by Khosrow Tehrani +In office +1989–1997 +President Akbar Hashemi Rafsanjani +Personal details +Born Hassan Fereydoun +12 November 1948 (age 72) +Sorkheh, Semnan Province, Imperial State of Iran +Political party Moderation and Development Party (1999–present) +Other political +affiliations Combatant Clergy Association (1988–present; inactive since 2009)[1] +Islamic Republican Party (1979–87) +Spouse(s) Sahebeh Arabi (1968–present) +Children 5 +Alma mater Qom Seminary +University of Tehran +Glasgow Caledonian University +Signature +Website Government website +Personal website (Persian) +Military service +Allegiance Iran +Years of service 1971–72 (conscription)[5] +1985–91[6] +Unit Sepah Danesh of Nishapur (1971–72)[5] +Commands Commander-in-Chief of Air Defense (1985–91)[6] +Deputy to Second-in-Command of Iran's Joint Chiefs of Staff (1988–89)[6] +Battles/wars Iran–Iraq War +Awards Order of Nasr Ribbon.svg Order of Nasr (1st Class)[2] +Fath Medal 2nd Order.jpg Order of Fath (2nd Class)[3][4] +Hassan Rouani 2017 portrait.jpg +This article is part of +a series about +Hassan Rouhani +Early life and careerPersonal life +Electoral history +Member of Parliament +Elections +Commission on DefenseCommission on +Foreign Policy and National Security +Iran–Iraq WarNuclear program of Iran Nuclear negotiatorSupreme National Security Council +Member of Assembly of Experts +Elections +Expediency Discernment Council +President of Iran +Incumbent + +First term +Presidential campaign General election +Cabinet members ConfirmationsInaugurationInternational trips +JCPOA +Iran and ISIL Iranian involvement in the Syrian Civil WarIranian intervention in IraqWorld Against Violence and Extremism +Second term +Reelection campaign General election +InaugurationCabinet members Confirmations2017–18 protests2019 protestsLeaked Mohammad Javad Zarif audiotape +Books +Emblem of Iran.svg +vte +Hassan Rouhani (Persian: حسن روحانی‎, Standard Persian pronunciation: [hæˈsæn-e ɾowhɒːˈniː] (About this soundlisten); born Hassan Fereydoun (Persian: حسن فریدون‎); 12 November 1948)[7][8] is an Iranian politician serving as the seventh president of Iran since 3 August 2013. He is also a lawyer,[9] academic, former diplomat and Islamic cleric. He has been a member of Iran's Assembly of Experts since 1999,[10] member of the Expediency Council since 1991,[11] and a member of the Supreme National Security Council since 1989.[6][12] Rouhani was deputy speaker of the fourth and fifth terms of the Parliament of Iran (Majlis) and Secretary of the Supreme National Security Council from 1989 to 2005.[6] In the latter capacity, he was the country's top negotiator with the EU three, UK, France, and Germany, on nuclear technology in Iran, and has also served as a Shia mujtahid (a senior cleric),[13] and economic trade negotiator.[14][15]:138 He has expressed official support for upholding the rights of ethnic and religious minorities.[16] In 2013, he appointed former industries minister Eshaq Jahangiri as his first vice-president.[citation needed] + +On 7 May 2013, Rouhani registered for the presidential election that was held on 14 June 2013.[17] He said that, if elected, he would prepare a "civil rights charter", restore the economy and improve rocky relations with Western nations.[18] Rouhani is frequently described as a moderate. He was elected as President of Iran on 15 June, defeating Tehran mayor Mohammad Bagher Ghalibaf and four other candidates.[19][20][21] He took office on 3 August 2013.[22] In 2013, Time magazine named him in its list of the 100 Most Influential People in the World. In domestic policy, he encourages personal freedom and free access to information, has improved women's rights by appointing female foreign ministry spokespeople, and has been described as a centrist and reformist who has improved Iran's diplomatic relations with other countries through exchanging conciliatory letters.[23][24][25] Rouhani won re-election in the 2017 election with 23,636,652 votes (57.1%).[26] He became the third Iranian President, after Mohammad Khatami and Mahmoud Ahmadinejad, to win a presidential victory as an incumbent with an increased electoral mandate. + + +author: hejazizo.ali@gmail.com +founder: ali@gmail.com \ No newline at end of file From 73b4920df58664d88c54fdfc76151a9675f623c5 Mon Sep 17 00:00:00 2001 From: Ali Date: Sun, 25 Jul 2021 19:49:38 -0400 Subject: [PATCH 02/31] updated python material --- ...sion.ipynb => 15 List Comprehension.ipynb} | 203 +++++++++++------- ...ut, and String Formatting in Python.ipynb} | 0 ...wer Python String Format Techniques.ipynb} | 0 ...8 Defining Your Own Python Function.ipynb} | 0 ...> 19 Namespaces and Scope in Python.ipynb} | 0 5 files changed, 127 insertions(+), 76 deletions(-) rename python/01. Basics/{List Comprehension.ipynb => 15 List Comprehension.ipynb} (87%) rename python/01. Basics/{15 Basic Input, Output, and String Formatting in Python.ipynb => 16 Basic Input, Output, and String Formatting in Python.ipynb} (100%) rename python/01. Basics/{16 Newer Python String Format Techniques.ipynb => 17 Newer Python String Format Techniques.ipynb} (100%) rename python/01. Basics/{17 Defining Your Own Python Function.ipynb => 18 Defining Your Own Python Function.ipynb} (100%) rename python/01. Basics/{18 Namespaces and Scope in Python.ipynb => 19 Namespaces and Scope in Python.ipynb} (100%) diff --git a/python/01. Basics/List Comprehension.ipynb b/python/01. Basics/15 List Comprehension.ipynb similarity index 87% rename from python/01. Basics/List Comprehension.ipynb rename to python/01. Basics/15 List Comprehension.ipynb index b52c006..cc229c8 100644 --- a/python/01. Basics/List Comprehension.ipynb +++ b/python/01. Basics/15 List Comprehension.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "3152c34f", + "id": "f58aa0c9", "metadata": {}, "source": [ "# When to Use a List Comprehension in Python" @@ -10,7 +10,7 @@ }, { "cell_type": "markdown", - "id": "d5c912c3", + "id": "5f773381", "metadata": {}, "source": [ "Python is famous for allowing you to write code that’s elegant, easy to write, and almost as easy to read as plain English. One of the language’s most distinctive features is the list comprehension, which you can use to create powerful functionality within a single line of code. However, many developers struggle to fully leverage the more advanced features of a list comprehension in Python. Some programmers even use them too much, which can lead to code that’s less efficient and harder to read." @@ -18,7 +18,7 @@ }, { "cell_type": "markdown", - "id": "42856702", + "id": "d7e238e3", "metadata": {}, "source": [ "## How to Create Lists in Python" @@ -26,7 +26,7 @@ }, { "cell_type": "markdown", - "id": "0bf3ef32", + "id": "5f937f87", "metadata": {}, "source": [ "There are a few different ways you can create lists in Python. To better understand the trade-offs of using a list comprehension in Python, let’s first see how to create lists with these approaches." @@ -34,7 +34,7 @@ }, { "cell_type": "markdown", - "id": "a35b647d", + "id": "df590574", "metadata": {}, "source": [ "### Using for Loops" @@ -42,7 +42,7 @@ }, { "cell_type": "markdown", - "id": "b0396622", + "id": "87440fdd", "metadata": {}, "source": [ "The most common type of loop is the for loop. You can use a for loop to create a list of elements in three steps:\n", @@ -54,7 +54,7 @@ }, { "cell_type": "markdown", - "id": "cf24ed22", + "id": "e60d2a38", "metadata": {}, "source": [ "If you want to create a list containing the first ten perfect squares, then you can complete these steps in three lines of code:" @@ -63,7 +63,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "1af99275", + "id": "2c73b929", "metadata": {}, "outputs": [ { @@ -86,7 +86,7 @@ }, { "cell_type": "markdown", - "id": "5d8f3589", + "id": "7c41bd32", "metadata": {}, "source": [ "Here, you instantiate an empty list, squares. Then, you use a for loop to iterate over `range(10)`. Finally, you multiply each number by itself and append the result to the end of the list." @@ -94,7 +94,7 @@ }, { "cell_type": "markdown", - "id": "f424261b", + "id": "4c4ceed1", "metadata": {}, "source": [ "### Using `map()` Objects" @@ -102,7 +102,7 @@ }, { "cell_type": "markdown", - "id": "52cf9b0e", + "id": "11e32a92", "metadata": {}, "source": [ "`map()` provides an alternative approach that’s based in functional programming. You pass in a function and an iterable, and `map()` will create an object. This object contains the output you would get from running each iterable element through the supplied function." @@ -110,7 +110,7 @@ }, { "cell_type": "markdown", - "id": "cd846d98", + "id": "dcb97c05", "metadata": {}, "source": [ "As an example, consider a situation in which you need to calculate the price after tax for a list of transactions:" @@ -119,7 +119,7 @@ { "cell_type": "code", "execution_count": 6, - "id": "168e613c", + "id": "e62aacb6", "metadata": {}, "outputs": [], "source": [ @@ -130,7 +130,7 @@ { "cell_type": "code", "execution_count": 7, - "id": "d6a2685c", + "id": "96e34612", "metadata": {}, "outputs": [], "source": [ @@ -141,7 +141,7 @@ { "cell_type": "code", "execution_count": 8, - "id": "9b16cb16", + "id": "baa10386", "metadata": {}, "outputs": [ { @@ -162,7 +162,7 @@ }, { "cell_type": "markdown", - "id": "11913fae", + "id": "6b958b8b", "metadata": {}, "source": [ "Here, you have an iterable txns and a function `get_price_with_tax()`. You pass both of these arguments to `map()`, and store the resulting object in final_prices. You can easily convert this map object into a list using `list()`." @@ -170,7 +170,7 @@ }, { "cell_type": "markdown", - "id": "94098bf1", + "id": "fb50ab52", "metadata": {}, "source": [ "### Using List Comprehensions" @@ -178,7 +178,7 @@ }, { "cell_type": "markdown", - "id": "5e282d8d", + "id": "219dfb6c", "metadata": {}, "source": [ "List comprehensions are a third way of making lists. With this elegant approach, you could rewrite the for loop from the first example in just a single line of code:" @@ -187,7 +187,7 @@ { "cell_type": "code", "execution_count": 9, - "id": "eda83deb", + "id": "2beeffdd", "metadata": {}, "outputs": [ { @@ -208,7 +208,7 @@ }, { "cell_type": "markdown", - "id": "c0d36b13", + "id": "c240ed54", "metadata": {}, "source": [ "Rather than creating an empty list and adding each element to the end, you simply define the list and its contents at the same time by following this format:\n", @@ -220,7 +220,7 @@ }, { "cell_type": "markdown", - "id": "04f33f21", + "id": "d150a3b0", "metadata": {}, "source": [ "Every list comprehension in Python includes three elements:\n", @@ -232,7 +232,7 @@ }, { "cell_type": "markdown", - "id": "72432652", + "id": "ca67f077", "metadata": {}, "source": [ "Because the expression requirement is so flexible, a list comprehension in Python works well in many places where you would use `map()`. You can rewrite the pricing example with its own list comprehension:" @@ -241,7 +241,7 @@ { "cell_type": "code", "execution_count": 10, - "id": "fa6be321", + "id": "9bcbb0d8", "metadata": {}, "outputs": [], "source": [ @@ -252,7 +252,7 @@ { "cell_type": "code", "execution_count": 11, - "id": "06156a8c", + "id": "8fc5c567", "metadata": {}, "outputs": [], "source": [ @@ -263,7 +263,7 @@ { "cell_type": "code", "execution_count": 12, - "id": "610da982", + "id": "a1ff6b6a", "metadata": {}, "outputs": [ { @@ -284,7 +284,7 @@ }, { "cell_type": "markdown", - "id": "6b39f2fc", + "id": "460062c4", "metadata": {}, "source": [ "The only distinction between this implementation and `map()` is that the list comprehension in Python returns a list, not a map object." @@ -292,7 +292,7 @@ }, { "cell_type": "markdown", - "id": "11dd1048", + "id": "1ac3dbe9", "metadata": {}, "source": [ "## Benefits of Using List Comprehensions" @@ -300,7 +300,7 @@ }, { "cell_type": "markdown", - "id": "425f9373", + "id": "93c89e56", "metadata": {}, "source": [ "List comprehensions are often described as being more Pythonic than loops or `map()`. But rather than blindly accepting that assessment, it’s worth it to understand the benefits of using a list comprehension in Python when compared to the alternatives. Later on, you’ll learn about a few scenarios where the alternatives are a better choice." @@ -308,7 +308,7 @@ }, { "cell_type": "markdown", - "id": "f2de596e", + "id": "667b1deb", "metadata": {}, "source": [ "One main benefit of using a list comprehension in Python is that it’s a single tool that you can use in many different situations. In addition to standard list creation, list comprehensions can also be used for mapping and filtering. You don’t have to use a different approach for each scenario." @@ -316,7 +316,7 @@ }, { "cell_type": "markdown", - "id": "d7ec12f5", + "id": "6f0cfa83", "metadata": {}, "source": [ "This is the main reason why list comprehensions are considered **Pythonic**, as Python embraces simple, powerful tools that you can use in a wide variety of situations. As an added side benefit, whenever you use a list comprehension in Python, you won’t need to remember the proper order of arguments like you would when you call `map()`." @@ -324,7 +324,7 @@ }, { "cell_type": "markdown", - "id": "ba63943f", + "id": "0cc7f834", "metadata": {}, "source": [ "List comprehensions are also more **declarative** than loops, which means they’re easier to read and understand. Loops require you to focus on how the list is created. You have to manually create an empty list, loop over the elements, and add each of them to the end of the list. With a list comprehension in Python, you can instead focus on what you want to go in the list and trust that Python will take care of how the list construction takes place." @@ -332,7 +332,7 @@ }, { "cell_type": "markdown", - "id": "51cf28dd", + "id": "8b8662a1", "metadata": {}, "source": [ "## How to Supercharge Your Comprehensions" @@ -340,7 +340,7 @@ }, { "cell_type": "markdown", - "id": "84ab2dd0", + "id": "4907fcca", "metadata": {}, "source": [ "In order to understand the full value that list comprehensions can provide, it’s helpful to understand their range of possible functionality. You’ll also want to understand the changes that are coming to the list comprehension in Python 3.8." @@ -348,7 +348,7 @@ }, { "cell_type": "markdown", - "id": "c409196a", + "id": "1849147f", "metadata": {}, "source": [ "### Using Conditional Logic" @@ -356,7 +356,7 @@ }, { "cell_type": "markdown", - "id": "1b355f60", + "id": "9f785fe8", "metadata": {}, "source": [ "Earlier, you saw this formula for how to create list comprehensions:\n", @@ -368,7 +368,7 @@ }, { "cell_type": "markdown", - "id": "f2dfaa43", + "id": "be67945e", "metadata": {}, "source": [ "While this formula is accurate, it’s also a bit incomplete. A more complete description of the comprehension formula adds support for optional **conditionals**. The most common way to add conditional logic to a list comprehension is to add a conditional to the end of the expression:\n", @@ -380,7 +380,7 @@ }, { "cell_type": "markdown", - "id": "42e59dd9", + "id": "ff3b98b8", "metadata": {}, "source": [ "Here, your conditional statement comes just before the closing bracket." @@ -388,7 +388,7 @@ }, { "cell_type": "markdown", - "id": "7ef6bfee", + "id": "cd7aca65", "metadata": {}, "source": [ "Conditionals are important because they allow list comprehensions to filter out unwanted values, which would normally require a call to `filter()`:" @@ -397,7 +397,7 @@ { "cell_type": "code", "execution_count": 13, - "id": "765c5292", + "id": "7dc0e00f", "metadata": {}, "outputs": [ { @@ -419,7 +419,7 @@ }, { "cell_type": "markdown", - "id": "1cf721a4", + "id": "65f3c11d", "metadata": {}, "source": [ "In this code block, the conditional statement filters out any characters in sentence that aren’t a vowel." @@ -427,7 +427,7 @@ }, { "cell_type": "markdown", - "id": "32cc82ec", + "id": "9fd89f75", "metadata": {}, "source": [ "The conditional can test any valid expression. If you need a more complex filter, then you can even move the conditional logic to a separate function:" @@ -436,7 +436,7 @@ { "cell_type": "code", "execution_count": 14, - "id": "91b9be41", + "id": "21aa3457", "metadata": {}, "outputs": [], "source": [ @@ -447,7 +447,7 @@ { "cell_type": "code", "execution_count": 15, - "id": "86730e6a", + "id": "78a1f5b5", "metadata": {}, "outputs": [], "source": [ @@ -459,7 +459,7 @@ { "cell_type": "code", "execution_count": 16, - "id": "55c04cd2", + "id": "943b870a", "metadata": {}, "outputs": [], "source": [ @@ -468,7 +468,7 @@ }, { "cell_type": "markdown", - "id": "9226fd8b", + "id": "e2ec60d0", "metadata": {}, "source": [ "Here, you create a complex filter `is_consonant()` and pass this function as the conditional statement for your list comprehension. Note that the member value `i` is also passed as an argument to your function." @@ -476,7 +476,7 @@ }, { "cell_type": "markdown", - "id": "ce74e165", + "id": "0d81008b", "metadata": {}, "source": [ "You can place the conditional at the end of the statement for simple filtering, but what if you want to change a member value instead of filtering it out? In this case, it’s useful to place the conditional near the beginning of the expression:\n", @@ -488,7 +488,7 @@ }, { "cell_type": "markdown", - "id": "80d084a8", + "id": "3cd71d06", "metadata": {}, "source": [ "With this formula, you can use conditional logic to select from multiple possible output options. For example, if you have a list of prices, then you may want to replace negative prices with 0 and leave the positive values unchanged:" @@ -497,7 +497,7 @@ { "cell_type": "code", "execution_count": 17, - "id": "20d87c8d", + "id": "f5a18ec4", "metadata": {}, "outputs": [ { @@ -519,7 +519,7 @@ }, { "cell_type": "markdown", - "id": "63971998", + "id": "5caf9204", "metadata": {}, "source": [ "Here, your expression `i` contains a conditional statement, if `i > 0` else `0`. This tells Python to output the value of `i` if the number is positive, but to change `i` to `0` if the number is negative. If this seems overwhelming, then it may be helpful to view the conditional logic as its own function:" @@ -528,7 +528,7 @@ { "cell_type": "code", "execution_count": 18, - "id": "38542932", + "id": "d1381f62", "metadata": {}, "outputs": [ { @@ -551,7 +551,7 @@ }, { "cell_type": "markdown", - "id": "eb89d56e", + "id": "064c6a70", "metadata": {}, "source": [ "Now, your conditional statement is contained within `get_price()`, and you can use it as part of your list comprehension expression." @@ -559,7 +559,7 @@ }, { "cell_type": "markdown", - "id": "5f3535ca", + "id": "474fc0ea", "metadata": {}, "source": [ "### Using Set and Dictionary Comprehensions" @@ -567,7 +567,7 @@ }, { "cell_type": "markdown", - "id": "f2dfa5a8", + "id": "1d2385a4", "metadata": {}, "source": [ "While the list comprehension in Python is a common tool, you can also create set and dictionary comprehensions. A **set** comprehension is almost exactly the same as a list comprehension in Python. The difference is that set comprehensions make sure the output contains no duplicates. You can create a set comprehension by using curly braces instead of brackets:" @@ -576,7 +576,7 @@ { "cell_type": "code", "execution_count": 19, - "id": "23b11126", + "id": "568c30fb", "metadata": {}, "outputs": [ { @@ -598,7 +598,7 @@ }, { "cell_type": "markdown", - "id": "e16921e4", + "id": "1d248f9e", "metadata": {}, "source": [ "Your set comprehension outputs all the unique vowels it found in `quote`. Unlike lists, sets don’t guarantee that items will be saved in any particular order. This is why the first member of the set is `a`, even though the first vowel in quote is `i`." @@ -606,7 +606,7 @@ }, { "cell_type": "markdown", - "id": "0ecfa4a2", + "id": "d5528a3e", "metadata": {}, "source": [ "**Dictionary comprehensions** are similar, with the additional requirement of defining a key:" @@ -615,7 +615,7 @@ { "cell_type": "code", "execution_count": 20, - "id": "8e4c4e43", + "id": "8f9f46dc", "metadata": {}, "outputs": [ { @@ -636,7 +636,7 @@ }, { "cell_type": "markdown", - "id": "d85016e5", + "id": "aaff8d57", "metadata": {}, "source": [ "To create the squares dictionary, you use curly braces (`{}`) as well as a key-value pair (`i: i * i`) in your expression." @@ -644,7 +644,7 @@ }, { "cell_type": "markdown", - "id": "ff9324d5", + "id": "970d53c8", "metadata": {}, "source": [ "## When Not to Use a List Comprehension in Python" @@ -652,7 +652,7 @@ }, { "cell_type": "markdown", - "id": "52ed3727", + "id": "98ccc2d1", "metadata": {}, "source": [ "List comprehensions are useful and can help you write elegant code that’s easy to read and debug, but they’re not the right choice for all circumstances. They might make your code run more slowly or use more memory. If your code is less performant or harder to understand, then it’s probably better to choose an alternative." @@ -660,7 +660,7 @@ }, { "cell_type": "markdown", - "id": "6b639e31", + "id": "85c44be6", "metadata": {}, "source": [ "### Watch Out for Nested Comprehensions" @@ -668,7 +668,7 @@ }, { "cell_type": "markdown", - "id": "9acecef6", + "id": "5b51b97b", "metadata": {}, "source": [ "Comprehensions can be **nested** to create combinations of lists, dictionaries, and sets within a collection. For example, say a climate laboratory is tracking the high temperature in five different cities for the first week of June. The perfect data structure for storing this data could be a Python list comprehension nested within a dictionary comprehension:" @@ -677,7 +677,7 @@ { "cell_type": "code", "execution_count": 21, - "id": "8dc1543c", + "id": "f10bbb3b", "metadata": {}, "outputs": [ { @@ -703,7 +703,7 @@ }, { "cell_type": "markdown", - "id": "60f08db0", + "id": "41ca8fa2", "metadata": {}, "source": [ "You create the outer collection temps with a dictionary comprehension. The expression is a key-value pair, which contains yet another comprehension. This code will quickly generate a list of data for each city in `cities`." @@ -711,7 +711,7 @@ }, { "cell_type": "markdown", - "id": "e33bfa5b", + "id": "752369a9", "metadata": {}, "source": [ "Nested lists are a common way to create **matrices**, which are often used for mathematical purposes. Take a look at the code block below:" @@ -720,7 +720,7 @@ { "cell_type": "code", "execution_count": 22, - "id": "c35b13e4", + "id": "9927b614", "metadata": {}, "outputs": [ { @@ -746,7 +746,7 @@ }, { "cell_type": "markdown", - "id": "cec3d619", + "id": "91f049d2", "metadata": {}, "source": [ "The outer list comprehension `[... for _ in range(6)]` creates six rows, while the inner list comprehension `[i for i in range(5)]` fills each of these rows with values." @@ -754,7 +754,7 @@ }, { "cell_type": "markdown", - "id": "5b40eff6", + "id": "51ced991", "metadata": {}, "source": [ "So far, the purpose of each nested comprehension is pretty intuitive. However, there are other situations, such as **flattening** nested lists, where the logic arguably makes your code more confusing. Take this example, which uses a nested list comprehension to flatten a matrix:" @@ -763,7 +763,7 @@ { "cell_type": "code", "execution_count": 23, - "id": "028db7cb", + "id": "29ed6bde", "metadata": {}, "outputs": [ { @@ -813,7 +813,7 @@ }, { "cell_type": "markdown", - "id": "fcc225d7", + "id": "52288902", "metadata": {}, "source": [ "The code to flatten the matrix is concise, but it may not be so intuitive to understand how it works. On the other hand, if you were to use `for` loops to flatten the same matrix, then your code will be much more straightforward:" @@ -822,7 +822,7 @@ { "cell_type": "code", "execution_count": 24, - "id": "3808359a", + "id": "eee26fe5", "metadata": {}, "outputs": [], "source": [ @@ -836,7 +836,7 @@ { "cell_type": "code", "execution_count": 26, - "id": "300850a3", + "id": "0aa7e9b8", "metadata": {}, "outputs": [], "source": [ @@ -849,7 +849,7 @@ { "cell_type": "code", "execution_count": 27, - "id": "84440358", + "id": "be5af3a0", "metadata": {}, "outputs": [ { @@ -869,13 +869,64 @@ }, { "cell_type": "markdown", - "id": "fed06ea0", + "id": "54bd5157", + "metadata": {}, + "source": [ + "Now you can see that the code traverses one row of the matrix at a time, pulling out all the elements in that row before moving on to the next one." + ] + }, + { + "cell_type": "markdown", + "id": "0f62e378", "metadata": {}, "source": [ - "Now you can see that the code traverses one row of the matrix at a time, pulling out all the elements in that row before moving on to the next one.\n", - "\n", "While the single-line nested list comprehension might seem more Pythonic, what’s most important is to write code that your team can easily understand and modify. When you choose your approach, you’ll have to make a judgment call based on whether you think the comprehension helps or hurts readability." ] + }, + { + "cell_type": "markdown", + "id": "cada16f6", + "metadata": {}, + "source": [ + "## Conclusion" + ] + }, + { + "cell_type": "markdown", + "id": "a6af6814", + "metadata": {}, + "source": [ + "In this tutorial, you learned how to use a list comprehension in Python to accomplish complex tasks without making your code overly complicated." + ] + }, + { + "cell_type": "markdown", + "id": "c2c3695b", + "metadata": {}, + "source": [ + "Now you can:\n", + "\n", + "- Simplify loops and `map()` calls with declarative **list comprehensions**\n", + "- Supercharge your comprehensions with **conditional logic**\n", + "- Create **set** and **dictionary** comprehensions\n", + "- Determine when code clarity or performance dictates an **alternative approach**" + ] + }, + { + "cell_type": "markdown", + "id": "856a033b", + "metadata": {}, + "source": [ + "Whenever you have to choose a list creation method, try multiple implementations and consider what’s easiest to read and understand in your specific scenario. If performance is important, then you can use profiling tools to give you actionable data instead of relying on hunches or guesses about what works the best." + ] + }, + { + "cell_type": "markdown", + "id": "e8ae0177", + "metadata": {}, + "source": [ + "Remember that while Python list comprehensions get a lot of attention, your intuition and ability to use data when it counts will help you write clean code that serves the task at hand. This, ultimately, is the key to making your code Pythonic!" + ] } ], "metadata": { diff --git a/python/01. Basics/15 Basic Input, Output, and String Formatting in Python.ipynb b/python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb similarity index 100% rename from python/01. Basics/15 Basic Input, Output, and String Formatting in Python.ipynb rename to python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb diff --git a/python/01. Basics/16 Newer Python String Format Techniques.ipynb b/python/01. Basics/17 Newer Python String Format Techniques.ipynb similarity index 100% rename from python/01. Basics/16 Newer Python String Format Techniques.ipynb rename to python/01. Basics/17 Newer Python String Format Techniques.ipynb diff --git a/python/01. Basics/17 Defining Your Own Python Function.ipynb b/python/01. Basics/18 Defining Your Own Python Function.ipynb similarity index 100% rename from python/01. Basics/17 Defining Your Own Python Function.ipynb rename to python/01. Basics/18 Defining Your Own Python Function.ipynb diff --git a/python/01. Basics/18 Namespaces and Scope in Python.ipynb b/python/01. Basics/19 Namespaces and Scope in Python.ipynb similarity index 100% rename from python/01. Basics/18 Namespaces and Scope in Python.ipynb rename to python/01. Basics/19 Namespaces and Scope in Python.ipynb From 1e20085b7887b2db0112a0c575963e558c8ace79 Mon Sep 17 00:00:00 2001 From: Ali Date: Sun, 25 Jul 2021 19:55:45 -0400 Subject: [PATCH 03/31] updated python material --- .../01. Data Types + Functions + IO.ipynb | 0 ...es + Functions + IO (with Solutions).ipynb | 0 .../02. Search Engine (With Solutions).ipynb | 0 .../03. OOP (With Solutions).ipynb | 0 .../04. OOP + Modularization.ipynb | 0 .../05. Review.ipynb | 0 .../Untitled.ipynb | 0 .../file.txt | 0 .../geo.py | 0 .../01 Data Types + Functions + IO.ipynb | 249 ++++++++++++++++++ python/XX. Practice Sessions/02 OOP.ipynb | 162 ++++++++++++ .../03 OOP + Modularization.ipynb | 82 ++++++ python/XX. Practice Sessions/04 Review.ipynb | 139 ++++++++++ 13 files changed, 632 insertions(+) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/01. Data Types + Functions + IO.ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/02. Data Types + Functions + IO (with Solutions).ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/02. Search Engine (With Solutions).ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/03. OOP (With Solutions).ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/04. OOP + Modularization.ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/05. Review.ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/Untitled.ipynb (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/file.txt (100%) rename python/{XX. Practice Sessions => XX. Practice Sessions-Solutions}/geo.py (100%) create mode 100755 python/XX. Practice Sessions/01 Data Types + Functions + IO.ipynb create mode 100755 python/XX. Practice Sessions/02 OOP.ipynb create mode 100755 python/XX. Practice Sessions/03 OOP + Modularization.ipynb create mode 100755 python/XX. Practice Sessions/04 Review.ipynb diff --git a/python/XX. Practice Sessions/01. Data Types + Functions + IO.ipynb b/python/XX. Practice Sessions-Solutions/01. Data Types + Functions + IO.ipynb similarity index 100% rename from python/XX. Practice Sessions/01. Data Types + Functions + IO.ipynb rename to python/XX. Practice Sessions-Solutions/01. Data Types + Functions + IO.ipynb diff --git a/python/XX. Practice Sessions/02. Data Types + Functions + IO (with Solutions).ipynb b/python/XX. Practice Sessions-Solutions/02. Data Types + Functions + IO (with Solutions).ipynb similarity index 100% rename from python/XX. Practice Sessions/02. Data Types + Functions + IO (with Solutions).ipynb rename to python/XX. Practice Sessions-Solutions/02. Data Types + Functions + IO (with Solutions).ipynb diff --git a/python/XX. Practice Sessions/02. Search Engine (With Solutions).ipynb b/python/XX. Practice Sessions-Solutions/02. Search Engine (With Solutions).ipynb similarity index 100% rename from python/XX. Practice Sessions/02. Search Engine (With Solutions).ipynb rename to python/XX. Practice Sessions-Solutions/02. Search Engine (With Solutions).ipynb diff --git a/python/XX. Practice Sessions/03. OOP (With Solutions).ipynb b/python/XX. Practice Sessions-Solutions/03. OOP (With Solutions).ipynb similarity index 100% rename from python/XX. Practice Sessions/03. OOP (With Solutions).ipynb rename to python/XX. Practice Sessions-Solutions/03. OOP (With Solutions).ipynb diff --git a/python/XX. Practice Sessions/04. OOP + Modularization.ipynb b/python/XX. Practice Sessions-Solutions/04. OOP + Modularization.ipynb similarity index 100% rename from python/XX. Practice Sessions/04. OOP + Modularization.ipynb rename to python/XX. Practice Sessions-Solutions/04. OOP + Modularization.ipynb diff --git a/python/XX. Practice Sessions/05. Review.ipynb b/python/XX. Practice Sessions-Solutions/05. Review.ipynb similarity index 100% rename from python/XX. Practice Sessions/05. Review.ipynb rename to python/XX. Practice Sessions-Solutions/05. Review.ipynb diff --git a/python/XX. Practice Sessions/Untitled.ipynb b/python/XX. Practice Sessions-Solutions/Untitled.ipynb similarity index 100% rename from python/XX. Practice Sessions/Untitled.ipynb rename to python/XX. Practice Sessions-Solutions/Untitled.ipynb diff --git a/python/XX. Practice Sessions/file.txt b/python/XX. Practice Sessions-Solutions/file.txt similarity index 100% rename from python/XX. Practice Sessions/file.txt rename to python/XX. Practice Sessions-Solutions/file.txt diff --git a/python/XX. Practice Sessions/geo.py b/python/XX. Practice Sessions-Solutions/geo.py similarity index 100% rename from python/XX. Practice Sessions/geo.py rename to python/XX. Practice Sessions-Solutions/geo.py diff --git a/python/XX. Practice Sessions/01 Data Types + Functions + IO.ipynb b/python/XX. Practice Sessions/01 Data Types + Functions + IO.ipynb new file mode 100755 index 0000000..a309260 --- /dev/null +++ b/python/XX. Practice Sessions/01 Data Types + Functions + IO.ipynb @@ -0,0 +1,249 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 01. Practice Session\n", + "\n", + "> Covering Data Types, Functions, and IO." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. `print` output?\n", + "\n", + "```python\n", + ">>> x, y = [1, 2, 3], ['1', '2', '3']\n", + ">>> print(x*3, y*3)\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Type of `*args` and `**kwargs`?\n", + "\n", + "```python\n", + "def func(a, b, c, ..., *args, **kwargs):\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|Type|Example|\n", + "|:--|:--|\n", + "|Positional Argument|`func(1, 2)`|\n", + "|Keyword Argument|`func(a=1, b=2)`|\n", + "|Infinite Positional Argument|`def func(*args):`|\n", + "|Infinite Keyword Argument|`def func(**kwargs):`|\n", + "|Optional Argument|`def func(a=1, b=2):`|\n", + "|Required Argument|`def func(a, b):`|" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. Define a `tuple` with length = 1.\n", + "\n", + "```python\n", + ">>> mytuple = # code here\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. What is the output where indicated with `# ?`?\n", + "\n", + "```python\n", + ">>> x = ['1', '2', '3']\n", + ">>> y = ''.join(x) # ?\n", + ">>> x = ['1', '2', 3]\n", + ">>> y = ''.join(x) # ?\n", + ">>> y.find(\"1\")\n", + ">>> '1' in x # ?\n", + ">>> '1' in y # ?\n", + ">>> type(x) # ?\n", + ">>> type(y) # ?\n", + ">>> z = x\n", + ">>> z *= 2\n", + ">>> x[0] = 0\n", + ">>> x # ?\n", + ">>> z # ?\n", + ">>> s1 = 'Ali'\n", + ">>> L1 = list(s1) # ?\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 5. Write down the variable value in each line:\n", + "\n", + "```python\n", + ">>> x = [i + 1 for i in range(10)]\n", + ">>> y = [i * 2 for i in x if i > 5]\n", + ">>> z = [(i, i + 1) for i in range(-2, 2) if i % 2 == 0]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```python\n", + ">>> A0 = dict(zip(('a','b','c','d','e'), (1,2,3,4,5)))\n", + ">>> A1 = range(10)\n", + ">>> A2 = [i for i in A1 if i in A0]\n", + ">>> A3 = sorted([A0[s] for s in A0])\n", + ">>> A4 = [i for i in A1 if i in A3]\n", + ">>> A5 = {i:i*i for i in A1}\n", + ">>> A6 = [[i,i*i] for i in A1]\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 6. Let `x = [1, 2, 3, 4]`, `y = [2, 2, 3, 4]`. How do you produce `z = [1, 4, 9, 16]` with list comprehension?\n", + "\n", + "```python\n", + ">>> x = [1, 2, 3, 4]\n", + ">>> y = [1, 2, 3, 4]\n", + "\n", + "z = # code here\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 7. `print` output?\n", + "\n", + "```python\n", + ">>> x = ['foo', [1, 2, 3], 10.4]\n", + ">>> y = x[:]\n", + ">>> y[0] = 'fooooooo'\n", + ">>> y[1][0] = 4\n", + "\n", + ">>> print(x, y, end = '*')\n", + "```\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 8. Output where indicated with `# ?`.\n", + "\n", + "```python\n", + "def f(*args, **kwargs):\n", + " print(args, kwargs)\n", + "\n", + ">>> l = [1, 2, 3]\n", + ">>> t = (4, 5, 6)\n", + ">>> d = {'a':7, 'b':8, 'c':9}\n", + "\n", + ">>> f() # ?\n", + ">>> f(1, 2, 3) # ?\n", + ">>> f(1, 2, 3, \"groovy\") # ?\n", + ">>> f(a=1, b=2, c=3) # ?\n", + "\n", + ">>> f(a=1, b=2, c=3, zzz=\"hi\") # ?\n", + ">>> f(1, 2, 3, a=1, b=2, c=3) # ?\n", + ">>> f(*l, **d) # ?\n", + ">>> f(*t, **d) # ?\n", + ">>> f(1, 2, *t) # ?\n", + ">>> f(q=\"winning\", **d) # ?\n", + ">>> f(1, 2, *t, q=\"winning\", **d) # ?\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 9. Output where indicated with `# ?`.\n", + "\n", + "```python\n", + "def f2(arg1, arg2, *args, **kwargs):\n", + " print(arg1, arg2, args, kwargs)\n", + "\n", + ">>> f2(1, 2, 3) # ?\n", + ">>> f2(1, 2, 3, \"groovy\") # ?\n", + ">>> f2(arg1=1, arg2=2, c=3) # ?\n", + ">>> f2(arg1=1, arg2=2, c=3, zzz=\"hi\") # ?\n", + ">>> f2(1, 2, 3, a=1, b=2, c=3) # ?\n", + ">>> f2(*l, **d) # ?\n", + ">>> f2(*t, **d) # ?\n", + ">>> f2(1, 2, *t) # ?\n", + ">>> f2(1, 1, q=\"winning\", **d) # ?\n", + ">>> f2(1, 2, *t, q=\"winning\", **d) # ?\n", + "```\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 9. Decode Nazis Messages\n", + "\n", + "German Nazis are using a system (Enigma) to encode their messages through transmission. We know that the system shifts every character with a constant number and all chracters are ASCII. For example with a `shift = 2`: \"abcde\" is encrypted to \"cdefg\"\n", + "\n", + "We also know that Germans put the phrase \"Heil Hitler\" in every encrypted message.\n", + "\n", + "1. Write a function that can decode a German message provided a constant shift. Write the decoded message in a `decoded.txt` file.\n", + "2. What is the time and space complexity of decode function? what about your final code?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/python/XX. Practice Sessions/02 OOP.ipynb b/python/XX. Practice Sessions/02 OOP.ipynb new file mode 100755 index 0000000..a7219b3 --- /dev/null +++ b/python/XX. Practice Sessions/02 OOP.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ignored-double", + "metadata": { + "hideCode": false, + "hidePrompt": false, + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "# OOP" + ] + }, + { + "cell_type": "markdown", + "id": "described-treaty", + "metadata": {}, + "source": [ + "1. Create a `Vehicle` class without any variables and methods." + ] + }, + { + "cell_type": "markdown", + "id": "infrared-infrared", + "metadata": { + "hideCode": false, + "hidePrompt": false + }, + "source": [ + "2. Create a `Vehicle` class with `max_speed` and `mileage` instance attributes." + ] + }, + { + "cell_type": "markdown", + "id": "inclusive-century", + "metadata": {}, + "source": [ + "3. Create a child class `Bus` that will inherit all of the variables and methods of the `Vehicle` class\n", + "\n", + "```python\n", + "class Vehicle:\n", + "\n", + " def __init__(self, name, max_speed, mileage):\n", + " self.name = name\n", + " self.max_speed = max_speed\n", + " self.mileage = mileage\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "talented-history", + "metadata": {}, + "source": [ + "4. Create a `Bus` class that inherits from the `Vehicle` class. Give the capacity argument of `Bus.seating_capacity()` a default value of 50.\n", + "\n", + "Use the following code for your parent `Vehicle` class. You need to use method overriding.\n", + "\n", + "```python\n", + "class Vehicle:\n", + " def __init__(self, name, max_speed, mileage):\n", + " self.name = name\n", + " self.max_speed = max_speed\n", + " self.mileage = mileage\n", + "\n", + " def seating_capacity(self, capacity):\n", + " return f\"The seating capacity of a {self.name} is {capacity} passengers\"\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "sized-darwin", + "metadata": {}, + "source": [ + "5. Define a property `color` that should have the same value for every class instance\n", + "\n", + "Use the following code for this exercise.\n", + "```python\n", + "class Vehicle:\n", + "\n", + " def __init__(self, name, max_speed, mileage):\n", + " self.name = name\n", + " self.max_speed = max_speed\n", + " self.mileage = mileage\n", + "\n", + "class Bus(Vehicle):\n", + " pass\n", + "\n", + "class Car(Vehicle):\n", + " pass\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "pleasant-citizen", + "metadata": {}, + "source": [ + "6. Create a `Bus` child class that inherits from the `Vehicle` class. The default fare charge of any vehicle is `seating capacity * 100`. If `Vehicle` is `Bus` instance, we need to add an extra 10% on full fare as a maintenance charge. So total fare for bus instance will become the `final amount = total fare + 10%` of the total fare\n", + "\n", + "```python\n", + "class Vehicle:\n", + " def __init__(self, name, mileage, capacity):\n", + " self.name = name\n", + " self.mileage = mileage\n", + " self.capacity = capacity\n", + "\n", + " def fare(self):\n", + " return self.capacity * 100\n", + "\n", + "class Bus(Vehicle):\n", + " pass\n", + "\n", + "school_bus = Bus(\"school Bus\", 12, 50)\n", + "print(\"Total Bus fare is:\", school_bus.fare())\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "realistic-department", + "metadata": {}, + "source": [ + "**Note:** The bus seating capacity is 50. so the final fare amount should be 5500. You need to override the fare() method of a Vehicle class in Bus class." + ] + }, + { + "cell_type": "markdown", + "id": "accurate-warning", + "metadata": {}, + "source": [ + "7. Determine if `school_bus` is also an instance of the `Vehicle` class" + ] + } + ], + "metadata": { + "hide_code_all_hidden": false, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/XX. Practice Sessions/03 OOP + Modularization.ipynb b/python/XX. Practice Sessions/03 OOP + Modularization.ipynb new file mode 100755 index 0000000..4f1a080 --- /dev/null +++ b/python/XX. Practice Sessions/03 OOP + Modularization.ipynb @@ -0,0 +1,82 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "moved-visibility", + "metadata": {}, + "source": [ + "# OOP and Modularization" + ] + }, + { + "cell_type": "markdown", + "id": "supreme-discovery", + "metadata": {}, + "source": [ + "1. Given an list of points where `points[i] = Point(xi, yi)` represents a point on the X-Y plane and an integer `k`, return the `k` closest points to the origin `(0, 0)`.\n", + "\n", + "The distance between two points on the X-Y plane is the Euclidean distance (i.e, $\\sqrt{x_1^2 + y_1^2)}$.\n", + "\n", + "```python\n", + "class Point:\n", + " pass\n", + "\n", + "mylist = [Point(3, 4), Point(6, 8), Point(2, 2), Point(9, 11)]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "public-fusion", + "metadata": {}, + "source": [ + "2. Define `__str__` and `__repr__` dunder methods." + ] + }, + { + "cell_type": "markdown", + "id": "demonstrated-constitution", + "metadata": {}, + "source": [ + "Read [Python String Conversion 101: Why Every Class Needs a “repr”](https://dbader.org/blog/python-repr-vs-str) for a complete tutorial on `__repr__` and the difference between `__repr__` and `__str__`." + ] + }, + { + "cell_type": "markdown", + "id": "renewable-estonia", + "metadata": {}, + "source": [ + "3. Extend your class to `n` dimensions ($\\sqrt[2]{x_1^2 + x_2^2 + ... + x_n^2}$)" + ] + }, + { + "cell_type": "markdown", + "id": "warming-neighborhood", + "metadata": {}, + "source": [ + "4. Write your class in a module named `geo.py` and import it." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/XX. Practice Sessions/04 Review.ipynb b/python/XX. Practice Sessions/04 Review.ipynb new file mode 100755 index 0000000..3020b8a --- /dev/null +++ b/python/XX. Practice Sessions/04 Review.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "adopted-latino", + "metadata": {}, + "source": [ + "# 05. Review" + ] + }, + { + "cell_type": "markdown", + "id": "regulation-passport", + "metadata": {}, + "source": [ + "### 1. Write a function that receives an iterable and an item, returns `True` if the item exists in iterable, `False` if it does not.\n", + "\n", + "**Note:** You should not use `item in mylist`. Use a for loop instead.\n", + "\n", + "```python\n", + "def search(iterable, item):\n", + " # code here\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "chinese-surprise", + "metadata": {}, + "source": [ + "### 2. Write the previous function with `for else`." + ] + }, + { + "cell_type": "markdown", + "id": "dense-italian", + "metadata": {}, + "source": [ + "### 3. Which one is more efficient? Why?\n", + "\n", + "1.\n", + "```python\n", + "for key in mydict:\n", + " print(key, mydict[key])\n", + "```\n", + "\n", + "2.\n", + "```python\n", + "for key, value in mydict:\n", + " print(key, value)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "mineral-proof", + "metadata": {}, + "source": [ + "### 4. Write a code that counts the number of items in an iterable.\n", + "\n", + "```python\n", + "mylist = ['red', 'green', 'red', 'blue', 'green', 'red', 'red', 'red', 'blue', 'blue']\n", + "```\n", + "\n", + "Output should look like this:\n", + "```python\n", + "{\n", + " 'red': 5,\n", + " 'green': 2,\n", + " 'blue': 3'\n", + "}\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "raising-mercy", + "metadata": {}, + "source": [ + "### 5. Write a function that generates passwords and a function that checks if a password is valid.\n", + "\n", + "Password requirements:\n", + "- Length > 8\n", + "- Have at least 1 capital letter.\n", + "- Have at least 1 non numeric/alphabetic characters.\n", + "\n", + "```python\n", + "def generate_password():\n", + " # code here\n", + "\n", + "def check_password(password):\n", + " # code here\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "specific-pride", + "metadata": {}, + "source": [ + "### 6. What is the output in lines indicated by `#?`? Why?\n", + "\n", + "```python\n", + "def add_employee(emp, emp_list=[]):\n", + " emp_list.append(emp)\n", + " \n", + " return emp_list\n", + "\n", + "add_employee(\"Name 1\") #?\n", + "add_employee(\"Name 2\") #?\n", + "add_employee(\"Name 3\") #?\n", + "```\n", + "\n", + "##### If there are unexpected results, what is your solution?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 2f33c8430291eecf9bd32d12b988385446d5b3d7 Mon Sep 17 00:00:00 2001 From: Ali Hejazizo Date: Sat, 4 Dec 2021 13:11:50 -0700 Subject: [PATCH 04/31] updated basics with new TOC --- python/01. Basics/00 Introduction.ipynb | 186 +- python/01. Basics/01 Setup.ipynb | 215 +- python/01. Basics/02 Conda Environments.ipynb | 821 +- .../03 Interacting with Python.ipynb | 611 +- python/01. Basics/04 Basic Data Types.ipynb | 1532 +- python/01. Basics/05 Variables.ipynb | 1123 +- .../06 Operators and Expressions.ipynb | 1634 +- python/01. Basics/07 Strings.ipynb | 2193 +-- ...mposite Data Types: Lists and Tuples.ipynb | 4189 +---- .../09 Composite Data Types: Dictionary.ipynb | 1415 +- .../10 Composite Data Types: Sets.ipynb | 666 +- .../11 Python Program Lexical Structure.ipynb | 1859 +- .../12 Conditional Statements in Python.ipynb | 1556 +- ...hile\" Loops (Indefinite Iteration).ipynb" | 13972 +--------------- ... \"for\" Loops (Definite Iteration).ipynb" | 1672 +- python/01. Basics/15 List Comprehension.ipynb | 954 +- ...put, and String Formatting in Python.ipynb | 730 +- ...ewer Python String Format Techniques.ipynb | 4329 +---- ...18 Defining Your Own Python Function.ipynb | 5699 +------ .../19 Namespaces and Scope in Python.ipynb | 4464 +---- python/01. Basics/tmp.txt | 7 - ...11 Data Types: An Array of Sequences.ipynb | 455 - .../tmp/13 Operators & Statements.ipynb | 1379 -- python/01. Basics/tmp/14 IO Operations.ipynb | 849 - python/01. Basics/tmp/Functions.ipynb | 1881 --- python/01. Basics/tmp/Text vs. Bytes.ipynb | 69 - python/01. Basics/tmp/string methods.ipynb | 2391 --- 27 files changed, 20 insertions(+), 56831 deletions(-) delete mode 100755 python/01. Basics/tmp.txt delete mode 100755 python/01. Basics/tmp/11 Data Types: An Array of Sequences.ipynb delete mode 100755 python/01. Basics/tmp/13 Operators & Statements.ipynb delete mode 100755 python/01. Basics/tmp/14 IO Operations.ipynb delete mode 100755 python/01. Basics/tmp/Functions.ipynb delete mode 100755 python/01. Basics/tmp/Text vs. Bytes.ipynb delete mode 100755 python/01. Basics/tmp/string methods.ipynb diff --git a/python/01. Basics/00 Introduction.ipynb b/python/01. Basics/00 Introduction.ipynb index dd798b6..1c9ef75 100755 --- a/python/01. Basics/00 Introduction.ipynb +++ b/python/01. Basics/00 Introduction.ipynb @@ -1,185 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Introduction\n", - "\n", - "- Python was created in 1990 by [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum).\n", - "- Python 3 released in 2008.\n", - "- Specifically designed as an easy to use language.\n", - "- High focus on readability of code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python is a high-level, interpreted scripting language developed in the late 1980s by Guido van Rossum at the National Research Institute for Mathematics and Computer Science in the Netherlands. The initial version was published at the alt.sources newsgroup in 1991, and version 1.0 was released in 1994." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python 2.0 was released in 2000, and the 2.x versions were the prevalent releases until December 2008. At that time, the development team made the decision to release version 3.0, which contained a few relatively small but significant changes that were not backward compatible with the 2.x versions. Python 2 and 3 are very similar, and some features of Python 3 have been backported to Python 2. But in general, they remain not quite compatible." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Both Python 2 and 3 have continued to be maintained and developed, with periodic release updates for both. As of this writing, the most recent versions available are 2.7.15 and 3.6.5. However, an official [End Of Life date of January 1, 2020](https://pythonclock.org/) has been established for Python 2, after which time it will no longer be maintained. If you are a newcomer to Python, it is recommended that you focus on Python 3, as this tutorial will do." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python is still maintained by a core development team at the Institute, and Guido is still in charge, having been given the title of BDFL (Benevolent Dictator For Life) by the Python community. The name Python, by the way, derives not from the snake, but from the British comedy troupe [Monty Python’s Flying Circus](https://en.wikipedia.org/wiki/Monty_Python%27s_Flying_Circus), of which Guido was, and presumably still is, a fan. It is common to find references to Monty Python sketches and movies scattered throughout the Python documentation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Why Choose Python\n", - "\n", - "If you’re going to write programs, there are literally dozens of commonly used languages to choose from. Why choose Python? Here are some of the features that make Python an appealing choice." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python is Popular\n", - "Python has been growing in popularity over the last few years. The [2018 Stack Overflow Developer Survey](https://insights.stackoverflow.com/survey/2018) ranked Python as the 7th most popular and the number one most wanted technology of the year. [World-class software development companies around the globe use Python every single day](https://realpython.com/world-class-companies-using-python/).\n", - "\n", - "According to [research by Dice](https://insights.dice.com/2016/02/01/whats-hot-and-not-in-tech-skills/) Python is also one of the hottest skills to have and the most popular programming language in the world based on the [Popularity of Programming Language Index](https://pypl.github.io/PYPL.html).\n", - "\n", - "Due to the popularity and widespread use of Python as a programming language, Python developers are sought after and paid well. If you’d like to dig deeper into [Python salary statistics and job opportunities, you can do so here](https://dbader.org/blog/why-learn-python)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python is Interpreted\n", - "Many languages are compiled, meaning the source code you create needs to be translated into machine code, the language of your computer’s processor, before it can be run. Programs written in an interpreted language are passed straight to an interpreter that runs them directly.\n", - "\n", - "This makes for a quicker development cycle because you just type in your code and run it, without the intermediate compilation step.\n", - "\n", - "One potential downside to interpreted languages is execution speed. Programs that are compiled into the native language of the computer processor tend to run more quickly than interpreted programs. For some applications that are particularly computationally intensive, like graphics processing or intense number crunching, this can be limiting.\n", - "\n", - "In practice, however, for most programs, the difference in execution speed is measured in milliseconds, or seconds at most, and not appreciably noticeable to a human user. The expediency of coding in an interpreted language is typically worth it for most applications." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Further Reading:** See this Wikipedia page to read more about the differences between interpreted and compiled languages." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python is Free\n", - "The Python interpreter is developed under an OSI-approved open-source license, making it free to install, use, and distribute, even for commercial purposes.\n", - "\n", - "A version of the interpreter is available for virtually any platform there is, including all flavors of Unix, Windows, macOS, smartphones and tablets, and probably anything else you ever heard of. A version even exists for the half dozen people remaining who use OS/2." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python is Portable\n", - "Because Python code is interpreted and not compiled into native machine instructions, code written for one platform will work on any other platform that has the Python interpreter installed. (This is true of any interpreted language, not just Python.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python is Simple\n", - "As programming languages go, Python is relatively uncluttered, and the developers have deliberately kept it that way.\n", - "\n", - "A rough estimate of the complexity of a language can be gleaned from the number of keywords or reserved words in the language. These are words that are reserved for special meaning by the compiler or interpreter because they designate specific built-in functionality of the language.\n", - "\n", - "Python 3 has 33 keywords, and Python 2 has 31. By contrast, C++ has 62, Java has 53, and Visual Basic has more than 120, though these latter examples probably vary somewhat by implementation or dialect.\n", - "\n", - "Python code has a simple and clean structure that is easy to learn and easy to read. In fact, as you will see, the language definition enforces code structure that is easy to read." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### But It’s Not That Simple\n", - "For all its syntactical simplicity, Python supports most constructs that would be expected in a very high-level language, including complex dynamic data types, structured and functional programming, and [object-oriented programming](https://realpython.com/python3-object-oriented-programming/).\n", - "\n", - "Additionally, a very extensive library of classes and functions is available that provides capability well beyond what is built into the language, such as database manipulation or GUI programming.\n", - "\n", - "Python accomplishes what many programming languages don’t: the language itself is simply designed, but it is very versatile in terms of what you can accomplish with it." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## What can you do with python?\n", - "- Automate Simple tasks.\n", - " * Searching for file and editing them.\n", - " * Scraping information from a website.\n", - " * Reading and editing excel files.\n", - " * Work with PDFs.\n", - " * Automate emails and text messages.\n", - " * Fill out Form.\n", - "- Data science and machine learning.\n", - " * Analyze large data files.\n", - " * Create visualizations.\n", - " * Perform machine learning tasks.\n", - " * Create and run predictive algorithms.\n", - "- Create websites.\n", - " * Use web frameworks such as Django and Flask to handle the backend of a website and user data.\n", - " * Create interactive dashboards for users. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "This section gave an overview of the Python programming language, including:\n", - "\n", - "A brief history of the development of Python\n", - "Some reasons why you might select Python as your language of choice\n", - "Python is a great option, whether you are a beginning programmer looking to learn the basics, an experienced programmer designing a large application, or anywhere in between. The basics of Python are easily grasped, and yet its capabilities are vast." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Introduction\n", "\n", "- Python was created in 1990 by [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum).\n", "- Python 3 released in 2008.\n", "- Specifically designed as an easy to use language.\n", "- High focus on readability of code."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Why Choose Python](#why_choose_python)\n * [Python is Popular](#python_is_popular)\n * [Python is Interpreted](#python_is_interpreted)\n * [Python is Free](#python_is_free)\n * [Python is Portable](#python_is_portable)\n * [Python is Simple](#python_is_simple)\n * [But It\u2019s Not That Simple](#but_it\u2019s_not_that_simple)\n* [What can you do with python?](#what_can_you_do_with_python?)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python is a high-level, interpreted scripting language developed in the late 1980s by Guido van Rossum at the National Research Institute for Mathematics and Computer Science in the Netherlands. The initial version was published at the alt.sources newsgroup in 1991, and version 1.0 was released in 1994."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python 2.0 was released in 2000, and the 2.x versions were the prevalent releases until December 2008. At that time, the development team made the decision to release version 3.0, which contained a few relatively small but significant changes that were not backward compatible with the 2.x versions. Python 2 and 3 are very similar, and some features of Python 3 have been backported to Python 2. But in general, they remain not quite compatible."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Both Python 2 and 3 have continued to be maintained and developed, with periodic release updates for both. As of this writing, the most recent versions available are 2.7.15 and 3.6.5. However, an official [End Of Life date of January 1, 2020](https://pythonclock.org/) has been established for Python 2, after which time it will no longer be maintained. If you are a newcomer to Python, it is recommended that you focus on Python 3, as this tutorial will do."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python is still maintained by a core development team at the Institute, and Guido is still in charge, having been given the title of BDFL (Benevolent Dictator For Life) by the Python community. The name Python, by the way, derives not from the snake, but from the British comedy troupe [Monty Python\u2019s Flying Circus](https://en.wikipedia.org/wiki/Monty_Python%27s_Flying_Circus), of which Guido was, and presumably still is, a fan. It is common to find references to Monty Python sketches and movies scattered throughout the Python documentation."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Why Choose Python\n", "\n", "If you\u2019re going to write programs, there are literally dozens of commonly used languages to choose from. Why choose Python? Here are some of the features that make Python an appealing choice."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Python is Popular\n", "Python has been growing in popularity over the last few years. The [2018 Stack Overflow Developer Survey](https://insights.stackoverflow.com/survey/2018) ranked Python as the 7th most popular and the number one most wanted technology of the year. [World-class software development companies around the globe use Python every single day](https://realpython.com/world-class-companies-using-python/).\n", "\n", "According to [research by Dice](https://insights.dice.com/2016/02/01/whats-hot-and-not-in-tech-skills/) Python is also one of the hottest skills to have and the most popular programming language in the world based on the [Popularity of Programming Language Index](https://pypl.github.io/PYPL.html).\n", "\n", "Due to the popularity and widespread use of Python as a programming language, Python developers are sought after and paid well. If you\u2019d like to dig deeper into [Python salary statistics and job opportunities, you can do so here](https://dbader.org/blog/why-learn-python)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Python is Interpreted\n", "Many languages are compiled, meaning the source code you create needs to be translated into machine code, the language of your computer\u2019s processor, before it can be run. Programs written in an interpreted language are passed straight to an interpreter that runs them directly.\n", "\n", "This makes for a quicker development cycle because you just type in your code and run it, without the intermediate compilation step.\n", "\n", "One potential downside to interpreted languages is execution speed. Programs that are compiled into the native language of the computer processor tend to run more quickly than interpreted programs. For some applications that are particularly computationally intensive, like graphics processing or intense number crunching, this can be limiting.\n", "\n", "In practice, however, for most programs, the difference in execution speed is measured in milliseconds, or seconds at most, and not appreciably noticeable to a human user. The expediency of coding in an interpreted language is typically worth it for most applications."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Further Reading:** See this Wikipedia page to read more about the differences between interpreted and compiled languages."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Python is Free\n", "The Python interpreter is developed under an OSI-approved open-source license, making it free to install, use, and distribute, even for commercial purposes.\n", "\n", "A version of the interpreter is available for virtually any platform there is, including all flavors of Unix, Windows, macOS, smartphones and tablets, and probably anything else you ever heard of. A version even exists for the half dozen people remaining who use OS/2."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Python is Portable\n", "Because Python code is interpreted and not compiled into native machine instructions, code written for one platform will work on any other platform that has the Python interpreter installed. (This is true of any interpreted language, not just Python.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Python is Simple\n", "As programming languages go, Python is relatively uncluttered, and the developers have deliberately kept it that way.\n", "\n", "A rough estimate of the complexity of a language can be gleaned from the number of keywords or reserved words in the language. These are words that are reserved for special meaning by the compiler or interpreter because they designate specific built-in functionality of the language.\n", "\n", "Python 3 has 33 keywords, and Python 2 has 31. By contrast, C++ has 62, Java has 53, and Visual Basic has more than 120, though these latter examples probably vary somewhat by implementation or dialect.\n", "\n", "Python code has a simple and clean structure that is easy to learn and easy to read. In fact, as you will see, the language definition enforces code structure that is easy to read."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### But It\u2019s Not That Simple\n", "For all its syntactical simplicity, Python supports most constructs that would be expected in a very high-level language, including complex dynamic data types, structured and functional programming, and [object-oriented programming](https://realpython.com/python3-object-oriented-programming/).\n", "\n", "Additionally, a very extensive library of classes and functions is available that provides capability well beyond what is built into the language, such as database manipulation or GUI programming.\n", "\n", "Python accomplishes what many programming languages don\u2019t: the language itself is simply designed, but it is very versatile in terms of what you can accomplish with it."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## What can you do with python?\n", "- Automate Simple tasks.\n", " * Searching for file and editing them.\n", " * Scraping information from a website.\n", " * Reading and editing excel files.\n", " * Work with PDFs.\n", " * Automate emails and text messages.\n", " * Fill out Form.\n", "- Data science and machine learning.\n", " * Analyze large data files.\n", " * Create visualizations.\n", " * Perform machine learning tasks.\n", " * Create and run predictive algorithms.\n", "- Create websites.\n", " * Use web frameworks such as Django and Flask to handle the backend of a website and user data.\n", " * Create interactive dashboards for users. "]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "This section gave an overview of the Python programming language, including:\n", "\n", "A brief history of the development of Python\n", "Some reasons why you might select Python as your language of choice\n", "Python is a great option, whether you are a beginning programmer looking to learn the basics, an experienced programmer designing a large application, or anywhere in between. The basics of Python are easily grasped, and yet its capabilities are vast."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/01 Setup.ipynb b/python/01. Basics/01 Setup.ipynb index af9e91f..46d63c0 100755 --- a/python/01. Basics/01 Setup.ipynb +++ b/python/01. Basics/01 Setup.ipynb @@ -1,214 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Python 3 Installation & Setup Guide\n", - "\n", - "## Table of Contents\n", - "* [1. Operating System Setup](#os-setup)\n", - "* [2. Setting up Python with Conda](#python-setup-with-conda)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Installing or updating Python on your computer is the first step to becoming a Python programmer. There are a multitude of installation methods: you can download official Python distributions from Python.org, install from a package manager, and even install specialized distributions for scientific computing, Internet of Things, and embedded systems." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This tutorial focuses on install from a package manager, as they’re generally the best option for full control in programming with python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## 1. Operating System Setup" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Windows" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are three installation methods on Windows:\n", - "\n", - "- **The Microsoft Store:** Microsoft Store package: The most straightforward installation method on Windows involves installing from the Microsoft Store app. This is recommended for beginner Python users looking for an easy-to-set-up interactive experience.\n", - "\n", - "- **Full Installer:** This approach involves downloading Python directly from the [Python.org](https://www.python.org/) website. This is recommended for intermediate and advanced developers who need more control during the setup process.\n", - "\n", - "- **Windows Subsystem for Linux (WSL):** The WSL allows you to run a Linux environment directly in Windows. You can learn how to enable the WSL by reading the[ Windows Subsystem for Linux Installation Guide for Windows 10](https://docs.microsoft.com/en-us/windows/wsl/install-win10)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In these series of tutorials, we follow the 3rd method by running Linux in Windows. The WSL allows you to run a Linux environment directly in Windows. You can also learn how to enable the WSL by reading the [Windows Subsystem for Linux Installation Guide for Windows 10](https://docs.microsoft.com/en-us/windows/wsl/install-win10) or follow the line above, both are good quality guides." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After installing WSL, follow the next section on **Conda Environments**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Linux and Mac" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you are in Mac or Linux, you are already set up and ready to go to the next section on **Conda Environments**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## 2. Setting up Python with Conda\n", - "\n", - "Python has been largely used for numerical and scientific applications in the last years. However, to perform numerical computations in an efficient manner, Python relies on external libraries, sometimes implemented in other languages, such as the NumPy library, which is partly implemented using the Fortran language." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Due to these dependencies, sometimes it isn’t trivial to set up an environment for numerical computations, linking all the necessary libraries. It’s common for people to struggle to get things working in workshops involving the use of Python for machine learning, especially when they are using an operating system that lacks a package management system, such as Windows." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Introducing Anaconda and Conda" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since 2011, Python has included [`pip`](https://pypi.org/project/pip/), a package management system used to install and manage software packages written in Python. However, for numerical computations, there are several dependencies that are not written in Python, so the initial releases of pip could not solve the problem by themselves." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To circumvent this problem, Continuum Analytics released [Anaconda](https://www.anaconda.com/distribution/), a Python distribution focused on scientific applications and [Conda](https://conda.io/), a package and environment management system, which is used by the Anaconda distribution. It’s worth noticing that the more recent versions of pip can handle external dependencies using [wheels](https://www.python.org/dev/peps/pep-0427/), but, by using Anaconda, you’ll be able to install critical libraries for data science more smoothly. (You can read more on this discussion [here](http://jakevdp.github.io/blog/2016/08/25/conda-myths-and-misconceptions/#Myth-#6:-Now-that-pip-uses-wheels,-conda-is-no-longer-necessary).)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Although Conda is tightly coupled to the Anaconda Python Distribution, the two are distinct projects with different goals:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- [**Anaconda**](https://www.anaconda.com/distribution/) is a full distribution of the software in the [PyData](https://pydata.org/) ecosystem, including Python itself along with binaries for several third-party open-source projects. Besides Anaconda, there’s also [Miniconda](https://conda.io/miniconda.html), which is a minimal Python distribution including basically Conda and its dependencies so that you can install only the packages you need, from scratch" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- [**Conda**](https://conda.io/) is a package, dependency, and environment management system that could be installed without the Anaconda or Miniconda distribution. It runs on Windows, macOS, and Linux and was created for Python programs, but it can package and distribute software for any language. The main purpose is to solve external dependencies issues in an easy way, by downloading pre-compiled versions of software.\n", - "\n", - " In this sense, it is more like a cross-platform version of a general purpose package manager such as [APT](https://en.wikipedia.org/wiki/APT_(Debian)) or [YUM](https://en.wikipedia.org/wiki/Yum_(software)), which helps to find and install packages in a language-agnostic way. Also, Conda is an environment manager, so if you need a package that requires a different version of Python, by using Conda, it is possible to set up a separate environment with a totally different version of Python, maintaining your usual version of Python on your default environment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There’s a lot of discussion regarding the creation of another package management system for the Python ecosystem. It’s worth mentioning that Conda’s creators pushed Python standard packaging to the limit and only created a second tool when it was clear that it was the only reasonable way forward." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Anaconda and Miniconda have become the most popular Python distributions, widely used for data science and machine learning in various companies and research laboratories. They are free and open source projects and currently include 1400+ packages in the repository. In the following section, we’ll go through the installation of the Miniconda Python distribution on a Windows machine." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How to install **Anaconda**\n", - "\n", - "1. Install Anaconda for your OS:\n", - " - [Anaconda Installation Tutorial for Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-the-anaconda-python-distribution-on-ubuntu-20-04)\n", - " - [Anaconda Installation Tutorial for Mac](https://docs.anaconda.com/anaconda/install/mac-os/)\n", - "\n", - "Anaconda installs Python and is an easy to use development environment and navigator launch tool.\n", - "\n", - "You will learn how to interact with conda and install python and packages in the next section." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In case `conda` is not recognized after installation like the image below, run the following commands:\n", - "- `source ~/anaconda3/etc/profile.d/conda.sh`\n", - "- `conda init bash`\n", - "\n", - "and restart your terminal." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"notebook\"" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Python 3 Installation & Setup Guide"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [1. Operating System Setup](#1._operating_system_setup)\n * [Windows](#windows)\n * [Linux and Mac](#linux_and_mac)\n* [2. Setting up Python with Conda](#2._setting_up_python_with_conda)\n * [Introducing Anaconda and Conda](#introducing_anaconda_and_conda)\n * [How to install **Anaconda**](#how_to_install_**anaconda**)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Installing or updating Python on your computer is the first step to becoming a Python programmer. There are a multitude of installation methods: you can download official Python distributions from Python.org, install from a package manager, and even install specialized distributions for scientific computing, Internet of Things, and embedded systems."]}, {"cell_type": "markdown", "metadata": {}, "source": ["This tutorial focuses on install from a package manager, as they\u2019re generally the best option for full control in programming with python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["\n", "\n", "## 1. Operating System Setup"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Windows"]}, {"cell_type": "markdown", "metadata": {}, "source": ["There are three installation methods on Windows:\n", "\n", "- **The Microsoft Store:** Microsoft Store package: The most straightforward installation method on Windows involves installing from the Microsoft Store app. This is recommended for beginner Python users looking for an easy-to-set-up interactive experience.\n", "\n", "- **Full Installer:** This approach involves downloading Python directly from the [Python.org](https://www.python.org/) website. This is recommended for intermediate and advanced developers who need more control during the setup process.\n", "\n", "- **Windows Subsystem for Linux (WSL):** The WSL allows you to run a Linux environment directly in Windows. You can learn how to enable the WSL by reading the[ Windows Subsystem for Linux Installation Guide for Windows 10](https://docs.microsoft.com/en-us/windows/wsl/install-win10)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In these series of tutorials, we follow the 3rd method by running Linux in Windows. The WSL allows you to run a Linux environment directly in Windows. You can also learn how to enable the WSL by reading the [Windows Subsystem for Linux Installation Guide for Windows 10](https://docs.microsoft.com/en-us/windows/wsl/install-win10) or follow the line above, both are good quality guides."]}, {"cell_type": "markdown", "metadata": {}, "source": ["After installing WSL, follow the next section on **Conda Environments**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Linux and Mac"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you are in Mac or Linux, you are already set up and ready to go to the next section on **Conda Environments**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["\n", "\n", "## 2. Setting up Python with Conda\n", "\n", "Python has been largely used for numerical and scientific applications in the last years. However, to perform numerical computations in an efficient manner, Python relies on external libraries, sometimes implemented in other languages, such as the NumPy library, which is partly implemented using the Fortran language."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Due to these dependencies, sometimes it isn\u2019t trivial to set up an environment for numerical computations, linking all the necessary libraries. It\u2019s common for people to struggle to get things working in workshops involving the use of Python for machine learning, especially when they are using an operating system that lacks a package management system, such as Windows."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Introducing Anaconda and Conda"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Since 2011, Python has included [`pip`](https://pypi.org/project/pip/), a package management system used to install and manage software packages written in Python. However, for numerical computations, there are several dependencies that are not written in Python, so the initial releases of pip could not solve the problem by themselves."]}, {"cell_type": "markdown", "metadata": {}, "source": ["To circumvent this problem, Continuum Analytics released [Anaconda](https://www.anaconda.com/distribution/), a Python distribution focused on scientific applications and [Conda](https://conda.io/), a package and environment management system, which is used by the Anaconda distribution. It\u2019s worth noticing that the more recent versions of pip can handle external dependencies using [wheels](https://www.python.org/dev/peps/pep-0427/), but, by using Anaconda, you\u2019ll be able to install critical libraries for data science more smoothly. (You can read more on this discussion [here](http://jakevdp.github.io/blog/2016/08/25/conda-myths-and-misconceptions/#Myth-#6:-Now-that-pip-uses-wheels,-conda-is-no-longer-necessary).)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Although Conda is tightly coupled to the Anaconda Python Distribution, the two are distinct projects with different goals:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- [**Anaconda**](https://www.anaconda.com/distribution/) is a full distribution of the software in the [PyData](https://pydata.org/) ecosystem, including Python itself along with binaries for several third-party open-source projects. Besides Anaconda, there\u2019s also [Miniconda](https://conda.io/miniconda.html), which is a minimal Python distribution including basically Conda and its dependencies so that you can install only the packages you need, from scratch"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- [**Conda**](https://conda.io/) is a package, dependency, and environment management system that could be installed without the Anaconda or Miniconda distribution. It runs on Windows, macOS, and Linux and was created for Python programs, but it can package and distribute software for any language. The main purpose is to solve external dependencies issues in an easy way, by downloading pre-compiled versions of software.\n", "\n", " In this sense, it is more like a cross-platform version of a general purpose package manager such as [APT](https://en.wikipedia.org/wiki/APT_(Debian)) or [YUM](https://en.wikipedia.org/wiki/Yum_(software)), which helps to find and install packages in a language-agnostic way. Also, Conda is an environment manager, so if you need a package that requires a different version of Python, by using Conda, it is possible to set up a separate environment with a totally different version of Python, maintaining your usual version of Python on your default environment."]}, {"cell_type": "markdown", "metadata": {}, "source": ["There\u2019s a lot of discussion regarding the creation of another package management system for the Python ecosystem. It\u2019s worth mentioning that Conda\u2019s creators pushed Python standard packaging to the limit and only created a second tool when it was clear that it was the only reasonable way forward."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Anaconda and Miniconda have become the most popular Python distributions, widely used for data science and machine learning in various companies and research laboratories. They are free and open source projects and currently include 1400+ packages in the repository. In the following section, we\u2019ll go through the installation of the Miniconda Python distribution on a Windows machine."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### How to install **Anaconda**\n", "\n", "1. Install Anaconda for your OS:\n", " - [Anaconda Installation Tutorial for Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-the-anaconda-python-distribution-on-ubuntu-20-04)\n", " - [Anaconda Installation Tutorial for Mac](https://docs.anaconda.com/anaconda/install/mac-os/)\n", "\n", "Anaconda installs Python and is an easy to use development environment and navigator launch tool.\n", "\n", "You will learn how to interact with conda and install python and packages in the next section."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In case `conda` is not recognized after installation like the image below, run the following commands:\n", "- `source ~/anaconda3/etc/profile.d/conda.sh`\n", "- `conda init bash`\n", "\n", "and restart your terminal."]}, {"cell_type": "markdown", "metadata": {}, "source": ["\"notebook\""]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/02 Conda Environments.ipynb b/python/01. Basics/02 Conda Environments.ipynb index 1ff6137..74d4bd5 100755 --- a/python/01. Basics/02 Conda Environments.ipynb +++ b/python/01. Basics/02 Conda Environments.ipynb @@ -1,820 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d4a95e9d", - "metadata": {}, - "source": [ - "# Conda Environments" - ] - }, - { - "cell_type": "markdown", - "id": "scheduled-witness", - "metadata": {}, - "source": [ - "## Table of Contents\n", - "* [1. Understanding Conda Environments](#u-conda-environments)\n", - "* [2. Understanding Basic Package Management With Conda](#basic-package-management)\n", - " * [2.1 Searching and Installing Packages](#search-install-packager)\n", - " * [2.2 Updating and Removing Packages](#u-r-packages)\n", - "* [3. Cheat Sheet](#cheat-sheet)\n", - "* [4. Read More](#read-more)" - ] - }, - { - "cell_type": "markdown", - "id": "successful-abortion", - "metadata": {}, - "source": [ - " \n", - "## Understanding Conda Environments" - ] - }, - { - "cell_type": "markdown", - "id": "reported-recovery", - "metadata": {}, - "source": [ - "When you start developing a project from scratch, it’s recommended that you use the latest versions of the libraries you need. However, when working with someone else’s project, such as when running an example from [Kaggle](https://www.kaggle.com/) or [Github](https://github.com/), you may need to install specific versions of packages or even another version of Python due to compatibility issues." - ] - }, - { - "cell_type": "markdown", - "id": "critical-tenant", - "metadata": {}, - "source": [ - "This problem may also occur when you try to run an application you’ve developed long ago, which uses a particular library version that does not work with your application anymore due to updates." - ] - }, - { - "cell_type": "markdown", - "id": "lovely-korea", - "metadata": {}, - "source": [ - "Virtual environments are a solution to this kind of problem. By using them, it is possible to create multiple environments, each one with different versions of packages. A typical Python set up includes [Virtualenv](https://virtualenv.pypa.io/en/stable/#), a tool to create isolated Python virtual environments, widely used in the Python community." - ] - }, - { - "cell_type": "markdown", - "id": "frozen-pavilion", - "metadata": {}, - "source": [ - "Conda includes its own environment manager and presents some advantages over Virtualenv, especially concerning numerical applications, such as the ability to manage non-Python dependencies and the ability to manage different versions of Python, which is not possible with Virtualenv. Besides that, Conda environments are entirely compatible with default [Python packages](https://realpython.com/python-modules-packages/) that may be installed using pip." - ] - }, - { - "cell_type": "markdown", - "id": "latter-bankruptcy", - "metadata": {}, - "source": [ - "Miniconda installation provides Conda and a root environment with a version of Python and some basic packages installed. Besides this root environment, it is possible to set up additional environments including different versions of Python and packages." - ] - }, - { - "cell_type": "markdown", - "id": "inner-allowance", - "metadata": {}, - "source": [ - "Using the Anaconda prompt, it is possible to check the available Conda environments by running `conda env list`:\n", - "\n", - "```bash\n", - "\n", - "$ (base) ~ % conda env list\n", - "\n", - "# conda environments:\n", - "#\n", - "base * /home/ali/anaconda3\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "lasting-prevention", - "metadata": {}, - "source": [ - "This base environment is the root environment, created by the Miniconda installer. It is possible to create another environment, named `otherenv`, by running `conda create --name otherenv`:\n", - "\n", - "\n", - "```bash\n", - "$ (base) ~ % conda create --name otherenv\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\otherenv\n", - "\n", - "\n", - "Proceed ([y]/n)? y\n", - "\n", - "Preparing transaction: done\n", - "Verifying transaction: done\n", - "Executing transaction: done\n", - "#\n", - "# To activate this environment, use\n", - "#\n", - "# $ conda activate otherenv\n", - "#\n", - "# To deactivate an active environment, use\n", - "#\n", - "# $ conda deactivate\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "limited-persian", - "metadata": {}, - "source": [ - "As notified after the environment creation process is finished, it is possible to activate the otherenv environment by running `conda activate otherenv`. You’ll notice the environment has changed by the indication between parentheses in the beginning of the prompt:\n", - "\n", - "```bash\n", - "$ (base) ~ % conda activate otherenv\n", - "$ (otherenv) ~ %\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "roman-multimedia", - "metadata": {}, - "source": [ - "You can open the Python interpreter within this environment by running `python`:\n", - "\n", - "```bash\n", - "$ (otherenv) ~ % python\n", - "\n", - "Python 3.7.0 (default, Jun 28 2018, 08:04:48) [MSC v.1912 64 bit (AMD64)] :: Anaconda, Inc. on win32\n", - "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n", - ">>>\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "hired-knife", - "metadata": {}, - "source": [ - "The environment includes Python 3.7.0, the same version included in the root base environment. To exit the Python interpreter, just run `quit()`:\n", - "\n", - "```bash\n", - ">>> quit()\n", - "\n", - "(otherenv) ~ %\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "fatal-lunch", - "metadata": {}, - "source": [ - "To deactivate the otherenv environment and go back to the root base environment, you should run `deactivate`:\n", - "\n", - "```bash\n", - "(otherenv) ~ % conda deactivate\n", - "\n", - "(base) ~ %\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "textile-integrity", - "metadata": {}, - "source": [ - "As mentioned earlier, Conda allows you to easily create environments with different versions of Python, which is not straightforward with Virtualenv. To include a different Python version within an environment, you have to specify it by using `python=` when running conda create. For example, to create an environment named `py2` with `Python 2.7`, you have to run `conda create --name py2 python=2.7`:\n", - "\n", - "\n", - "```bash\n", - "(base) ~ % create --name py2 python=2.7\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\py2\n", - "\n", - " added / updated specs:\n", - " - python=2.7\n", - "\n", - "\n", - "The following NEW packages will be INSTALLED:\n", - "\n", - " certifi: 2018.8.24-py27_1\n", - " pip: 10.0.1-py27_0\n", - " python: 2.7.15-he216670_0\n", - " setuptools: 40.2.0-py27_0\n", - " vc: 9-h7299396_1\n", - " vs2008_runtime: 9.00.30729.1-hfaea7d5_1\n", - " wheel: 0.31.1-py27_0\n", - " wincertstore: 0.2-py27hf04cefb_0\n", - "\n", - "Proceed ([y]/n)? y\n", - "\n", - "Preparing transaction: done\n", - "Verifying transaction: done\n", - "Executing transaction: done\n", - "#\n", - "# To activate this environment, use\n", - "#\n", - "# $ conda activate py2\n", - "#\n", - "# To deactivate an active environment, use\n", - "#\n", - "# $ conda deactivate\n", - "\n", - "(base) /mnt/c/Users/username%\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "labeled-november", - "metadata": {}, - "source": [ - "As shown by the output of `conda create`, this time some new packages were installed, since the new environment uses Python 2. You can check the new environment indeed uses Python 2 by activating it and running the Python interpreter:\n", - "\n", - "```\n", - "(base) ~ % conda activate py2\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "obvious-cycle", - "metadata": {}, - "source": [ - "Now, if you run `conda env list`, you should see the two environments that were created, besides the root base environment:\n", - "\n", - "```bash\n", - "(py2) ~ % conda env list\n", - "# conda environments:\n", - "#\n", - "base C:\\Users\\IEUser\\Miniconda3\n", - "otherenv C:\\Users\\IEUser\\Miniconda3\\envs\\otherenv\n", - "py2 * C:\\Users\\IEUser\\Miniconda3\\envs\\py2\n", - "\n", - "\n", - "(py2) ~ %\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "known-timothy", - "metadata": {}, - "source": [ - "In the list, the asterisk indicates the activated environment. It is possible to remove an environment by running `conda remove --name --all`. Since it is not possible to remove an activated environment, you should first deactivate the `py2` environment, to remove it:\n", - "\n", - "```bash\n", - "(py2) ~ % conda deactivate\n", - "(base) ~ % conda remove --name py2 --all\n", - "\n", - "Remove all packages in environment C:\\Users\\IEUser\\Miniconda3\\envs\\py2:\n", - "\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\py2\n", - "\n", - "\n", - "The following packages will be REMOVED:\n", - "\n", - " certifi: 2018.8.24-py27_1\n", - " pip: 10.0.1-py27_0\n", - " python: 2.7.15-he216670_0\n", - " setuptools: 40.2.0-py27_0\n", - " vc: 9-h7299396_1\n", - " vs2008_runtime: 9.00.30729.1-hfaea7d5_1\n", - " wheel: 0.31.1-py27_0\n", - " wincertstore: 0.2-py27hf04cefb_0\n", - "\n", - "Proceed ([y]/n)? y\n", - "\n", - "\n", - "(base) /mnt/c/Users/username%\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "widespread-mixture", - "metadata": {}, - "source": [ - "Now that you’ve covered the basics of managing environments with Conda, let’s see how to manage packages within the environments." - ] - }, - { - "cell_type": "markdown", - "id": "diagnostic-fisher", - "metadata": {}, - "source": [ - " \n", - "## Understanding Basic Package Management With Conda\n", - "\n", - "Within each environment, packages of software can be installed using the Conda package manager. The root base environment created by the Miniconda installer includes some packages by default that are not part of Python standard library." - ] - }, - { - "cell_type": "markdown", - "id": "enabling-bolivia", - "metadata": {}, - "source": [ - "The default installation includes the minimum packages necessary to use Conda. To check the list of installed packages in an environment, you just have to make sure it is activated and run `conda list`. In the root environment, the following packages are installed by default:\n", - "\n", - "```bash\n", - "(base) ~ % conda list\n", - "# packages in environment at C:\\Users\\IEUser\\Miniconda3:\n", - "#\n", - "# Name Version Build Channel\n", - "asn1crypto 0.24.0 py37_0\n", - "ca-certificates 2018.03.07 0\n", - "certifi 2018.8.24 py37_1\n", - "cffi 1.11.5 py37h74b6da3_1\n", - "chardet 3.0.4 py37_1\n", - "conda 4.5.11 py37_0\n", - "conda-env 2.6.0 1\n", - "console_shortcut 0.1.1 3\n", - "cryptography 2.3.1 py37h74b6da3_0\n", - "idna 2.7 py37_0\n", - "menuinst 1.4.14 py37hfa6e2cd_0\n", - "openssl 1.0.2p hfa6e2cd_0\n", - "pip 10.0.1 py37_0\n", - "pycosat 0.6.3 py37hfa6e2cd_0\n", - "pycparser 2.18 py37_1\n", - "pyopenssl 18.0.0 py37_0\n", - "pysocks 1.6.8 py37_0\n", - "python 3.7.0 hea74fb7_0\n", - "pywin32 223 py37hfa6e2cd_1\n", - "requests 2.19.1 py37_0\n", - "ruamel_yaml 0.15.46 py37hfa6e2cd_0\n", - "setuptools 40.2.0 py37_0\n", - "six 1.11.0 py37_1\n", - "urllib3 1.23 py37_0\n", - "vc 14 h0510ff6_3\n", - "vs2015_runtime 14.0.25123 3\n", - "wheel 0.31.1 py37_0\n", - "win_inet_pton 1.0.1 py37_1\n", - "wincertstore 0.2 py37_0\n", - "yaml 0.1.7 hc54c509_2\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "indoor-savannah", - "metadata": {}, - "source": [ - "To manage the packages, you should also use Conda. Next, let’s see how to search, install, update, and remove packages using Conda." - ] - }, - { - "cell_type": "markdown", - "id": "coral-governor", - "metadata": {}, - "source": [ - " \n", - "### Searching and Installing Packages\n", - "\n", - "Packages are installed from repositories called **channels** by Conda, and some default channels are configured by the installer. To search for a specific package, you can run `conda search `. For example, this is how you search for the `keras` package (a machine learning library):\n", - "\n", - "```bash\n", - "(base) ~ % conda search keras\n", - "Loading channels: done\n", - "# Name Version Build Channel\n", - "keras 2.0.8 py35h15001cb_0 pkgs/main\n", - "keras 2.0.8 py36h65e7a35_0 pkgs/main\n", - "keras 2.1.2 py35_0 pkgs/main\n", - "keras 2.1.2 py36_0 pkgs/main\n", - "keras 2.1.3 py35_0 pkgs/main\n", - "keras 2.1.3 py36_0 pkgs/main\n", - "\n", - "... (more)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "cardiovascular-zimbabwe", - "metadata": {}, - "source": [ - "According to the previous output, there are different versions of the package and different builds for each version, such as for Python 3.5 and 3.6." - ] - }, - { - "cell_type": "markdown", - "id": "mighty-impact", - "metadata": {}, - "source": [ - "The previous search shows only exact matches for packages named `keras`. To perform a broader search, including all packages containing `keras` in their names, you should use the wildcard `*`. For example, when you run conda search `*keras*`, you get the following:\n", - "\n", - "```bash\n", - "(base) ~ % conda search \"*keras*\"\n", - "Loading channels: done\n", - "# Name Version Build Channel\n", - "keras 2.0.8 py35h15001cb_0 pkgs/main\n", - "keras 2.0.8 py36h65e7a35_0 pkgs/main\n", - "keras 2.1.2 py35_0 pkgs/main\n", - "keras 2.1.2 py36_0 pkgs/main\n", - "keras 2.1.3 py35_0 pkgs/main\n", - "keras 2.1.3 py36_0 pkgs/main\n", - "\n", - "... (more)\n", - "\n", - "keras-applications 1.0.2 py35_0 pkgs/main\n", - "keras-applications 1.0.2 py36_0 pkgs/main\n", - "keras-applications 1.0.4 py35_0 pkgs/main\n", - "\n", - "... (more)\n", - "\n", - "keras-base 2.2.0 py35_0 pkgs/main\n", - "keras-base 2.2.0 py36_0 pkgs/main\n", - "\n", - "... (more)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "simplified-freedom", - "metadata": {}, - "source": [ - "As the previous output shows, there are some other keras related packages in the default channels." - ] - }, - { - "cell_type": "markdown", - "id": "promising-digest", - "metadata": {}, - "source": [ - "To install a package, you should run `conda install `. By default, the newest version of the package will be installed in the active environment. So, let’s install the package `keras` in the environment `otherenv` that you’ve already created:\n", - "\n", - "```bash\n", - "(base) ~ % conda activate otherenv\n", - "\n", - "(otherenv) ~ % conda install keras\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\otherenv\n", - "\n", - " added / updated specs:\n", - " - keras\n", - "\n", - "\n", - "The following NEW packages will be INSTALLED:\n", - "\n", - " _tflow_1100_select: 0.0.3-mkl\n", - " absl-py: 0.4.1-py36_0\n", - " astor: 0.7.1-py36_0\n", - " blas: 1.0-mkl\n", - " certifi: 2018.8.24-py36_1\n", - " gast: 0.2.0-py36_0\n", - " grpcio: 1.12.1-py36h1a1b453_0\n", - " h5py: 2.8.0-py36h3bdd7fb_2\n", - " hdf5: 1.10.2-hac2f561_1\n", - " icc_rt: 2017.0.4-h97af966_0\n", - " intel-openmp: 2018.0.3-0\n", - " keras: 2.2.2-0\n", - " keras-applications: 1.0.4-py36_1\n", - " keras-base: 2.2.2-py36_0\n", - " keras-preprocessing: 1.0.2-py36_1\n", - " libmklml: 2018.0.3-1\n", - " libprotobuf: 3.6.0-h1a1b453_0\n", - " markdown: 2.6.11-py36_0\n", - " mkl: 2019.0-117\n", - " mkl_fft: 1.0.4-py36h1e22a9b_1\n", - " mkl_random: 1.0.1-py36h77b88f5_1\n", - " numpy: 1.15.1-py36ha559c80_0\n", - " numpy-base: 1.15.1-py36h8128ebf_0\n", - " pip: 10.0.1-py36_0\n", - " protobuf: 3.6.0-py36he025d50_0\n", - " python: 3.6.6-hea74fb7_0\n", - " pyyaml: 3.13-py36hfa6e2cd_0\n", - " scipy: 1.1.0-py36h4f6bf74_1\n", - " setuptools: 40.2.0-py36_0\n", - " six: 1.11.0-py36_1\n", - " tensorboard: 1.10.0-py36he025d50_0\n", - " tensorflow: 1.10.0-mkl_py36hb361250_0\n", - " tensorflow-base: 1.10.0-mkl_py36h81393da_0\n", - " termcolor: 1.1.0-py36_1\n", - " vc: 14-h0510ff6_3\n", - " vs2013_runtime: 12.0.21005-1\n", - " vs2015_runtime: 14.0.25123-3\n", - " werkzeug: 0.14.1-py36_0\n", - " wheel: 0.31.1-py36_0\n", - " wincertstore: 0.2-py36h7fe50ca_0\n", - " yaml: 0.1.7-hc54c509_2\n", - " zlib: 1.2.11-h8395fce_2\n", - "\n", - "Proceed ([y]/n)?\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "elementary-milan", - "metadata": {}, - "source": [ - "Conda manages the necessary dependencies for a package when it is installed. Since the package keras has a lot of dependencies, when you install it, Conda manages to install this big list of packages." - ] - }, - { - "cell_type": "markdown", - "id": "appreciated-australia", - "metadata": {}, - "source": [ - "> **Note:** The paragraph below may not happen when you run it as newer versions of `keras` may be available that use python 3.7.\n", - "\n", - "It’s worth noticing that, since the keras package’s newest build uses Python 3.6 and the otherenv environment was created using Python 3.7, the package python version 3.6.6 was included as a dependency. After confirming the installation, you can check that the Python version for the otherenv environment is downgraded to the 3.6.6 version." - ] - }, - { - "cell_type": "markdown", - "id": "seven-filename", - "metadata": {}, - "source": [ - "Sometimes, you don’t want packages to be downgraded, and it would be better to just create a new environment with the necessary version of Python. To check the list of new packages, updates, and downgrades necessary for a package without installing it, you should use the parameter `--dry-run`. For example, to check the packages that will be changed by the installation of the package keras, you should run the following:\n", - "\n", - "```\n", - "(base) ~ % conda install keras --dry-run\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "ordinary-member", - "metadata": {}, - "source": [ - "However, if necessary, it is possible to change the default Python of a Conda environment by installing a specific version of the package python. To demonstrate that, let’s create a new environment called envpython:\n", - "\n", - "```bash\n", - "(otherenv) ~ % conda create --name envpython\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\envpython\n", - "\n", - "\n", - "Proceed ([y]/n)? y\n", - "\n", - "Preparing transaction: done\n", - "Verifying transaction: done\n", - "Executing transaction: done\n", - "#\n", - "# To activate this environment, use\n", - "#\n", - "# $ conda activate envpython\n", - "#\n", - "# To deactivate an active environment, use\n", - "#\n", - "# $ conda deactivate\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "blind-samba", - "metadata": {}, - "source": [ - "As you saw before, since the root base environment uses Python 3.7, envpython is created including this same version of Python:\n", - "\n", - "```bash\n", - "(base) ~ % conda activate envpython\n", - "(envpython) ~ % python\n", - "Python 3.7.0 (default, Jun 28 2018, 08:04:48) [MSC v.1912 64 bit (AMD64)] :: Anaconda, Inc. on win32\n", - "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n", - ">>> quit()\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "dependent-norwegian", - "metadata": {}, - "source": [ - "To install a specific version of a package, you can run `conda install =`. For example, this is how you install Python 3.6 in the envpython environment:\n", - "\n", - "```bash\n", - "(envpython) ~ % conda install python=3.6\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\envpython\n", - "\n", - " added / updated specs:\n", - " - python=3.6\n", - "\n", - "\n", - "The following NEW packages will be INSTALLED:\n", - "\n", - " certifi: 2018.8.24-py36_1\n", - " pip: 10.0.1-py36_0\n", - " python: 3.6.6-hea74fb7_0\n", - " setuptools: 40.2.0-py36_0\n", - " vc: 14-h0510ff6_3\n", - " vs2015_runtime: 14.0.25123-3\n", - " wheel: 0.31.1-py36_0\n", - " wincertstore: 0.2-py36h7fe50ca_0\n", - "\n", - "Proceed ([y]/n)?\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "infinite-western", - "metadata": {}, - "source": [ - "In case you need to install more than one package in an environment, it is possible to run conda install only once, passing the names of the packages. To illustrate that, let’s install `numpy`, `scipy`, and `matplotlib`, basic packages for numerical computation:\n", - "\n", - "```bash\n", - "(envpython) ~ % conda install numpy scipy matplotlib\n", - "\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\n", - "\n", - " added / updated specs:\n", - " - matplotlib\n", - " - numpy\n", - " - scipy\n", - "\n", - "\n", - "The following packages will be downloaded:\n", - "\n", - " package | build\n", - " ---------------------------|-----------------\n", - " libpng-1.6.34 | h79bbb47_0 1.3 MB\n", - " mkl_random-1.0.1 | py37h77b88f5_1 267 KB\n", - " intel-openmp-2019.0 | 117 1.7 MB\n", - " qt-5.9.6 | vc14h62aca36_0 92.5 MB\n", - " matplotlib-2.2.3 | py37hd159220_0 6.5 MB\n", - " tornado-5.1 | py37hfa6e2cd_0 668 KB\n", - " pyqt-5.9.2 | py37ha878b3d_0 4.6 MB\n", - " pytz-2018.5 | py37_0 232 KB\n", - " scipy-1.1.0 | py37h4f6bf74_1 13.5 MB\n", - " jpeg-9b | hb83a4c4_2 313 KB\n", - " python-dateutil-2.7.3 | py37_0 260 KB\n", - " numpy-base-1.15.1 | py37h8128ebf_0 3.9 MB\n", - " numpy-1.15.1 | py37ha559c80_0 37 KB\n", - " mkl_fft-1.0.4 | py37h1e22a9b_1 120 KB\n", - " kiwisolver-1.0.1 | py37h6538335_0 61 KB\n", - " pyparsing-2.2.0 | py37_1 96 KB\n", - " cycler-0.10.0 | py37_0 13 KB\n", - " freetype-2.9.1 | ha9979f8_1 470 KB\n", - " icu-58.2 | ha66f8fd_1 21.9 MB\n", - " sqlite-3.24.0 | h7602738_0 899 KB\n", - " sip-4.19.12 | py37h6538335_0 283 KB\n", - " ------------------------------------------------------------\n", - " Total: 149.5 MB\n", - "\n", - "The following NEW packages will be INSTALLED:\n", - "\n", - " blas: 1.0-mkl\n", - " cycler: 0.10.0-py37_0\n", - " freetype: 2.9.1-ha9979f8_1\n", - " icc_rt: 2017.0.4-h97af966_0\n", - " icu: 58.2-ha66f8fd_1\n", - " intel-openmp: 2019.0-117\n", - " jpeg: 9b-hb83a4c4_2\n", - " kiwisolver: 1.0.1-py37h6538335_0\n", - " libpng: 1.6.34-h79bbb47_0\n", - " matplotlib: 2.2.3-py37hd159220_0\n", - " mkl: 2019.0-117\n", - " mkl_fft: 1.0.4-py37h1e22a9b_1\n", - " mkl_random: 1.0.1-py37h77b88f5_1\n", - " numpy: 1.15.1-py37ha559c80_0\n", - " numpy-base: 1.15.1-py37h8128ebf_0\n", - " pyparsing: 2.2.0-py37_1\n", - " pyqt: 5.9.2-py37ha878b3d_0\n", - " python-dateutil: 2.7.3-py37_0\n", - " pytz: 2018.5-py37_0\n", - " qt: 5.9.6-vc14h62aca36_0\n", - " scipy: 1.1.0-py37h4f6bf74_1\n", - " sip: 4.19.12-py37h6538335_0\n", - " sqlite: 3.24.0-h7602738_0\n", - " tornado: 5.1-py37hfa6e2cd_0\n", - " zlib: 1.2.11-h8395fce_2\n", - "\n", - "Proceed ([y]/n)?\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "impossible-intent", - "metadata": {}, - "source": [ - "Now that you’ve covered how to search and install packages, let’s see how to update and remove them using Conda." - ] - }, - { - "cell_type": "markdown", - "id": "acting-brief", - "metadata": {}, - "source": [ - " \n", - "### Updating and Removing Packages\n", - "\n", - "Sometimes, when new packages are released, you need to update them. To do so, you may run `conda update `. In case you wish to update all the packages within one environment, you should activate the environment and run `conda update --all`." - ] - }, - { - "cell_type": "markdown", - "id": "listed-seeking", - "metadata": {}, - "source": [ - "To remove a package, you can run `conda remove `. For example, this is how you remove numpy from the root base environment:\n", - "\n", - "```bash\n", - "(envpython) ~ % conda remove numpy\n", - "Solving environment: done\n", - "\n", - "## Package Plan ##\n", - "\n", - " environment location: C:\\Users\\IEUser\\Miniconda3\n", - "\n", - " removed specs:\n", - " - numpy\n", - "\n", - "\n", - "The following packages will be REMOVED:\n", - "\n", - " matplotlib: 2.2.3-py37hd159220_0\n", - " mkl_fft: 1.0.4-py37h1e22a9b_1\n", - " mkl_random: 1.0.1-py37h77b88f5_1\n", - " numpy: 1.15.1-py37ha559c80_0\n", - " scipy: 1.1.0-py37h4f6bf74_1\n", - "\n", - "Proceed ([y]/n)?\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "metropolitan-helping", - "metadata": {}, - "source": [ - "> **Note:** It’s worth noting that when you remove a package, all packages that depend on it are also removed." - ] - }, - { - "cell_type": "markdown", - "id": "satisfactory-fourth", - "metadata": {}, - "source": [ - " \n", - "## Cheat Sheet\n", - "\n", - "[Click here to get access to a Conda cheat sheet](https://static.realpython.com/conda-cheatsheet.pdf) with handy usage examples for managing your Python environment and packages." - ] - }, - { - "cell_type": "markdown", - "id": "confident-dynamics", - "metadata": {}, - "source": [ - " \n", - "## Read More" - ] - }, - { - "cell_type": "markdown", - "id": "silent-hawaii", - "metadata": {}, - "source": [ - "Also, if you’d like a deeper understanding of Anaconda and Conda, check out the following links:\n", - "\n", - "- [Why you need Python environments and how to manage them with Conda](https://medium.freecodecamp.org/why-you-need-python-environments-and-how-to-manage-them-with-conda-85f155f4353c)\n", - "- [Conda: Myths and Misconceptions](http://jakevdp.github.io/blog/2016/08/25/conda-myths-and-misconceptions/)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "d4a95e9d", "metadata": {}, "source": ["# Conda Environments"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Understanding Conda Environments](#understanding_conda_environments)\n* [Understanding Basic Package Management With Conda](#understanding_basic_package_management_with_conda)\n * [Searching and Installing Packages](#searching_and_installing_packages)\n * [Updating and Removing Packages](#updating_and_removing_packages)\n* [Cheat Sheet](#cheat_sheet)\n* [Read More](#read_more)\n\n---"]}, {"cell_type": "markdown", "id": "successful-abortion", "metadata": {}, "source": ["", "\n", "## Understanding Conda Environments"]}, {"cell_type": "markdown", "id": "reported-recovery", "metadata": {}, "source": ["When you start developing a project from scratch, it\u2019s recommended that you use the latest versions of the libraries you need. However, when working with someone else\u2019s project, such as when running an example from [Kaggle](https://www.kaggle.com/) or [Github](https://github.com/), you may need to install specific versions of packages or even another version of Python due to compatibility issues."]}, {"cell_type": "markdown", "id": "critical-tenant", "metadata": {}, "source": ["This problem may also occur when you try to run an application you\u2019ve developed long ago, which uses a particular library version that does not work with your application anymore due to updates."]}, {"cell_type": "markdown", "id": "lovely-korea", "metadata": {}, "source": ["Virtual environments are a solution to this kind of problem. By using them, it is possible to create multiple environments, each one with different versions of packages. A typical Python set up includes [Virtualenv](https://virtualenv.pypa.io/en/stable/#), a tool to create isolated Python virtual environments, widely used in the Python community."]}, {"cell_type": "markdown", "id": "frozen-pavilion", "metadata": {}, "source": ["Conda includes its own environment manager and presents some advantages over Virtualenv, especially concerning numerical applications, such as the ability to manage non-Python dependencies and the ability to manage different versions of Python, which is not possible with Virtualenv. Besides that, Conda environments are entirely compatible with default [Python packages](https://realpython.com/python-modules-packages/) that may be installed using pip."]}, {"cell_type": "markdown", "id": "latter-bankruptcy", "metadata": {}, "source": ["Miniconda installation provides Conda and a root environment with a version of Python and some basic packages installed. Besides this root environment, it is possible to set up additional environments including different versions of Python and packages."]}, {"cell_type": "markdown", "id": "inner-allowance", "metadata": {}, "source": ["\n", "Using the Anaconda prompt, it is possible to check the available Conda environments by running `conda env list`:\n", "\n", "```bash\n", "\n", "$ (base) ~ % conda env list\n", "\n", "# conda environments:\n", "#\n", "base * /home/ali/anaconda3\n", "```"]}, {"cell_type": "markdown", "id": "lasting-prevention", "metadata": {}, "source": ["\n", "This base environment is the root environment, created by the Miniconda installer. It is possible to create another environment, named `otherenv`, by running `conda create --name otherenv`:\n", "\n", "\n", "```bash\n", "$ (base) ~ % conda create --name otherenv\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\otherenv\n", "\n", "\n", "Proceed ([y]/n)? y\n", "\n", "Preparing transaction: done\n", "Verifying transaction: done\n", "Executing transaction: done\n", "#\n", "# To activate this environment, use\n", "#\n", "# $ conda activate otherenv\n", "#\n", "# To deactivate an active environment, use\n", "#\n", "# $ conda deactivate\n", "```"]}, {"cell_type": "markdown", "id": "limited-persian", "metadata": {}, "source": ["As notified after the environment creation process is finished, it is possible to activate the otherenv environment by running `conda activate otherenv`. You\u2019ll notice the environment has changed by the indication between parentheses in the beginning of the prompt:\n", "\n", "```bash\n", "$ (base) ~ % conda activate otherenv\n", "$ (otherenv) ~ %\n", "```"]}, {"cell_type": "markdown", "id": "roman-multimedia", "metadata": {}, "source": ["You can open the Python interpreter within this environment by running `python`:\n", "\n", "```bash\n", "$ (otherenv) ~ % python\n", "\n", "Python 3.7.0 (default, Jun 28 2018, 08:04:48) [MSC v.1912 64 bit (AMD64)] :: Anaconda, Inc. on win32\n", "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n", ">>>\n", "```"]}, {"cell_type": "markdown", "id": "hired-knife", "metadata": {}, "source": ["The environment includes Python 3.7.0, the same version included in the root base environment. To exit the Python interpreter, just run `quit()`:\n", "\n", "```bash\n", ">>> quit()\n", "\n", "(otherenv) ~ %\n", "```"]}, {"cell_type": "markdown", "id": "fatal-lunch", "metadata": {}, "source": ["To deactivate the otherenv environment and go back to the root base environment, you should run `deactivate`:\n", "\n", "```bash\n", "(otherenv) ~ % conda deactivate\n", "\n", "(base) ~ %\n", "```"]}, {"cell_type": "markdown", "id": "textile-integrity", "metadata": {}, "source": ["\n", "As mentioned earlier, Conda allows you to easily create environments with different versions of Python, which is not straightforward with Virtualenv. To include a different Python version within an environment, you have to specify it by using `python=` when running conda create. For example, to create an environment named `py2` with `Python 2.7`, you have to run `conda create --name py2 python=2.7`:\n", "\n", "\n", "```bash\n", "(base) ~ % create --name py2 python=2.7\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\py2\n", "\n", " added / updated specs:\n", " - python=2.7\n", "\n", "\n", "The following NEW packages will be INSTALLED:\n", "\n", " certifi: 2018.8.24-py27_1\n", " pip: 10.0.1-py27_0\n", " python: 2.7.15-he216670_0\n", " setuptools: 40.2.0-py27_0\n", " vc: 9-h7299396_1\n", " vs2008_runtime: 9.00.30729.1-hfaea7d5_1\n", " wheel: 0.31.1-py27_0\n", " wincertstore: 0.2-py27hf04cefb_0\n", "\n", "Proceed ([y]/n)? y\n", "\n", "Preparing transaction: done\n", "Verifying transaction: done\n", "Executing transaction: done\n", "#\n", "# To activate this environment, use\n", "#\n", "# $ conda activate py2\n", "#\n", "# To deactivate an active environment, use\n", "#\n", "# $ conda deactivate\n", "\n", "(base) /mnt/c/Users/username%\n", "```"]}, {"cell_type": "markdown", "id": "labeled-november", "metadata": {}, "source": ["As shown by the output of `conda create`, this time some new packages were installed, since the new environment uses Python 2. You can check the new environment indeed uses Python 2 by activating it and running the Python interpreter:\n", "\n", "```\n", "(base) ~ % conda activate py2\n", "```"]}, {"cell_type": "markdown", "id": "obvious-cycle", "metadata": {}, "source": ["\n", "Now, if you run `conda env list`, you should see the two environments that were created, besides the root base environment:\n", "\n", "```bash\n", "(py2) ~ % conda env list\n", "# conda environments:\n", "#\n", "base C:\\Users\\IEUser\\Miniconda3\n", "otherenv C:\\Users\\IEUser\\Miniconda3\\envs\\otherenv\n", "py2 * C:\\Users\\IEUser\\Miniconda3\\envs\\py2\n", "\n", "\n", "(py2) ~ %\n", "```"]}, {"cell_type": "markdown", "id": "known-timothy", "metadata": {}, "source": ["\n", "In the list, the asterisk indicates the activated environment. It is possible to remove an environment by running `conda remove --name --all`. Since it is not possible to remove an activated environment, you should first deactivate the `py2` environment, to remove it:\n", "\n", "```bash\n", "(py2) ~ % conda deactivate\n", "(base) ~ % conda remove --name py2 --all\n", "\n", "Remove all packages in environment C:\\Users\\IEUser\\Miniconda3\\envs\\py2:\n", "\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\py2\n", "\n", "\n", "The following packages will be REMOVED:\n", "\n", " certifi: 2018.8.24-py27_1\n", " pip: 10.0.1-py27_0\n", " python: 2.7.15-he216670_0\n", " setuptools: 40.2.0-py27_0\n", " vc: 9-h7299396_1\n", " vs2008_runtime: 9.00.30729.1-hfaea7d5_1\n", " wheel: 0.31.1-py27_0\n", " wincertstore: 0.2-py27hf04cefb_0\n", "\n", "Proceed ([y]/n)? y\n", "\n", "\n", "(base) /mnt/c/Users/username%\n", "```"]}, {"cell_type": "markdown", "id": "widespread-mixture", "metadata": {}, "source": ["Now that you\u2019ve covered the basics of managing environments with Conda, let\u2019s see how to manage packages within the environments."]}, {"cell_type": "markdown", "id": "diagnostic-fisher", "metadata": {}, "source": ["", "\n", "## Understanding Basic Package Management With Conda\n", "\n", "Within each environment, packages of software can be installed using the Conda package manager. The root base environment created by the Miniconda installer includes some packages by default that are not part of Python standard library."]}, {"cell_type": "markdown", "id": "enabling-bolivia", "metadata": {}, "source": ["\n", "The default installation includes the minimum packages necessary to use Conda. To check the list of installed packages in an environment, you just have to make sure it is activated and run `conda list`. In the root environment, the following packages are installed by default:\n", "\n", "```bash\n", "(base) ~ % conda list\n", "# packages in environment at C:\\Users\\IEUser\\Miniconda3:\n", "#\n", "# Name Version Build Channel\n", "asn1crypto 0.24.0 py37_0\n", "ca-certificates 2018.03.07 0\n", "certifi 2018.8.24 py37_1\n", "cffi 1.11.5 py37h74b6da3_1\n", "chardet 3.0.4 py37_1\n", "conda 4.5.11 py37_0\n", "conda-env 2.6.0 1\n", "console_shortcut 0.1.1 3\n", "cryptography 2.3.1 py37h74b6da3_0\n", "idna 2.7 py37_0\n", "menuinst 1.4.14 py37hfa6e2cd_0\n", "openssl 1.0.2p hfa6e2cd_0\n", "pip 10.0.1 py37_0\n", "pycosat 0.6.3 py37hfa6e2cd_0\n", "pycparser 2.18 py37_1\n", "pyopenssl 18.0.0 py37_0\n", "pysocks 1.6.8 py37_0\n", "python 3.7.0 hea74fb7_0\n", "pywin32 223 py37hfa6e2cd_1\n", "requests 2.19.1 py37_0\n", "ruamel_yaml 0.15.46 py37hfa6e2cd_0\n", "setuptools 40.2.0 py37_0\n", "six 1.11.0 py37_1\n", "urllib3 1.23 py37_0\n", "vc 14 h0510ff6_3\n", "vs2015_runtime 14.0.25123 3\n", "wheel 0.31.1 py37_0\n", "win_inet_pton 1.0.1 py37_1\n", "wincertstore 0.2 py37_0\n", "yaml 0.1.7 hc54c509_2\n", "```"]}, {"cell_type": "markdown", "id": "indoor-savannah", "metadata": {}, "source": ["To manage the packages, you should also use Conda. Next, let\u2019s see how to search, install, update, and remove packages using Conda."]}, {"cell_type": "markdown", "id": "coral-governor", "metadata": {}, "source": ["", "\n", "### Searching and Installing Packages\n", "\n", "Packages are installed from repositories called **channels** by Conda, and some default channels are configured by the installer. To search for a specific package, you can run `conda search `. For example, this is how you search for the `keras` package (a machine learning library):\n", "\n", "```bash\n", "(base) ~ % conda search keras\n", "Loading channels: done\n", "# Name Version Build Channel\n", "keras 2.0.8 py35h15001cb_0 pkgs/main\n", "keras 2.0.8 py36h65e7a35_0 pkgs/main\n", "keras 2.1.2 py35_0 pkgs/main\n", "keras 2.1.2 py36_0 pkgs/main\n", "keras 2.1.3 py35_0 pkgs/main\n", "keras 2.1.3 py36_0 pkgs/main\n", "\n", "... (more)\n", "```"]}, {"cell_type": "markdown", "id": "cardiovascular-zimbabwe", "metadata": {}, "source": ["According to the previous output, there are different versions of the package and different builds for each version, such as for Python 3.5 and 3.6."]}, {"cell_type": "markdown", "id": "mighty-impact", "metadata": {}, "source": ["\n", "The previous search shows only exact matches for packages named `keras`. To perform a broader search, including all packages containing `keras` in their names, you should use the wildcard `*`. For example, when you run conda search `*keras*`, you get the following:\n", "\n", "```bash\n", "(base) ~ % conda search \"*keras*\"\n", "Loading channels: done\n", "# Name Version Build Channel\n", "keras 2.0.8 py35h15001cb_0 pkgs/main\n", "keras 2.0.8 py36h65e7a35_0 pkgs/main\n", "keras 2.1.2 py35_0 pkgs/main\n", "keras 2.1.2 py36_0 pkgs/main\n", "keras 2.1.3 py35_0 pkgs/main\n", "keras 2.1.3 py36_0 pkgs/main\n", "\n", "... (more)\n", "\n", "keras-applications 1.0.2 py35_0 pkgs/main\n", "keras-applications 1.0.2 py36_0 pkgs/main\n", "keras-applications 1.0.4 py35_0 pkgs/main\n", "\n", "... (more)\n", "\n", "keras-base 2.2.0 py35_0 pkgs/main\n", "keras-base 2.2.0 py36_0 pkgs/main\n", "\n", "... (more)\n", "```"]}, {"cell_type": "markdown", "id": "simplified-freedom", "metadata": {}, "source": ["As the previous output shows, there are some other keras related packages in the default channels."]}, {"cell_type": "markdown", "id": "promising-digest", "metadata": {}, "source": ["\n", "To install a package, you should run `conda install `. By default, the newest version of the package will be installed in the active environment. So, let\u2019s install the package `keras` in the environment `otherenv` that you\u2019ve already created:\n", "\n", "```bash\n", "(base) ~ % conda activate otherenv\n", "\n", "(otherenv) ~ % conda install keras\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\otherenv\n", "\n", " added / updated specs:\n", " - keras\n", "\n", "\n", "The following NEW packages will be INSTALLED:\n", "\n", " _tflow_1100_select: 0.0.3-mkl\n", " absl-py: 0.4.1-py36_0\n", " astor: 0.7.1-py36_0\n", " blas: 1.0-mkl\n", " certifi: 2018.8.24-py36_1\n", " gast: 0.2.0-py36_0\n", " grpcio: 1.12.1-py36h1a1b453_0\n", " h5py: 2.8.0-py36h3bdd7fb_2\n", " hdf5: 1.10.2-hac2f561_1\n", " icc_rt: 2017.0.4-h97af966_0\n", " intel-openmp: 2018.0.3-0\n", " keras: 2.2.2-0\n", " keras-applications: 1.0.4-py36_1\n", " keras-base: 2.2.2-py36_0\n", " keras-preprocessing: 1.0.2-py36_1\n", " libmklml: 2018.0.3-1\n", " libprotobuf: 3.6.0-h1a1b453_0\n", " markdown: 2.6.11-py36_0\n", " mkl: 2019.0-117\n", " mkl_fft: 1.0.4-py36h1e22a9b_1\n", " mkl_random: 1.0.1-py36h77b88f5_1\n", " numpy: 1.15.1-py36ha559c80_0\n", " numpy-base: 1.15.1-py36h8128ebf_0\n", " pip: 10.0.1-py36_0\n", " protobuf: 3.6.0-py36he025d50_0\n", " python: 3.6.6-hea74fb7_0\n", " pyyaml: 3.13-py36hfa6e2cd_0\n", " scipy: 1.1.0-py36h4f6bf74_1\n", " setuptools: 40.2.0-py36_0\n", " six: 1.11.0-py36_1\n", " tensorboard: 1.10.0-py36he025d50_0\n", " tensorflow: 1.10.0-mkl_py36hb361250_0\n", " tensorflow-base: 1.10.0-mkl_py36h81393da_0\n", " termcolor: 1.1.0-py36_1\n", " vc: 14-h0510ff6_3\n", " vs2013_runtime: 12.0.21005-1\n", " vs2015_runtime: 14.0.25123-3\n", " werkzeug: 0.14.1-py36_0\n", " wheel: 0.31.1-py36_0\n", " wincertstore: 0.2-py36h7fe50ca_0\n", " yaml: 0.1.7-hc54c509_2\n", " zlib: 1.2.11-h8395fce_2\n", "\n", "Proceed ([y]/n)?\n", "```"]}, {"cell_type": "markdown", "id": "elementary-milan", "metadata": {}, "source": ["Conda manages the necessary dependencies for a package when it is installed. Since the package keras has a lot of dependencies, when you install it, Conda manages to install this big list of packages."]}, {"cell_type": "markdown", "id": "appreciated-australia", "metadata": {}, "source": ["> **Note:** The paragraph below may not happen when you run it as newer versions of `keras` may be available that use python 3.7.\n", "\n", "It\u2019s worth noticing that, since the keras package\u2019s newest build uses Python 3.6 and the otherenv environment was created using Python 3.7, the package python version 3.6.6 was included as a dependency. After confirming the installation, you can check that the Python version for the otherenv environment is downgraded to the 3.6.6 version."]}, {"cell_type": "markdown", "id": "seven-filename", "metadata": {}, "source": ["Sometimes, you don\u2019t want packages to be downgraded, and it would be better to just create a new environment with the necessary version of Python. To check the list of new packages, updates, and downgrades necessary for a package without installing it, you should use the parameter `--dry-run`. For example, to check the packages that will be changed by the installation of the package keras, you should run the following:\n", "\n", "```\n", "(base) ~ % conda install keras --dry-run\n", "```"]}, {"cell_type": "markdown", "id": "ordinary-member", "metadata": {}, "source": ["\n", "However, if necessary, it is possible to change the default Python of a Conda environment by installing a specific version of the package python. To demonstrate that, let\u2019s create a new environment called envpython:\n", "\n", "```bash\n", "(otherenv) ~ % conda create --name envpython\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\envpython\n", "\n", "\n", "Proceed ([y]/n)? y\n", "\n", "Preparing transaction: done\n", "Verifying transaction: done\n", "Executing transaction: done\n", "#\n", "# To activate this environment, use\n", "#\n", "# $ conda activate envpython\n", "#\n", "# To deactivate an active environment, use\n", "#\n", "# $ conda deactivate\n", "```"]}, {"cell_type": "markdown", "id": "blind-samba", "metadata": {}, "source": ["As you saw before, since the root base environment uses Python 3.7, envpython is created including this same version of Python:\n", "\n", "```bash\n", "(base) ~ % conda activate envpython\n", "(envpython) ~ % python\n", "Python 3.7.0 (default, Jun 28 2018, 08:04:48) [MSC v.1912 64 bit (AMD64)] :: Anaconda, Inc. on win32\n", "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n", ">>> quit()\n", "```"]}, {"cell_type": "markdown", "id": "dependent-norwegian", "metadata": {}, "source": ["\n", "To install a specific version of a package, you can run `conda install =`. For example, this is how you install Python 3.6 in the envpython environment:\n", "\n", "```bash\n", "(envpython) ~ % conda install python=3.6\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\\envs\\envpython\n", "\n", " added / updated specs:\n", " - python=3.6\n", "\n", "\n", "The following NEW packages will be INSTALLED:\n", "\n", " certifi: 2018.8.24-py36_1\n", " pip: 10.0.1-py36_0\n", " python: 3.6.6-hea74fb7_0\n", " setuptools: 40.2.0-py36_0\n", " vc: 14-h0510ff6_3\n", " vs2015_runtime: 14.0.25123-3\n", " wheel: 0.31.1-py36_0\n", " wincertstore: 0.2-py36h7fe50ca_0\n", "\n", "Proceed ([y]/n)?\n", "```"]}, {"cell_type": "markdown", "id": "infinite-western", "metadata": {}, "source": ["\n", "In case you need to install more than one package in an environment, it is possible to run conda install only once, passing the names of the packages. To illustrate that, let\u2019s install `numpy`, `scipy`, and `matplotlib`, basic packages for numerical computation:\n", "\n", "```bash\n", "(envpython) ~ % conda install numpy scipy matplotlib\n", "\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\n", "\n", " added / updated specs:\n", " - matplotlib\n", " - numpy\n", " - scipy\n", "\n", "\n", "The following packages will be downloaded:\n", "\n", " package | build\n", " ---------------------------|-----------------\n", " libpng-1.6.34 | h79bbb47_0 1.3 MB\n", " mkl_random-1.0.1 | py37h77b88f5_1 267 KB\n", " intel-openmp-2019.0 | 117 1.7 MB\n", " qt-5.9.6 | vc14h62aca36_0 92.5 MB\n", " matplotlib-2.2.3 | py37hd159220_0 6.5 MB\n", " tornado-5.1 | py37hfa6e2cd_0 668 KB\n", " pyqt-5.9.2 | py37ha878b3d_0 4.6 MB\n", " pytz-2018.5 | py37_0 232 KB\n", " scipy-1.1.0 | py37h4f6bf74_1 13.5 MB\n", " jpeg-9b | hb83a4c4_2 313 KB\n", " python-dateutil-2.7.3 | py37_0 260 KB\n", " numpy-base-1.15.1 | py37h8128ebf_0 3.9 MB\n", " numpy-1.15.1 | py37ha559c80_0 37 KB\n", " mkl_fft-1.0.4 | py37h1e22a9b_1 120 KB\n", " kiwisolver-1.0.1 | py37h6538335_0 61 KB\n", " pyparsing-2.2.0 | py37_1 96 KB\n", " cycler-0.10.0 | py37_0 13 KB\n", " freetype-2.9.1 | ha9979f8_1 470 KB\n", " icu-58.2 | ha66f8fd_1 21.9 MB\n", " sqlite-3.24.0 | h7602738_0 899 KB\n", " sip-4.19.12 | py37h6538335_0 283 KB\n", " ------------------------------------------------------------\n", " Total: 149.5 MB\n", "\n", "The following NEW packages will be INSTALLED:\n", "\n", " blas: 1.0-mkl\n", " cycler: 0.10.0-py37_0\n", " freetype: 2.9.1-ha9979f8_1\n", " icc_rt: 2017.0.4-h97af966_0\n", " icu: 58.2-ha66f8fd_1\n", " intel-openmp: 2019.0-117\n", " jpeg: 9b-hb83a4c4_2\n", " kiwisolver: 1.0.1-py37h6538335_0\n", " libpng: 1.6.34-h79bbb47_0\n", " matplotlib: 2.2.3-py37hd159220_0\n", " mkl: 2019.0-117\n", " mkl_fft: 1.0.4-py37h1e22a9b_1\n", " mkl_random: 1.0.1-py37h77b88f5_1\n", " numpy: 1.15.1-py37ha559c80_0\n", " numpy-base: 1.15.1-py37h8128ebf_0\n", " pyparsing: 2.2.0-py37_1\n", " pyqt: 5.9.2-py37ha878b3d_0\n", " python-dateutil: 2.7.3-py37_0\n", " pytz: 2018.5-py37_0\n", " qt: 5.9.6-vc14h62aca36_0\n", " scipy: 1.1.0-py37h4f6bf74_1\n", " sip: 4.19.12-py37h6538335_0\n", " sqlite: 3.24.0-h7602738_0\n", " tornado: 5.1-py37hfa6e2cd_0\n", " zlib: 1.2.11-h8395fce_2\n", "\n", "Proceed ([y]/n)?\n", "```"]}, {"cell_type": "markdown", "id": "impossible-intent", "metadata": {}, "source": ["Now that you\u2019ve covered how to search and install packages, let\u2019s see how to update and remove them using Conda."]}, {"cell_type": "markdown", "id": "acting-brief", "metadata": {}, "source": ["", "\n", "### Updating and Removing Packages\n", "\n", "Sometimes, when new packages are released, you need to update them. To do so, you may run `conda update `. In case you wish to update all the packages within one environment, you should activate the environment and run `conda update --all`."]}, {"cell_type": "markdown", "id": "listed-seeking", "metadata": {}, "source": ["\n", "To remove a package, you can run `conda remove `. For example, this is how you remove numpy from the root base environment:\n", "\n", "```bash\n", "(envpython) ~ % conda remove numpy\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: C:\\Users\\IEUser\\Miniconda3\n", "\n", " removed specs:\n", " - numpy\n", "\n", "\n", "The following packages will be REMOVED:\n", "\n", " matplotlib: 2.2.3-py37hd159220_0\n", " mkl_fft: 1.0.4-py37h1e22a9b_1\n", " mkl_random: 1.0.1-py37h77b88f5_1\n", " numpy: 1.15.1-py37ha559c80_0\n", " scipy: 1.1.0-py37h4f6bf74_1\n", "\n", "Proceed ([y]/n)?\n", "```"]}, {"cell_type": "markdown", "id": "metropolitan-helping", "metadata": {}, "source": ["> **Note:** It\u2019s worth noting that when you remove a package, all packages that depend on it are also removed."]}, {"cell_type": "markdown", "id": "satisfactory-fourth", "metadata": {}, "source": ["", "\n", "## Cheat Sheet\n", "\n", "[Click here to get access to a Conda cheat sheet](https://static.realpython.com/conda-cheatsheet.pdf) with handy usage examples for managing your Python environment and packages."]}, {"cell_type": "markdown", "id": "confident-dynamics", "metadata": {}, "source": ["", "\n", "## Read More"]}, {"cell_type": "markdown", "id": "silent-hawaii", "metadata": {}, "source": ["Also, if you\u2019d like a deeper understanding of Anaconda and Conda, check out the following links:\n", "\n", "- [Why you need Python environments and how to manage them with Conda](https://medium.freecodecamp.org/why-you-need-python-environments-and-how-to-manage-them-with-conda-85f155f4353c)\n", "- [Conda: Myths and Misconceptions](http://jakevdp.github.io/blog/2016/08/25/conda-myths-and-misconceptions/)"]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/python/01. Basics/03 Interacting with Python.ipynb b/python/01. Basics/03 Interacting with Python.ipynb index e8cb5e2..d097df4 100755 --- a/python/01. Basics/03 Interacting with Python.ipynb +++ b/python/01. Basics/03 Interacting with Python.ipynb @@ -1,610 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Interacting with Python" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Table of Contents\n", - "* [Hello World!](#hello-world)\n", - "* [Different Ways to Execute Python Code](#execute-python)\n", - " * [1. Using the Python Interpreter Interactively](#python-interpreter)\n", - " * [2. IPython](#ipython)\n", - " * [3. Notebook](#notebook)\n", - " * [4. Online Python REPL Sites](#online-repl)\n", - " * [5. Running a Python Script from the Command Line](#command-line)\n", - " * [6. Interacting with Python through an IDE](#ide)\n", - " * [7. Text Editors](#text-editors)\n", - "* [Conclusion](#conclusion)\n", - "* [FAQ](#faq)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "At this point, you should have a working Python 3 interpreter at hand. If you need help getting Python set up correctly, please refer to the previous section on how to interact with Conda." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- There are several ways to run Python code.\n", - "- First let's discuss the various options for development environments. There are 3 main types of environments:\n", - " * Text Editors\n", - " * Full IDEs\n", - " * Notebook Environments\n", - " \n", - " \n", - "**Note:** Development environments are a personal choice highly dependent on personal preference." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Hello, World!\n", - "\n", - "There is a long-standing custom in the field of computer programming that the first code written in a newly installed language is a short program that simply displays the string Hello, World! to the console." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Note: This is a time-honored tradition dating back to the 1970s. See [Hello, World!](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) for a brief history. You seriously risk upsetting the qi of the universe if you don’t abide by this custom." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The simplest Python 3 code to display `Hello, World!` is:\n", - "\n", - "```python\n", - "print(\"Hello World\")\n", - "```\n", - "\n", - "You will explore several different ways to execute this code above." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Different Ways to Execute Python Code" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 1. Using the Python Interpreter Interactively\n", - "\n", - "The most straightforward way to start talking to Python is in an interactive [Read-Eval-Print Loop (REPL)](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) environment. That simply means starting up the interpreter and typing commands to it directly. The interpreter:\n", - "\n", - "- **R**eads the command you enter\n", - "- **E**valuates and executes the command\n", - "- **P**rints the output (if any) to the console\n", - "- **L**oops back and repeats the process\n", - "\n", - "The session continues in this manner until you instruct the interpreter to terminate. Most of the example code in this tutorial series is presented as REPL interaction." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Starting the Interpreter\n", - "\n", - "you can open a terminal window and run the interpreter from the command line. How you go about opening a terminal window varies depending on which operating system you’re using:\n", - "\n", - "- In Windows, it is called **Command Prompt**.\n", - "- In macOS or Linux, it should be called **Terminal**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once a terminal window is open, if paths have been set up properly by the Python install process, you should be able to just type `python`. Then, you should see a response from the Python interpreter.\n", - "\n", - "```bash\n", - "(base) ~ % python\n", - "Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32\n", - "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n", - ">>>\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Technical Note:** If you are on a Linux system and installed Python 3, it may be that both Python 2 and Python 3 are installed. In that case, it is possible that typing python at the prompt will start Python 2. Starting Python 3 may require typing something else, like python3.\n", - ">\n", - "> If you installed a more recent version of Python 3 than the one that was included in the distribution, you may even need to specify the version you installed specifically—for example python3.6." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you are not seeing the `>>>` prompt, then you are not talking to the Python interpreter. This could be because Python is either not installed or not in your terminal window session’s path. It’s also possible that you just haven’t found the correct command to execute it. You can refer to our installing Python section for help." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Executing Python Code\n", - "\n", - "If you are seeing the prompt, you’re off and running! The next step is to execute the statement that displays `Hello, World!` to the console:\n", - "\n", - "1. Ensure that the `>>>` prompt is displayed, and the cursor is positioned after it.\n", - "2. Type the command `print(\"Hello, World!\")` exactly as shown.\n", - "3. Press the Enter key." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The interpreter’s response should appear on the next line. You can tell it is console output because the `>>>` prompt is absent:\n", - "\n", - "```bash\n", - ">>> print(\"Hello, World!\")\n", - "Hello, World!\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If your session looks like the above, then you have executed your first Python code! Take a moment to celebrate." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"notebook\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Exiting the Interpreter\n", - "When you are finished interacting with the interpreter, you can exit a REPL session in several ways:\n", - "\n", - "- Type `exit()` and press Enter:\n", - "\n", - "```bash\n", - ">>> exit()\n", - "\n", - "(base) ~ %\n", - "```\n", - "\n", - "- In Linux or macOS, type `Ctrl+D`. The interpreter terminates immediately; pressing Enter is not needed.\n", - "- If all else fails, you can simply close the interpreter window. This isn’t the best way, but it will get the job done." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Below are a list of other REPLs that you can optionally install to make working in data science more developer-friendly." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 2. IPython\n", - "\n", - "[IPython](https://ipython.org/install.html) is an upgraded Python [read-eval-print loop (REPL)](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) that makes editing code in a live interpreter session more straightforward and prettier. Here’s what an IPython REPL session looks like:\n", - "\n", - "```bash\n", - "In [1]: import numpy as np\n", - "\n", - "In [2]: digits = np.array([\n", - " ...: [1, 2, 3],\n", - " ...: [4, 5, 6],\n", - " ...: [6, 7, 9],\n", - " ...: ])\n", - "\n", - "In [3]: digits\n", - "Out[3]:\n", - "array([[1, 2, 3],\n", - " [4, 5, 6],\n", - " [6, 7, 9]])\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It has several differences from a basic Python REPL, including its line numbers, use of colors, and quality of array visualizations. There are also a lot of user-experience bonuses that make it more pleasant to enter, re-enter, and edit code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can install IPython as a standalone:\n", - "\n", - "```bash\n", - "$ pip install ipython\n", - "```\n", - "\n", - "Alternatively, if you wait and install any of the subsequent tools, then they’ll include a copy of IPython." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 3. Notebook\n", - "\n", - "A slightly more featureful alternative to a REPL is a **notebook**. Notebooks are a slightly different style of writing Python than standard scripts, though. Instead of a traditional Python file, they give you a series of mini-scripts called **cells** that you can run and re-run in whatever order you want, all in the same Python memory session." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One neat thing about notebooks is that you can include graphs and render Markdown paragraphs between cells, so they’re really nice for writing up data analyses right inside the code!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here’s what it looks like:\n", - "\n", - "\"notebook\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The most popular notebook offering is probably the [Jupyter Notebook](https://realpython.com/jupyter-notebook-introduction/), but [nteract](https://nteract.io/)\n", - "is another option that wraps the Jupyter functionality and attempts to make it a bit more approachable and powerful." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "However, if you’re looking at Jupyter Notebook and thinking that it needs more IDE-like qualities, then [JupyterLab](https://jupyterlab.readthedocs.io/en/stable/) is another option. You can customize text editors, notebooks, terminals, and custom components, all in a browser-based interface. It will likely be more comfortable for people coming from [MatLab](https://realpython.com/matlab-vs-python/). It’s the youngest of the offerings, but its 1.0 release was back in 2019, so it should be stable and full featured." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is what the interface looks like:\n", - "\n", - "\"jupyterlab\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Whichever option you choose, once you have it installed, you’ll be ready to run your first lines of data science codes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notebook Environments are:\n", - "\n", - "- Great for learning.\n", - "- See input and output next to each other.\n", - "- Support in-line markdown notes, visualization, videos, and more.\n", - "- Special file formats that are not `.py`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 4. Online Python REPL Sites\n", - "\n", - "There are [websites available](https://realpython.com/installing-python/#online-python-interpreters) that can provide you with interactive access to a Python interpreter online without you having to install anything locally." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This approach may be unsatisfactory for some of the more complicated or lengthy examples in this tutorial. But for simple REPL sessions, it should work well." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Python Software Foundation provides an Interactive Shell on their website. Go directly to https://www.python.org/shell. You should get a page with a window that looks something like this:\n", - "\n", - "\"notebook\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The familiar `>>>` prompt shows you that you are talking to the Python interpreter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here are a few other sites that provide Python REPL:\n", - "\n", - "- [PythonFiddle](http://pythonfiddle.com/)\n", - "- [repl.it](https://repl.it/)\n", - "- [Trinket](https://trinket.io/)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 5. Running a Python Script from the Command Line" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Entering commands to the Python interpreter interactively is great for quick testing and exploring features or functionality." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Eventually though, as you create more complex applications, you will develop longer bodies of code that you will want to edit and run repeatedly. You clearly don’t want to re-type the code into the interpreter every time! This is where you will want to create a script file." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A Python script is a reusable set of code. It is essentially a Python program—a sequence of Python instructions—contained in a file. You can run the program by specifying the name of the script file to the interpreter." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python scripts are just plain text, so you can edit them with any text editor. If you [have a favorite programmer’s editor](https://realpython.com/python-ides-code-editors-guide/) that operates on text files, it should be fine to use. If you don’t, the following are typically installed natively with their respective operating systems:\n", - "\n", - "- Windows: Notepad\n", - "- Unix/Linux: vi or vim\n", - "- macOS: TextEdit\n", - "\n", - "Using whatever editor you’ve chosen, create a script file called `hello.py` containing the following:\n", - "\n", - "```python\n", - "print(\"Hello, World!\")\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now save the file, keeping track of the directory or folder you chose to save into." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Start a command prompt or terminal window. If the current working directory is the same as the location in which you saved the file, you can simply specify the filename as a command-line argument to the Python interpreter: `python hello.py`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, in linux it would look like this:\n", - "\n", - "```bash\n", - "(base) ~ % python hello.py\n", - "Hello, World!\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If the script is not in the current working directory, you can still run it. You’ll just have to specify the path name to it:\n", - "\n", - "```bash\n", - "(base) ~ % python /home/ali/Documents/test/hello.py\n", - "Hello, World!\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A script file is not required to have a `.py` extension. The Python interpreter will run the file no matter what it’s called, so long as you properly specify the file name on the command line, but giving Python files a `.py` extension is a useful convention because it makes them more easily identifiable. In desktop-oriented folder/icon environments like Windows and macOS, this will also typically allow for setting up an appropriate file association, so that you can run the script just by clicking its icon." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 6. Interacting with Python through an IDE\n", - "\n", - "An Integrated Development Environment (IDE) is an application that more or less combines all the functionality you have seen so far. IDEs usually provide REPL capability as well as an editor with which you can create and modify code to then submit to the interpreter for execution." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You may also find cool features such as:\n", - "\n", - "- **Syntax highlighting:** IDEs often colorize different syntax elements in the code to make it easier to read.\n", - "- **Context-sensitive help:** Advanced IDEs can display related information from the Python documentation or even suggested fixes for common types of code errors.\n", - "- **Code-completion:** Some IDEs can complete partially typed pieces of code (like function names) for you—a great time-saver and convenience feature.\n", - "- **Debugging:** A debugger allows you to run code step-by-step and inspect program data as you go. This is invaluable when you are trying to determine why a program is behaving improperly, as will inevitably happen." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### 7. Text Editors\n", - "\n", - "- General editors for any text files.\n", - "- Work with a variety of file types.\n", - "- Can be customized with plugins and add-ons.\n", - "- Keep in mind, most are not desinged with only Python in mind.\n", - "\n", - "Most popular: VSCode, Submile Text, and Atom." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Download and install **[VSCode](https://code.visualstudio.com/download)**. For WSL you just need to install it in your Windows OS and it will automatically download and install it in WSL the first time you run `code` in your WSL terminal." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Run these commands to make sure everything is setup:\n", - "\n", - "```bash\n", - "~ % code --version\n", - "1.57.1\n", - "507ce72a4466fbb27b715c3722558bb15afa9f48\n", - "x64\n", - "```\n", - "\n", - "You should see `vscode` installation version." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Conclusion\n", - "Larger applications are typically contained in script files that are passed to the Python interpreter for execution." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But one of the advantages of an interpreted language is that you can run the interpreter and execute commands interactively. Python is easy to use in this manner, and it is a great way to get your feet wet learning how the language works." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The examples throughout this tutorial have been produced by direct interaction with the Python interpreter, but if you choose to use IDLE or some other available IDE, the examples should still work just fine." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Continue to the next section, where you will start to explore the elements of the Python language itself." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## FAQ" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. How can I launch a jupyter notebook in my computer?\n", - "\n", - "**Answer**: Run `jupyter notebook` in your terminal." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. I'm getting an error when trying to run `jupyter notebook` or `jupyter lab` to run notebook.\n", - "\n", - "![jupyter-error](../images/jupyter-error.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Answer**: Follow these steps:\n", - "1. In your terminal run `jupyter notebook --generate-config`.\n", - "2. It will generate a config file at: `~/.jupyter/jupyter_notebook_config.py`\n", - "3. Open `~/.jupyter/jupyter_notebook_config.py` file, look for `c.NotebookApp.use_redirect_file`.\n", - "4. If `c.NotebookApp.use_redirect_file` exist, uncomment it and set it to `False`. Otherwise add it at the end of the file like this: `c.NotebookApp.use_redirect_file = False`\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Interacting with Python"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Hello, World!](#hello,_world!)\n* [Different Ways to Execute Python Code](#different_ways_to_execute_python_code)\n * [1. Using the Python Interpreter Interactively](#1._using_the_python_interpreter_interactively)\n * [2. IPython](#2._ipython)\n * [3. Notebook](#3._notebook)\n * [4. Online Python REPL Sites](#4._online_python_repl_sites)\n * [5. Running a Python Script from the Command Line](#5._running_a_python_script_from_the_command_line)\n * [6. Interacting with Python through an IDE](#6._interacting_with_python_through_an_ide)\n * [7. Text Editors](#7._text_editors)\n* [Conclusion](#conclusion)\n* [FAQ](#faq)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["At this point, you should have a working Python 3 interpreter at hand. If you need help getting Python set up correctly, please refer to the previous section on how to interact with Conda."]}, {"cell_type": "markdown", "metadata": {}, "source": ["There are several ways to run Python code.\n", "- First let's discuss the various options for development environments. There are 3 main types of environments:\n", " * Text Editors\n", " * Full IDEs\n", " * Notebook Environments\n", " \n", " \n", "**Note:** Development environments are a personal choice highly dependent on personal preference."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Hello, World!\n", "\n", "There is a long-standing custom in the field of computer programming that the first code written in a newly installed language is a short program that simply displays the string Hello, World! to the console."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Note: This is a time-honored tradition dating back to the 1970s. See [Hello, World!](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) for a brief history. You seriously risk upsetting the qi of the universe if you don\u2019t abide by this custom."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The simplest Python 3 code to display `Hello, World!` is:\n", "\n", "```python\n", "print(\"Hello World\")\n", "```\n", "\n", "You will explore several different ways to execute this code above."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Different Ways to Execute Python Code"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 1. Using the Python Interpreter Interactively\n", "\n", "The most straightforward way to start talking to Python is in an interactive [Read-Eval-Print Loop (REPL)](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) environment. That simply means starting up the interpreter and typing commands to it directly. The interpreter:\n", "\n", "- **R**eads the command you enter\n", "- **E**valuates and executes the command\n", "- **P**rints the output (if any) to the console\n", "- **L**oops back and repeats the process\n", "\n", "The session continues in this manner until you instruct the interpreter to terminate. Most of the example code in this tutorial series is presented as REPL interaction."]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Starting the Interpreter\n", "\n", "you can open a terminal window and run the interpreter from the command line. How you go about opening a terminal window varies depending on which operating system you\u2019re using:\n", "\n", "- In Windows, it is called **Command Prompt**.\n", "- In macOS or Linux, it should be called **Terminal**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Once a terminal window is open, if paths have been set up properly by the Python install process, you should be able to just type `python`. Then, you should see a response from the Python interpreter.\n", "\n", "```bash\n", "(base) ~ % python\n", "Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32\n", "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n", ">>>\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Technical Note:** If you are on a Linux system and installed Python 3, it may be that both Python 2 and Python 3 are installed. In that case, it is possible that typing python at the prompt will start Python 2. Starting Python 3 may require typing something else, like python3.\n", ">\n", "> If you installed a more recent version of Python 3 than the one that was included in the distribution, you may even need to specify the version you installed specifically\u2014for example python3.6."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you are not seeing the `>>>` prompt, then you are not talking to the Python interpreter. This could be because Python is either not installed or not in your terminal window session\u2019s path. It\u2019s also possible that you just haven\u2019t found the correct command to execute it. You can refer to our installing Python section for help."]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Executing Python Code\n", "\n", "If you are seeing the prompt, you\u2019re off and running! The next step is to execute the statement that displays `Hello, World!` to the console:\n", "\n", "1. Ensure that the `>>>` prompt is displayed, and the cursor is positioned after it.\n", "2. Type the command `print(\"Hello, World!\")` exactly as shown.\n", "3. Press the Enter key."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The interpreter\u2019s response should appear on the next line. You can tell it is console output because the `>>>` prompt is absent:\n", "\n", "```bash\n", ">>> print(\"Hello, World!\")\n", "Hello, World!\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If your session looks like the above, then you have executed your first Python code! Take a moment to celebrate."]}, {"cell_type": "markdown", "metadata": {}, "source": ["\"notebook\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Exiting the Interpreter\n", "When you are finished interacting with the interpreter, you can exit a REPL session in several ways:\n", "\n", "- Type `exit()` and press Enter:\n", "\n", "```bash\n", ">>> exit()\n", "\n", "(base) ~ %\n", "```\n", "\n", "- In Linux or macOS, type `Ctrl+D`. The interpreter terminates immediately; pressing Enter is not needed.\n", "- If all else fails, you can simply close the interpreter window. This isn\u2019t the best way, but it will get the job done."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Below are a list of other REPLs that you can optionally install to make working in data science more developer-friendly."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 2. IPython\n", "\n", "[IPython](https://ipython.org/install.html) is an upgraded Python [read-eval-print loop (REPL)](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) that makes editing code in a live interpreter session more straightforward and prettier. Here\u2019s what an IPython REPL session looks like:\n", "\n", "```bash\n", "In [1]: import numpy as np\n", "\n", "In [2]: digits = np.array([\n", " ...: [1, 2, 3],\n", " ...: [4, 5, 6],\n", " ...: [6, 7, 9],\n", " ...: ])\n", "\n", "In [3]: digits\n", "Out[3]:\n", "array([[1, 2, 3],\n", " [4, 5, 6],\n", " [6, 7, 9]])\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It has several differences from a basic Python REPL, including its line numbers, use of colors, and quality of array visualizations. There are also a lot of user-experience bonuses that make it more pleasant to enter, re-enter, and edit code."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can install IPython as a standalone:\n", "\n", "```bash\n", "$ pip install ipython\n", "```\n", "\n", "Alternatively, if you wait and install any of the subsequent tools, then they\u2019ll include a copy of IPython."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 3. Notebook\n", "\n", "A slightly more featureful alternative to a REPL is a **notebook**. Notebooks are a slightly different style of writing Python than standard scripts, though. Instead of a traditional Python file, they give you a series of mini-scripts called **cells** that you can run and re-run in whatever order you want, all in the same Python memory session."]}, {"cell_type": "markdown", "metadata": {}, "source": ["One neat thing about notebooks is that you can include graphs and render Markdown paragraphs between cells, so they\u2019re really nice for writing up data analyses right inside the code!"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here\u2019s what it looks like:\n", "\n", "\"notebook\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["The most popular notebook offering is probably the [Jupyter Notebook](https://realpython.com/jupyter-notebook-introduction/), but [nteract](https://nteract.io/)\n", "is another option that wraps the Jupyter functionality and attempts to make it a bit more approachable and powerful."]}, {"cell_type": "markdown", "metadata": {}, "source": ["However, if you\u2019re looking at Jupyter Notebook and thinking that it needs more IDE-like qualities, then [JupyterLab](https://jupyterlab.readthedocs.io/en/stable/) is another option. You can customize text editors, notebooks, terminals, and custom components, all in a browser-based interface. It will likely be more comfortable for people coming from [MatLab](https://realpython.com/matlab-vs-python/). It\u2019s the youngest of the offerings, but its 1.0 release was back in 2019, so it should be stable and full featured."]}, {"cell_type": "markdown", "metadata": {}, "source": ["This is what the interface looks like:\n", "\n", "\"jupyterlab\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["Whichever option you choose, once you have it installed, you\u2019ll be ready to run your first lines of data science codes."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Notebook Environments are:\n", "\n", "- Great for learning.\n", "- See input and output next to each other.\n", "- Support in-line markdown notes, visualization, videos, and more.\n", "- Special file formats that are not `.py`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 4. Online Python REPL Sites\n", "\n", "There are [websites available](https://realpython.com/installing-python/#online-python-interpreters) that can provide you with interactive access to a Python interpreter online without you having to install anything locally."]}, {"cell_type": "markdown", "metadata": {}, "source": ["This approach may be unsatisfactory for some of the more complicated or lengthy examples in this tutorial. But for simple REPL sessions, it should work well."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The Python Software Foundation provides an Interactive Shell on their website. Go directly to https://www.python.org/shell. You should get a page with a window that looks something like this:\n", "\n", "\"notebook\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["The familiar `>>>` prompt shows you that you are talking to the Python interpreter."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here are a few other sites that provide Python REPL:\n", "\n", "- [PythonFiddle](http://pythonfiddle.com/)\n", "- [repl.it](https://repl.it/)\n", "- [Trinket](https://trinket.io/)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 5. Running a Python Script from the Command Line"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Entering commands to the Python interpreter interactively is great for quick testing and exploring features or functionality."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Eventually though, as you create more complex applications, you will develop longer bodies of code that you will want to edit and run repeatedly. You clearly don\u2019t want to re-type the code into the interpreter every time! This is where you will want to create a script file."]}, {"cell_type": "markdown", "metadata": {}, "source": ["A Python script is a reusable set of code. It is essentially a Python program\u2014a sequence of Python instructions\u2014contained in a file. You can run the program by specifying the name of the script file to the interpreter."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python scripts are just plain text, so you can edit them with any text editor. If you [have a favorite programmer\u2019s editor](https://realpython.com/python-ides-code-editors-guide/) that operates on text files, it should be fine to use. If you don\u2019t, the following are typically installed natively with their respective operating systems:\n", "\n", "- Windows: Notepad\n", "- Unix/Linux: vi or vim\n", "- macOS: TextEdit\n", "\n", "Using whatever editor you\u2019ve chosen, create a script file called `hello.py` containing the following:\n", "\n", "```python\n", "print(\"Hello, World!\")\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now save the file, keeping track of the directory or folder you chose to save into."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Start a command prompt or terminal window. If the current working directory is the same as the location in which you saved the file, you can simply specify the filename as a command-line argument to the Python interpreter: `python hello.py`"]}, {"cell_type": "markdown", "metadata": {}, "source": ["For example, in linux it would look like this:\n", "\n", "```bash\n", "(base) ~ % python hello.py\n", "Hello, World!\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If the script is not in the current working directory, you can still run it. You\u2019ll just have to specify the path name to it:\n", "\n", "```bash\n", "(base) ~ % python /home/ali/Documents/test/hello.py\n", "Hello, World!\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A script file is not required to have a `.py` extension. The Python interpreter will run the file no matter what it\u2019s called, so long as you properly specify the file name on the command line, but giving Python files a `.py` extension is a useful convention because it makes them more easily identifiable. In desktop-oriented folder/icon environments like Windows and macOS, this will also typically allow for setting up an appropriate file association, so that you can run the script just by clicking its icon."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 6. Interacting with Python through an IDE\n", "\n", "An Integrated Development Environment (IDE) is an application that more or less combines all the functionality you have seen so far. IDEs usually provide REPL capability as well as an editor with which you can create and modify code to then submit to the interpreter for execution."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You may also find cool features such as:\n", "\n", "- **Syntax highlighting:** IDEs often colorize different syntax elements in the code to make it easier to read.\n", "- **Context-sensitive help:** Advanced IDEs can display related information from the Python documentation or even suggested fixes for common types of code errors.\n", "- **Code-completion:** Some IDEs can complete partially typed pieces of code (like function names) for you\u2014a great time-saver and convenience feature.\n", "- **Debugging:** A debugger allows you to run code step-by-step and inspect program data as you go. This is invaluable when you are trying to determine why a program is behaving improperly, as will inevitably happen."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### 7. Text Editors\n", "\n", "- General editors for any text files.\n", "- Work with a variety of file types.\n", "- Can be customized with plugins and add-ons.\n", "- Keep in mind, most are not desinged with only Python in mind.\n", "\n", "Most popular: VSCode, Submile Text, and Atom."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Download and install **[VSCode](https://code.visualstudio.com/download)**. For WSL you just need to install it in your Windows OS and it will automatically download and install it in WSL the first time you run `code` in your WSL terminal."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Run these commands to make sure everything is setup:\n", "\n", "```bash\n", "~ % code --version\n", "1.57.1\n", "507ce72a4466fbb27b715c3722558bb15afa9f48\n", "x64\n", "```\n", "\n", "You should see `vscode` installation version."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "Larger applications are typically contained in script files that are passed to the Python interpreter for execution."]}, {"cell_type": "markdown", "metadata": {}, "source": ["But one of the advantages of an interpreted language is that you can run the interpreter and execute commands interactively. Python is easy to use in this manner, and it is a great way to get your feet wet learning how the language works."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The examples throughout this tutorial have been produced by direct interaction with the Python interpreter, but if you choose to use IDLE or some other available IDE, the examples should still work just fine."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Continue to the next section, where you will start to explore the elements of the Python language itself."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## FAQ"]}, {"cell_type": "markdown", "metadata": {}, "source": ["1. How can I launch a jupyter notebook in my computer?\n", "\n", "**Answer**: Run `jupyter notebook` in your terminal."]}, {"cell_type": "markdown", "metadata": {}, "source": ["2. I'm getting an error when trying to run `jupyter notebook` or `jupyter lab` to run notebook.\n", "\n", "![jupyter-error](../images/jupyter-error.png)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Answer**: Follow these steps:\n", "1. In your terminal run `jupyter notebook --generate-config`.\n", "2. It will generate a config file at: `~/.jupyter/jupyter_notebook_config.py`\n", "3. Open `~/.jupyter/jupyter_notebook_config.py` file, look for `c.NotebookApp.use_redirect_file`.\n", "4. If `c.NotebookApp.use_redirect_file` exist, uncomment it and set it to `False`. Otherwise add it at the end of the file like this: `c.NotebookApp.use_redirect_file = False`\n"]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/04 Basic Data Types.ipynb b/python/01. Basics/04 Basic Data Types.ipynb index 448b2ea..2697ae3 100755 --- a/python/01. Basics/04 Basic Data Types.ipynb +++ b/python/01. Basics/04 Basic Data Types.ipynb @@ -1,1531 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Basic Data Types" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now you know how to interact with the Python interpreter and execute Python code. It’s time to dig into the Python language. First up is a discussion of the basic data types that are built into Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "## Basic Data Types" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Integers" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python 3, there is effectively no limit to how long an integer value can be. Of course, it is constrained by the amount of memory your system has, as are all things, but beyond that an integer can be as long as you need it to be:" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "28" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import sys\n", - "sys.getsizeof(1)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "123123123123123123123123123123123123123123123123\n" - ] - } - ], - "source": [ - "print(123123123123123123123123123123123123123123123123)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python interprets a sequence of decimal digits without any prefix to be a decimal number:" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10\n" - ] - } - ], - "source": [ - "print(10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The following strings can be prepended to an integer value to indicate a base other than 10:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "|Prefix|Interpretation|Base|\n", - "|:--|:--|:--|\n", - "|`0b` (zero + lowercase letter `'b'`) |Binary|2|\n", - "|`0B` (zero + uppercase letter `'B'`) |Binary |2|\n", - "|`0o` (zero + lowercase letter `'o'`) |Octal|8|\n", - "|`0O` (zero + uppercase letter `'O'`) |Octal |8|\n", - "|`0x` (zero + lowercase letter `'x'`) |Hexadecimal|16|\n", - "|`0X` (zero + uppercase letter `'X'`) |Hexadecimal |16|" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "8\n" - ] - } - ], - "source": [ - "# octal\n", - "print(0o10)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "16\n" - ] - } - ], - "source": [ - "# Hexadecimal\n", - "print(0x10)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2\n" - ] - } - ], - "source": [ - "# Binary\n", - "print(0b10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For more information on integer values with non-decimal bases, see the following Wikipedia sites: [Binary](https://en.wikipedia.org/wiki/Binary_number), [Octal](https://en.wikipedia.org/wiki/Octal), and [Hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The underlying type of a Python integer, irrespective of the base used to specify it, is called int:" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(10)" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(0o10)" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(0x10)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** This is a good time to mention that if you want to display a value while in a REPL session, you don’t need to use the `print()` function. Just typing the value at the `>>>` prompt and hitting _Enter_ will display it:\n", - ">\n", - ">```bash\n", - ">>> 10\n", - "10\n", - ">>> 0x10\n", - "16\n", - ">>> 0b10\n", - "2\n", - ">```\n", - "Many of the examples in this tutorial series will use this feature.\n", - ">\n", - "> Note that this does not work inside a script file. A value appearing on a line by itself in a script file will not do anything." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Floating-Point Numbers\n", - "\n", - "The float type in Python designates a floating-point number. `float` values are specified with a decimal point. Optionally, the character `e` or `E` followed by a positive or negative integer may be appended to specify [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation):" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.2" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "4.2" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "float" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(4.2)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4.0" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "4." - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.2" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - ".2" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4000000.0" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - ".4e7" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "float" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(.4e7)" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.00042" - ] - }, - "execution_count": 83, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "4.2e-4" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> Deep Dive: **Floating-Point Representation**\n", - ">\n", - "> The following is a bit more in-depth information on how Python represents floating-point numbers internally. You can readily use floating-point numbers in Python without understanding them to this level, so don’t worry if this seems overly complicated. The information is presented here in case you are curious.\n", - ">\n", - "> Almost all platforms represent Python float values as 64-bit “double-precision” values, according to the [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754_revision) standard. In that case, the maximum value a floating-point number can have is approximately $1.8 \\times 10^{308}$. Python will indicate a number greater than that by the string inf:\n", - ">\n", - "> ```bash\n", - ">>> 1.79e308\n", - "1.79e+308\n", - ">>> 1.8e308\n", - "inf\n", - "> ```\n", - "> The closest a nonzero number can be to zero is approximately $5.0 \\times 10^{-324}$. Anything closer to zero than that is effectively zero:\n", - "> \n", - "> ```bash\n", - ">>> 5e-324\n", - "5e-324\n", - ">>> 1e-325\n", - "0.0\n", - "> ```\n", - "> Floating point numbers are represented internally as binary (base-2) fractions. Most decimal fractions cannot be represented exactly as binary fractions, so in most cases the internal representation of a floating-point number is an approximation of the actual value. In practice, the difference between the actual value and the represented value is very small and should not usually cause significant problems." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Further Reading:** For additional information on floating-point representation in Python and the potential pitfalls involved, see [Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3.6/tutorial/floatingpoint.html) in the Python documentation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Complex Numbers\n", - "\n", - "Complex numbers are specified as `+j`. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2+3j)" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "2+3j" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "complex" - ] - }, - "execution_count": 95, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(2+3j)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### FAQ\n", - "\n", - "1. What's the difference between floating point and an integer?\n", - "\n", - "An integer has no decimals in it, a floating point number can display digits past the decimal point.\n", - "\n", - "2. Why doesn't `0.1 + 0.2 - 0.3` equal `0.0` ?\n", - "\n", - "This has to do with floating point accuracy and computer's abilities to represent numbers in memory. For a full breakdown, check out: https://docs.python.org/2/tutorial/floatingpoint.html" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 103, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Why is this False? Refer to FAQ above.\n", - "0.1 + 0.2 - 0.3 == 0.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Strings\n", - "\n", - "Strings are sequences of character data. The string type in Python is called `str`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "String literals may be delimited using either single or double quotes. All the characters between the opening delimiter and matching closing delimiter are part of the string:" - ] - }, - { - "cell_type": "code", - "execution_count": 115, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I am a string.\n" - ] - } - ], - "source": [ - "print(\"I am a string.\")" - ] - }, - { - "cell_type": "code", - "execution_count": 116, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "str" - ] - }, - "execution_count": 116, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(\"I am a string.\")" - ] - }, - { - "cell_type": "code", - "execution_count": 117, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I am too.\n" - ] - } - ], - "source": [ - "print('I am too.')" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "str" - ] - }, - "execution_count": 118, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type('I am too.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A string in Python can contain as many characters as you wish. The only limit is your machine’s memory resources. A string can also be empty:" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "''" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\"\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What if you want to include a quote character as part of the string itself? Your first impulse might be to try something like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 99, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print('This string contains a single quote (') character.')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "print('This string contains a single quote (') character.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see, that doesn’t work so well. The string in this example opens with a single quote, so Python assumes the next single quote, the one in parentheses which was intended to be part of the string, is the closing delimiter. The final single quote is then a stray and causes the syntax error shown." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you want to include either type of quote character within the string, the simplest way is to delimit the string with the other type. If a string is to contain a single quote, delimit it with double quotes and vice versa:" - ] - }, - { - "cell_type": "code", - "execution_count": 100, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This string contains a single quote (') character.\n" - ] - } - ], - "source": [ - "print(\"This string contains a single quote (') character.\")" - ] - }, - { - "cell_type": "code", - "execution_count": 101, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This string contains a double quote (\") character.\n" - ] - } - ], - "source": [ - "print('This string contains a double quote (\") character.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Escape Sequences in Strings\n", - "Sometimes, you want Python to interpret a character or sequence of characters within a string differently. This may occur in one of two ways:\n", - "- You may want to suppress the special interpretation that certain characters are usually given within a string.\n", - "- You may want to apply special interpretation to characters in a string which would normally be taken literally." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can accomplish this using a backslash (`\\`) character. A backslash character in a string indicates that one or more characters that follow it should be treated specially. (This is referred to as an escape sequence, because the backslash causes the subsequent character sequence to “escape” its usual meaning.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let’s see how this works." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Suppressing Special Character Meaning\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You have already seen the problems you can come up against when you try to include quote characters in a string. If a string is delimited by single quotes, you can’t directly specify a single quote character as part of the string because, for that string, the single quote has special meaning—it terminates the string:" - ] - }, - { - "cell_type": "code", - "execution_count": 130, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print('This string contains a single quote (') character.')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "print('This string contains a single quote (') character.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Specifying a backslash in front of the quote character in a string “escapes” it and causes Python to suppress its usual special meaning. It is then interpreted simply as a literal single quote character:" - ] - }, - { - "cell_type": "code", - "execution_count": 131, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This string contains a single quote (') character.\n" - ] - } - ], - "source": [ - "print('This string contains a single quote (\\') character.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The same works in a string delimited by double quotes as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 132, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This string contains a double quote (\") character.\n" - ] - } - ], - "source": [ - "print(\"This string contains a double quote (\\\") character.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The following is a table of escape sequences which cause Python to suppress the usual special interpretation of a character in a string:\n", - "\n", - "|Escape Sequence | Usual Interpretation of Character(s) After Backslash| “Escaped” Interpretation |\n", - "|:--|:--|:--|\n", - "|`\\'` | Terminates string with single quote opening delimiter | Literal single quote (`'`) character|\n", - "|`\\\"` | Terminates string with double quote opening delimiter | Literal double quote (`\"`) character|\n", - "|`\\\\` | Introduces escape sequence | Literal backslash (`\\`) character | " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Ordinarily, a newline character terminates line input. So pressing _Enter_ in the middle of a string will cause Python to think it is incomplete:" - ] - }, - { - "cell_type": "code", - "execution_count": 137, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "EOL while scanning string literal (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print('a\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n" - ] - } - ], - "source": [ - "print('a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To break up a string over more than one line, include a backslash before each newline, and the newlines will be ignored:" - ] - }, - { - "cell_type": "code", - "execution_count": 149, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "asldjflasdjflasdjflasdjflasdjflasjflasdjfl32972394723947asdjfalsjflsdfjlajfslasdfj\n" - ] - } - ], - "source": [ - "print('asldjflasdjfl\\\n", - "asdjflasdjflasdjflas\\\n", - "jflasdjfl329723947239\\\n", - "47asdjfalsjflsdfjlajf\\\n", - "slasdfj')" - ] - }, - { - "cell_type": "code", - "execution_count": 150, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "abc\n" - ] - } - ], - "source": [ - "print('a\\\n", - "b\\\n", - "c')" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a very very very very very very very long string.\n" - ] - } - ], - "source": [ - "print('a very very very \\\n", - "very very very \\\n", - "very long string.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To include a literal backslash in a string, escape it with a backslash:" - ] - }, - { - "cell_type": "code", - "execution_count": 152, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\\bar\n" - ] - } - ], - "source": [ - "print('foo\\\\bar')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Applying Special Meaning to Characters\n", - "\n", - "Next, suppose you need to create a string that contains a tab character in it. Some text editors may allow you to insert a tab character directly into your code. But many programmers consider that poor practice, for several reasons:\n", - "\n", - "- The computer can distinguish between a tab character and a sequence of space characters, but you can’t. To a human reading the code, tab and space characters are visually indistinguishable.\n", - "- Some text editors are configured to automatically eliminate tab characters by expanding them to the appropriate number of spaces.\n", - "- Some Python REPL environments will not insert tabs into code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python (and almost all other common computer languages), a tab character can be specified by the escape sequence `\\t`:" - ] - }, - { - "cell_type": "code", - "execution_count": 98, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fooo\tbar\n" - ] - } - ], - "source": [ - "print('fooo\\tbar')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The escape sequence `\\t` causes the `t` character to lose its usual meaning, that of a literal t. Instead, the combination is interpreted as a tab character." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a list of escape sequences that cause Python to apply special meaning instead of interpreting literally:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "|Escape Sequence | “Escaped” Interpretation |\n", - "|:--|:--|\n", - "|`\\a` |\tASCII Bell (BEL) character |\n", - "|`\\b` |\tASCII Backspace (BS) character |\n", - "|`\\f` |\tASCII Formfeed (FF) character |\n", - "|`\\n` |\tASCII Linefeed (LF) character |\n", - "|`\\N{}` |\tCharacter from Unicode database with given `` |\n", - "|`\\r` |\tASCII Carriage Return (CR) character |\n", - "|`\\t` |\tASCII Horizontal Tab (TAB) character |\n", - "|`\\uxxxx` |\tUnicode character with 16-bit hex value `xxxx` |\n", - "|`\\Uxxxxxxxx` |\tUnicode character with 32-bit hex value `xxxxxxxx` |\n", - "|`\\v` |\tASCII Vertical Tab (VT) character |\n", - "|`\\ooo` |\tCharacter with octal value ooo |\n", - "|`\\xhh` |\tCharacter with hex value hh |" - ] - }, - { - "cell_type": "code", - "execution_count": 122, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a\tb\n" - ] - } - ], - "source": [ - "print(\"a\\tb\")" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "aaa\n" - ] - } - ], - "source": [ - "print(\"a\\141\\x61\")" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "a\n", - "b\n" - ] - } - ], - "source": [ - "print(\"a\\nb\")" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "→ →\n" - ] - } - ], - "source": [ - "print('\\u2192 \\N{rightwards arrow}')" - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "print(\"\\u0033\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This type of escape sequence is typically used to insert characters that are not readily generated from the keyboard or are not easily readable or printable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** See the [list of Unicode Characters](https://en.wikipedia.org/wiki/List_of_Unicode_characters)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Raw Strings\n", - "\n", - "A raw string literal is preceded by r or R, which specifies that escape sequences in the associated string are not translated. The backslash character is left in the string:" - ] - }, - { - "cell_type": "code", - "execution_count": 137, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "bar\n" - ] - } - ], - "source": [ - "print('foo\\nbar')" - ] - }, - { - "cell_type": "code", - "execution_count": 138, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\\nbar\n" - ] - } - ], - "source": [ - "print(r'foo\\nbar')" - ] - }, - { - "cell_type": "code", - "execution_count": 139, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\\bar\n" - ] - } - ], - "source": [ - "print('foo\\\\bar')" - ] - }, - { - "cell_type": "code", - "execution_count": 140, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\\\\bar\n" - ] - } - ], - "source": [ - "print(R'foo\\\\bar')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Triple-Quoted Strings\n", - "\n", - "There is yet another way of delimiting strings in Python. Triple-quoted strings are delimited by matching groups of three single quotes or three double quotes. Escape sequences still work in triple-quoted strings, but single quotes, double quotes, and newlines can be included without escaping them. This provides a convenient way to create a string with both single and double quotes in it:" - ] - }, - { - "cell_type": "code", - "execution_count": 145, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This string has a single (') and a double (\") quote.\n" - ] - } - ], - "source": [ - "print('''This string has a single (') and a double (\") quote.''')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Because newlines can be included without escaping them, this also allows for multiline strings:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This is a\n", - "string that spans\n", - "across several lines\n", - "\n" - ] - } - ], - "source": [ - "print(\"\"\"This is a\n", - "string that spans\n", - "across several lines\n", - "\"\"\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Boolean Type, Boolean Context, and “Truthiness”" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python 3 provides a Boolean data type. Objects of Boolean type may have one of two values, True or False:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "bool" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(True)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "bool" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you will see in upcoming section, expressions in Python are often evaluated in Boolean context, meaning they are interpreted to represent truth or falsehood. A value that is true in Boolean context is sometimes said to be “truthy,” and one that is false in Boolean context is said to be “falsy.” (You may also see “falsy” spelled “falsey.”)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The “truthiness” of an object of Boolean type is self-evident: Boolean objects that are equal to True are truthy (`True`), and those equal to False are falsy (`False`). But non-Boolean objects can be evaluated in Boolean context as well and determined to be true or false." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You will learn more about evaluation of objects in Boolean context when you encounter logical operators in the upcoming sections on operators and expressions in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Built-In Functions\n", - "\n", - "The Python interpreter supports many functions that are built-in: sixty-eight, as of Python 3.6. You will cover many of these in the following discussions, as they come up in context." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For now, a brief overview follows, just to give a feel for what is available. See the [Python documentation on built-in functions](https://docs.python.org/3.6/library/functions.html) for more detail. Many of the following descriptions refer to topics and concepts that will be discussed in future tutorials." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Math\n", - "\n", - "|Function | Description |\n", - "|:--|:--|\n", - "|`abs()`\t| Returns absolute value of a number |\n", - "|`divmod()`\t| Returns quotient and remainder of integer division |\n", - "|`max()`\t| Returns the largest of the given arguments or items in an iterable |\n", - "|`min()`\t| Returns the smallest of the given arguments or items in an iterable |\n", - "|`pow()`\t| Raises a number to a power |\n", - "|`round()`\t| Rounds a floating-point value |\n", - "|`sum()`\t| Sums the items of an iterable |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Type Conversion\n", - "\n", - "| Function | Description |\n", - "|:--|:--|\n", - "|`ascii()` |\tReturns a string containing a printable representation of an object |\n", - "|`bin()` |\tConverts an integer to a binary string |\n", - "|`bool()` |\tConverts an argument to a Boolean value |\n", - "|`chr()` |\tReturns string representation of character given by integer argument |\n", - "|`complex()` |\tReturns a complex number constructed from arguments |\n", - "|`float()` |\tReturns a floating-point object constructed from a number or string |\n", - "|`hex()` |\tConverts an integer to a hexadecimal string |\n", - "|`int()` |\tReturns an integer object constructed from a number or string |\n", - "|`oct()` |\tConverts an integer to an octal string |\n", - "|`ord()` |\tReturns integer representation of a character |\n", - "|`repr()` |\tReturns a string containing a printable representation of an object |\n", - "|`str()` |\tReturns a string version of an object |\n", - "|`type()` |\tReturns the type of an object or creates a new type object |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Iterables and Iterators\n", - "|Function | Description|\n", - "|:--|:--|\n", - "|`all()`| Returns True if all elements of an iterable are true|\n", - "|`any()`| Returns True if any elements of an iterable are true|\n", - "|`enumerate()`| Returns a list of tuples containing indices and values from an iterable|\n", - "|`filter()`| Filters elements from an iterable|\n", - "|`iter()`| Returns an iterator object|\n", - "|`len()`| Returns the length of an object|\n", - "|`map()`| Applies a function to every item of an iterable|\n", - "|`next()`| Retrieves the next item from an iterator|\n", - "|`range()`| Generates a range of integer values|\n", - "|`reversed()`| Returns a reverse iterator|\n", - "|`slice()`| Returns a slice object|\n", - "|`sorted()`| Returns a sorted list from an iterable|\n", - "|`zip()`| Creates an iterator that aggregates elements from iterables|" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Composite Data Type\n", - "|Function | Description|\n", - "|:--|:--|\n", - "| `bytearray()` | \tCreates and returns an object of the bytearray class |\n", - "| `bytes()` | \tCreates and returns a bytes object (similar to bytearray, but immutable) |\n", - "| `dict()` | \tCreates a dict object |\n", - "| `frozenset()` | \tCreates a frozenset object |\n", - "| `list()` | \tCreates a list object |\n", - "| `object()` | \tCreates a new featureless object |\n", - "| `set()` | \tCreates a set object |\n", - "| `tuple()` | \tCreates a tuple object |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Classes, Attributes, and Inheritance\n", - "|Function | Description|\n", - "|:--|:--|\n", - "| `classmethod()` |\tReturns a class method for a function |\n", - "| `delattr()` |\tDeletes an attribute from an object |\n", - "| `getattr()` |\tReturns the value of a named attribute of an object |\n", - "| `hasattr()` |\tReturns True if an object has a given attribute |\n", - "| `isinstance()` |\tDetermines whether an object is an instance of a given class |\n", - "| `issubclass()` |\tDetermines whether a class is a subclass of a given class |\n", - "| `property()` |\tReturns a property value of a class |\n", - "| `setattr()` |\tSets the value of a named attribute of an object |\n", - "| `super()` |\tReturns a proxy object that delegates method calls to a parent or sibling class |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Input/Output\n", - "|Function | Description|\n", - "|:--|:--|\n", - "|`format()` |\tConverts a value to a formatted representation |\n", - "|`input()` |\tReads input from the console |\n", - "|`open()` |\tOpens a file and returns a file object |\n", - "|`print()` |\tPrints to a text stream or the console |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Variables, References, and Scope\n", - "|Function | Description|\n", - "|:--|:--|\n", - "|`dir()` | Returns a list of names in current local scope or a list of object attributes |\n", - "|`globals()` | Returns a dictionary representing the current global symbol table |\n", - "|`id()` | Returns the identity of an object |\n", - "|`locals()` | Updates and returns a dictionary representing current local symbol table |\n", - "|`vars()` | Returns __dict__ attribute for a module, class, or object |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Miscellaneous\n", - "|Function | Description|\n", - "|:--|:--|\n", - "|`callable()` | Returns True if object appears callable |\n", - "|`compile()` | Compiles source into a code or AST object |\n", - "|`eval()` | Evaluates a Python expression |\n", - "|`exec()` | Implements dynamic execution of Python code |\n", - "|`hash()` | Returns the hash value of an object |\n", - "|`help()` | Invokes the built-in help system |\n", - "|`memoryview()` | Returns a memory view object |\n", - "|`staticmethod()` | Returns a static method for a function |\n", - "|`__import__()` | Invoked by the import statement |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "In this section, you learned about the built-in data types and functions Python provides.\n", - "\n", - "The examples given so far have all manipulated and displayed only constant values. In most programs, you are usually going to want to create objects that change in value as the program executes.\n", - "\n", - "Head to the next section to learn about Python variables." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Basic Data Types"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Integers](#integers)\n* [Floating-Point Numbers](#floating-point_numbers)\n* [Complex Numbers](#complex_numbers)\n* [Strings](#strings)\n * [Escape Sequences in Strings](#escape_sequences_in_strings)\n * [Applying Special Meaning to Characters](#applying_special_meaning_to_characters)\n * [Raw Strings](#raw_strings)\n * [Triple-Quoted Strings](#triple-quoted_strings)\n* [Boolean Type, Boolean Context, and \u201cTruthiness\u201d](#boolean_type,_boolean_context,_and_\u201ctruthiness\u201d)\n* [Built-In Functions](#built-in_functions)\n * [Math](#math)\n * [Type Conversion](#type_conversion)\n * [Iterables and Iterators](#iterables_and_iterators)\n * [Composite Data Type](#composite_data_type)\n * [Classes, Attributes, and Inheritance](#classes,_attributes,_and_inheritance)\n * [Input/Output](#input/output)\n * [Variables, References, and Scope](#variables,_references,_and_scope)\n * [Miscellaneous](#miscellaneous)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now you know how to interact with the Python interpreter and execute Python code. It\u2019s time to dig into the Python language. First up is a discussion of the basic data types that are built into Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Integers"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In Python 3, there is effectively no limit to how long an integer value can be. Of course, it is constrained by the amount of memory your system has, as are all things, but beyond that an integer can be as long as you need it to be:"]}, {"cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [{"data": {"text/plain": ["28"]}, "execution_count": 39, "metadata": {}, "output_type": "execute_result"}], "source": ["import sys\n", "sys.getsizeof(1)"]}, {"cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["123123123123123123123123123123123123123123123123\n"]}], "source": ["print(123123123123123123123123123123123123123123123123)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python interprets a sequence of decimal digits without any prefix to be a decimal number:"]}, {"cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["10\n"]}], "source": ["print(10)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The following strings can be prepended to an integer value to indicate a base other than 10:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["|Prefix|Interpretation|Base|\n", "|:--|:--|:--|\n", "|`0b` (zero + lowercase letter `'b'`) |Binary|2|\n", "|`0B` (zero + uppercase letter `'B'`) |Binary |2|\n", "|`0o` (zero + lowercase letter `'o'`) |Octal|8|\n", "|`0O` (zero + uppercase letter `'O'`) |Octal |8|\n", "|`0x` (zero + lowercase letter `'x'`) |Hexadecimal|16|\n", "|`0X` (zero + uppercase letter `'X'`) |Hexadecimal |16|"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["8\n"]}], "source": ["# octal\n", "print(0o10)"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["16\n"]}], "source": ["# Hexadecimal\n", "print(0x10)"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["2\n"]}], "source": ["# Binary\n", "print(0b10)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["For more information on integer values with non-decimal bases, see the following Wikipedia sites: [Binary](https://en.wikipedia.org/wiki/Binary_number), [Octal](https://en.wikipedia.org/wiki/Octal), and [Hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The underlying type of a Python integer, irrespective of the base used to specify it, is called int:"]}, {"cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 74, "metadata": {}, "output_type": "execute_result"}], "source": ["type(10)"]}, {"cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 75, "metadata": {}, "output_type": "execute_result"}], "source": ["type(0o10)"]}, {"cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 76, "metadata": {}, "output_type": "execute_result"}], "source": ["type(0x10)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** This is a good time to mention that if you want to display a value while in a REPL session, you don\u2019t need to use the `print()` function. Just typing the value at the `>>>` prompt and hitting _Enter_ will display it:\n", ">\n", ">```bash\n", ">>> 10\n", "10\n", ">>> 0x10\n", "16\n", ">>> 0b10\n", "2\n", ">```\n", "Many of the examples in this tutorial series will use this feature.\n", ">\n", "> Note that this does not work inside a script file. A value appearing on a line by itself in a script file will not do anything."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Floating-Point Numbers\n", "\n", "The float type in Python designates a floating-point number. `float` values are specified with a decimal point. Optionally, the character `e` or `E` followed by a positive or negative integer may be appended to specify [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation):"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"text/plain": ["4.2"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["4.2"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/plain": ["float"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["type(4.2)"]}, {"cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [{"data": {"text/plain": ["4.0"]}, "execution_count": 73, "metadata": {}, "output_type": "execute_result"}], "source": ["4."]}, {"cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [{"data": {"text/plain": ["0.2"]}, "execution_count": 74, "metadata": {}, "output_type": "execute_result"}], "source": [".2"]}, {"cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [{"data": {"text/plain": ["4000000.0"]}, "execution_count": 75, "metadata": {}, "output_type": "execute_result"}], "source": [".4e7"]}, {"cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [{"data": {"text/plain": ["float"]}, "execution_count": 76, "metadata": {}, "output_type": "execute_result"}], "source": ["type(.4e7)"]}, {"cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [{"data": {"text/plain": ["0.00042"]}, "execution_count": 83, "metadata": {}, "output_type": "execute_result"}], "source": ["4.2e-4"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> Deep Dive: **Floating-Point Representation**\n", ">\n", "> The following is a bit more in-depth information on how Python represents floating-point numbers internally. You can readily use floating-point numbers in Python without understanding them to this level, so don\u2019t worry if this seems overly complicated. The information is presented here in case you are curious.\n", ">\n", "> Almost all platforms represent Python float values as 64-bit \u201cdouble-precision\u201d values, according to the [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754_revision) standard. In that case, the maximum value a floating-point number can have is approximately $1.8 \\times 10^{308}$. Python will indicate a number greater than that by the string inf:\n", ">\n", "> ```bash\n", ">>> 1.79e308\n", "1.79e+308\n", ">>> 1.8e308\n", "inf\n", "> ```\n", "> The closest a nonzero number can be to zero is approximately $5.0 \\times 10^{-324}$. Anything closer to zero than that is effectively zero:\n", "> \n", "> ```bash\n", ">>> 5e-324\n", "5e-324\n", ">>> 1e-325\n", "0.0\n", "> ```\n", "> Floating point numbers are represented internally as binary (base-2) fractions. Most decimal fractions cannot be represented exactly as binary fractions, so in most cases the internal representation of a floating-point number is an approximation of the actual value. In practice, the difference between the actual value and the represented value is very small and should not usually cause significant problems."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Further Reading:** For additional information on floating-point representation in Python and the potential pitfalls involved, see [Floating Point Arithmetic: Issues and Limitations](https://docs.python.org/3.6/tutorial/floatingpoint.html) in the Python documentation."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Complex Numbers\n", "\n", "Complex numbers are specified as `+j`. For example:"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": ["complex"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["2+3j"]}, {"cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [{"data": {"text/plain": ["complex"]}, "execution_count": 95, "metadata": {}, "output_type": "execute_result"}], "source": ["type(2+3j)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### FAQ\n", "\n", "1. What's the difference between floating point and an integer?\n", "\n", "An integer has no decimals in it, a floating point number can display digits past the decimal point.\n", "\n", "2. Why doesn't `0.1 + 0.2 - 0.3` equal `0.0` ?\n", "\n", "This has to do with floating point accuracy and computer's abilities to represent numbers in memory. For a full breakdown, check out: https://docs.python.org/2/tutorial/floatingpoint.html"]}, {"cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 103, "metadata": {}, "output_type": "execute_result"}], "source": ["# Why is this False? Refer to FAQ above.\n", "0.1 + 0.2 - 0.3 == 0.0"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Strings\n", "\n", "Strings are sequences of character data. The string type in Python is called `str`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["String literals may be delimited using either single or double quotes. All the characters between the opening delimiter and matching closing delimiter are part of the string:"]}, {"cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["I am a string.\n"]}], "source": ["print(\"I am a string.\")"]}, {"cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [{"data": {"text/plain": ["str"]}, "execution_count": 116, "metadata": {}, "output_type": "execute_result"}], "source": ["type(\"I am a string.\")"]}, {"cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["I am too.\n"]}], "source": ["print('I am too.')"]}, {"cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [{"data": {"text/plain": ["str"]}, "execution_count": 118, "metadata": {}, "output_type": "execute_result"}], "source": ["type('I am too.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A string in Python can contain as many characters as you wish. The only limit is your machine\u2019s memory resources. A string can also be empty:"]}, {"cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [{"data": {"text/plain": ["''"]}, "execution_count": 126, "metadata": {}, "output_type": "execute_result"}], "source": ["\"\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["What if you want to include a quote character as part of the string itself? Your first impulse might be to try something like this:"]}, {"cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print('This string contains a single quote (') character.')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["print('This string contains a single quote (') character.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["As you can see, that doesn\u2019t work so well. The string in this example opens with a single quote, so Python assumes the next single quote, the one in parentheses which was intended to be part of the string, is the closing delimiter. The final single quote is then a stray and causes the syntax error shown."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you want to include either type of quote character within the string, the simplest way is to delimit the string with the other type. If a string is to contain a single quote, delimit it with double quotes and vice versa:"]}, {"cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["This string contains a single quote (') character.\n"]}], "source": ["print(\"This string contains a single quote (') character.\")"]}, {"cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["This string contains a double quote (\") character.\n"]}], "source": ["print('This string contains a double quote (\") character.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Escape Sequences in Strings\n", "Sometimes, you want Python to interpret a character or sequence of characters within a string differently. This may occur in one of two ways:\n", "- You may want to suppress the special interpretation that certain characters are usually given within a string.\n", "- You may want to apply special interpretation to characters in a string which would normally be taken literally."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can accomplish this using a backslash (`\\`) character. A backslash character in a string indicates that one or more characters that follow it should be treated specially. (This is referred to as an escape sequence, because the backslash causes the subsequent character sequence to \u201cescape\u201d its usual meaning.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Let\u2019s see how this works."]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Suppressing Special Character Meaning\n"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You have already seen the problems you can come up against when you try to include quote characters in a string. If a string is delimited by single quotes, you can\u2019t directly specify a single quote character as part of the string because, for that string, the single quote has special meaning\u2014it terminates the string:"]}, {"cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print('This string contains a single quote (') character.')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["print('This string contains a single quote (') character.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Specifying a backslash in front of the quote character in a string \u201cescapes\u201d it and causes Python to suppress its usual special meaning. It is then interpreted simply as a literal single quote character:"]}, {"cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["This string contains a single quote (') character.\n"]}], "source": ["print('This string contains a single quote (\\') character.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The same works in a string delimited by double quotes as well:"]}, {"cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["This string contains a double quote (\") character.\n"]}], "source": ["print(\"This string contains a double quote (\\\") character.\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The following is a table of escape sequences which cause Python to suppress the usual special interpretation of a character in a string:\n", "\n", "|Escape Sequence | Usual Interpretation of Character(s) After Backslash| \u201cEscaped\u201d Interpretation |\n", "|:--|:--|:--|\n", "|`\\'` | Terminates string with single quote opening delimiter | Literal single quote (`'`) character|\n", "|`\\\"` | Terminates string with double quote opening delimiter | Literal double quote (`\"`) character|\n", "|`\\\\` | Introduces escape sequence | Literal backslash (`\\`) character | "]}, {"cell_type": "markdown", "metadata": {}, "source": ["Ordinarily, a newline character terminates line input. So pressing _Enter_ in the middle of a string will cause Python to think it is incomplete:"]}, {"cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "EOL while scanning string literal (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print('a\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n"]}], "source": ["print('a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To break up a string over more than one line, include a backslash before each newline, and the newlines will be ignored:"]}, {"cell_type": "code", "execution_count": 149, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["asldjflasdjflasdjflasdjflasdjflasjflasdjfl32972394723947asdjfalsjflsdfjlajfslasdfj\n"]}], "source": ["print('asldjflasdjfl\\\n", "asdjflasdjflasdjflas\\\n", "jflasdjfl329723947239\\\n", "47asdjfalsjflsdfjlajf\\\n", "slasdfj')"]}, {"cell_type": "code", "execution_count": 150, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["abc\n"]}], "source": ["print('a\\\n", "b\\\n", "c')"]}, {"cell_type": "code", "execution_count": 151, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["a very very very very very very very long string.\n"]}], "source": ["print('a very very very \\\n", "very very very \\\n", "very long string.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To include a literal backslash in a string, escape it with a backslash:"]}, {"cell_type": "code", "execution_count": 152, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\\bar\n"]}], "source": ["print('foo\\\\bar')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Applying Special Meaning to Characters\n", "\n", "Next, suppose you need to create a string that contains a tab character in it. Some text editors may allow you to insert a tab character directly into your code. But many programmers consider that poor practice, for several reasons:\n", "\n", "- The computer can distinguish between a tab character and a sequence of space characters, but you can\u2019t. To a human reading the code, tab and space characters are visually indistinguishable.\n", "- Some text editors are configured to automatically eliminate tab characters by expanding them to the appropriate number of spaces.\n", "- Some Python REPL environments will not insert tabs into code."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In Python (and almost all other common computer languages), a tab character can be specified by the escape sequence `\\t`:"]}, {"cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["fooo\tbar\n"]}], "source": ["print('fooo\\tbar')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The escape sequence `\\t` causes the `t` character to lose its usual meaning, that of a literal t. Instead, the combination is interpreted as a tab character."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here is a list of escape sequences that cause Python to apply special meaning instead of interpreting literally:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["|Escape Sequence | \u201cEscaped\u201d Interpretation |\n", "|:--|:--|\n", "|`\\a` |\tASCII Bell (BEL) character |\n", "|`\\b` |\tASCII Backspace (BS) character |\n", "|`\\f` |\tASCII Formfeed (FF) character |\n", "|`\\n` |\tASCII Linefeed (LF) character |\n", "|`\\N{}` |\tCharacter from Unicode database with given `` |\n", "|`\\r` |\tASCII Carriage Return (CR) character |\n", "|`\\t` |\tASCII Horizontal Tab (TAB) character |\n", "|`\\uxxxx` |\tUnicode character with 16-bit hex value `xxxx` |\n", "|`\\Uxxxxxxxx` |\tUnicode character with 32-bit hex value `xxxxxxxx` |\n", "|`\\v` |\tASCII Vertical Tab (VT) character |\n", "|`\\ooo` |\tCharacter with octal value ooo |\n", "|`\\xhh` |\tCharacter with hex value hh |"]}, {"cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["a\tb\n"]}], "source": ["print(\"a\\tb\")"]}, {"cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["aaa\n"]}], "source": ["print(\"a\\141\\x61\")"]}, {"cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["a\n", "b\n"]}], "source": ["print(\"a\\nb\")"]}, {"cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u2192 \u2192\n"]}], "source": ["print('\\u2192 \\N{rightwards arrow}')"]}, {"cell_type": "code", "execution_count": 128, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["3\n"]}], "source": ["print(\"\\u0033\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This type of escape sequence is typically used to insert characters that are not readily generated from the keyboard or are not easily readable or printable."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** See the [list of Unicode Characters](https://en.wikipedia.org/wiki/List_of_Unicode_characters)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Raw Strings\n", "\n", "A raw string literal is preceded by r or R, which specifies that escape sequences in the associated string are not translated. The backslash character is left in the string:"]}, {"cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "bar\n"]}], "source": ["print('foo\\nbar')"]}, {"cell_type": "code", "execution_count": 138, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\\nbar\n"]}], "source": ["print(r'foo\\nbar')"]}, {"cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\\bar\n"]}], "source": ["print('foo\\\\bar')"]}, {"cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\\\\bar\n"]}], "source": ["print(R'foo\\\\bar')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Triple-Quoted Strings\n", "\n", "There is yet another way of delimiting strings in Python. Triple-quoted strings are delimited by matching groups of three single quotes or three double quotes. Escape sequences still work in triple-quoted strings, but single quotes, double quotes, and newlines can be included without escaping them. This provides a convenient way to create a string with both single and double quotes in it:"]}, {"cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["This string has a single (') and a double (\") quote.\n"]}], "source": ["print('''This string has a single (') and a double (\") quote.''')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Because newlines can be included without escaping them, this also allows for multiline strings:"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["This is a\n", "string that spans\n", "across several lines\n", "\n"]}], "source": ["print(\"\"\"This is a\n", "string that spans\n", "across several lines\n", "\"\"\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Boolean Type, Boolean Context, and \u201cTruthiness\u201d"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python 3 provides a Boolean data type. Objects of Boolean type may have one of two values, True or False:"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/plain": ["bool"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["type(True)"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"text/plain": ["bool"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["type(False)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["As you will see in upcoming section, expressions in Python are often evaluated in Boolean context, meaning they are interpreted to represent truth or falsehood. A value that is true in Boolean context is sometimes said to be \u201ctruthy,\u201d and one that is false in Boolean context is said to be \u201cfalsy.\u201d (You may also see \u201cfalsy\u201d spelled \u201cfalsey.\u201d)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The \u201ctruthiness\u201d of an object of Boolean type is self-evident: Boolean objects that are equal to True are truthy (`True`), and those equal to False are falsy (`False`). But non-Boolean objects can be evaluated in Boolean context as well and determined to be true or false."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You will learn more about evaluation of objects in Boolean context when you encounter logical operators in the upcoming sections on operators and expressions in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Built-In Functions\n", "\n", "The Python interpreter supports many functions that are built-in: sixty-eight, as of Python 3.6. You will cover many of these in the following discussions, as they come up in context."]}, {"cell_type": "markdown", "metadata": {}, "source": ["For now, a brief overview follows, just to give a feel for what is available. See the [Python documentation on built-in functions](https://docs.python.org/3.6/library/functions.html) for more detail. Many of the following descriptions refer to topics and concepts that will be discussed in future tutorials."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Math\n", "\n", "|Function | Description |\n", "|:--|:--|\n", "|`abs()`\t| Returns absolute value of a number |\n", "|`divmod()`\t| Returns quotient and remainder of integer division |\n", "|`max()`\t| Returns the largest of the given arguments or items in an iterable |\n", "|`min()`\t| Returns the smallest of the given arguments or items in an iterable |\n", "|`pow()`\t| Raises a number to a power |\n", "|`round()`\t| Rounds a floating-point value |\n", "|`sum()`\t| Sums the items of an iterable |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Type Conversion\n", "\n", "| Function | Description |\n", "|:--|:--|\n", "|`ascii()` |\tReturns a string containing a printable representation of an object |\n", "|`bin()` |\tConverts an integer to a binary string |\n", "|`bool()` |\tConverts an argument to a Boolean value |\n", "|`chr()` |\tReturns string representation of character given by integer argument |\n", "|`complex()` |\tReturns a complex number constructed from arguments |\n", "|`float()` |\tReturns a floating-point object constructed from a number or string |\n", "|`hex()` |\tConverts an integer to a hexadecimal string |\n", "|`int()` |\tReturns an integer object constructed from a number or string |\n", "|`oct()` |\tConverts an integer to an octal string |\n", "|`ord()` |\tReturns integer representation of a character |\n", "|`repr()` |\tReturns a string containing a printable representation of an object |\n", "|`str()` |\tReturns a string version of an object |\n", "|`type()` |\tReturns the type of an object or creates a new type object |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Iterables and Iterators\n", "|Function | Description|\n", "|:--|:--|\n", "|`all()`| Returns True if all elements of an iterable are true|\n", "|`any()`| Returns True if any elements of an iterable are true|\n", "|`enumerate()`| Returns a list of tuples containing indices and values from an iterable|\n", "|`filter()`| Filters elements from an iterable|\n", "|`iter()`| Returns an iterator object|\n", "|`len()`| Returns the length of an object|\n", "|`map()`| Applies a function to every item of an iterable|\n", "|`next()`| Retrieves the next item from an iterator|\n", "|`range()`| Generates a range of integer values|\n", "|`reversed()`| Returns a reverse iterator|\n", "|`slice()`| Returns a slice object|\n", "|`sorted()`| Returns a sorted list from an iterable|\n", "|`zip()`| Creates an iterator that aggregates elements from iterables|"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Composite Data Type\n", "|Function | Description|\n", "|:--|:--|\n", "| `bytearray()` | \tCreates and returns an object of the bytearray class |\n", "| `bytes()` | \tCreates and returns a bytes object (similar to bytearray, but immutable) |\n", "| `dict()` | \tCreates a dict object |\n", "| `frozenset()` | \tCreates a frozenset object |\n", "| `list()` | \tCreates a list object |\n", "| `object()` | \tCreates a new featureless object |\n", "| `set()` | \tCreates a set object |\n", "| `tuple()` | \tCreates a tuple object |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Classes, Attributes, and Inheritance\n", "|Function | Description|\n", "|:--|:--|\n", "| `classmethod()` |\tReturns a class method for a function |\n", "| `delattr()` |\tDeletes an attribute from an object |\n", "| `getattr()` |\tReturns the value of a named attribute of an object |\n", "| `hasattr()` |\tReturns True if an object has a given attribute |\n", "| `isinstance()` |\tDetermines whether an object is an instance of a given class |\n", "| `issubclass()` |\tDetermines whether a class is a subclass of a given class |\n", "| `property()` |\tReturns a property value of a class |\n", "| `setattr()` |\tSets the value of a named attribute of an object |\n", "| `super()` |\tReturns a proxy object that delegates method calls to a parent or sibling class |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Input/Output\n", "|Function | Description|\n", "|:--|:--|\n", "|`format()` |\tConverts a value to a formatted representation |\n", "|`input()` |\tReads input from the console |\n", "|`open()` |\tOpens a file and returns a file object |\n", "|`print()` |\tPrints to a text stream or the console |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Variables, References, and Scope\n", "|Function | Description|\n", "|:--|:--|\n", "|`dir()` | Returns a list of names in current local scope or a list of object attributes |\n", "|`globals()` | Returns a dictionary representing the current global symbol table |\n", "|`id()` | Returns the identity of an object |\n", "|`locals()` | Updates and returns a dictionary representing current local symbol table |\n", "|`vars()` | Returns __dict__ attribute for a module, class, or object |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Miscellaneous\n", "|Function | Description|\n", "|:--|:--|\n", "|`callable()` | Returns True if object appears callable |\n", "|`compile()` | Compiles source into a code or AST object |\n", "|`eval()` | Evaluates a Python expression |\n", "|`exec()` | Implements dynamic execution of Python code |\n", "|`hash()` | Returns the hash value of an object |\n", "|`help()` | Invokes the built-in help system |\n", "|`memoryview()` | Returns a memory view object |\n", "|`staticmethod()` | Returns a static method for a function |\n", "|`__import__()` | Invoked by the import statement |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "In this section, you learned about the built-in data types and functions Python provides.\n", "\n", "The examples given so far have all manipulated and displayed only constant values. In most programs, you are usually going to want to create objects that change in value as the program executes.\n", "\n", "Head to the next section to learn about Python variables."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/05 Variables.ipynb b/python/01. Basics/05 Variables.ipynb index c3e999b..1640411 100755 --- a/python/01. Basics/05 Variables.ipynb +++ b/python/01. Basics/05 Variables.ipynb @@ -1,1122 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "a55f4b8f", - "metadata": {}, - "source": [ - "# Variables in Python\n", - "\n", - "In the previous tutorial on Basic Data Types in Python, you saw how values of various Python data types can be created. But so far, all the values shown have been literal or constant values:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "73ada819", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5.3\n" - ] - } - ], - "source": [ - "print(5.3)" - ] - }, - { - "cell_type": "markdown", - "id": "a369bcd2", - "metadata": {}, - "source": [ - "If you’re writing more complex code, your program will need data that can change as program execution proceeds." - ] - }, - { - "cell_type": "markdown", - "id": "90e3c3d7", - "metadata": {}, - "source": [ - "## Variable Assignment\n", - "\n", - "Think of a variable as a name attached to a particular object. In Python, variables need not be declared or defined in advance, as is the case in many other programming languages. To create a variable, you just assign it a value and then start using it. Assignment is done with a single equals sign (`=`):" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b6f94fff", - "metadata": {}, - "outputs": [], - "source": [ - "n = 300" - ] - }, - { - "cell_type": "markdown", - "id": "e4f4f1fa", - "metadata": {}, - "source": [ - "This is read or interpreted as “n is assigned the value 300.” Once this is done, n can be used in a statement or expression, and its value will be substituted:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "659a5389", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "300\n" - ] - } - ], - "source": [ - "print(n)" - ] - }, - { - "cell_type": "markdown", - "id": "5f17dad1", - "metadata": {}, - "source": [ - "Just as a literal value can be displayed directly from the interpreter prompt in a REPL session without the need for `print()`, so can a variable:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "2a6a7f6d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "300" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "n" - ] - }, - { - "cell_type": "markdown", - "id": "9d6c6a97", - "metadata": {}, - "source": [ - "Later, if you change the value of `n` and use it again, the new value will be substituted instead:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6bd9d37e", - "metadata": {}, - "outputs": [], - "source": [ - "n = 1000" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "1aa1a866", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1000\n" - ] - } - ], - "source": [ - "print(n)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "4556ebb9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1000" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "n" - ] - }, - { - "cell_type": "markdown", - "id": "62a2e72c", - "metadata": {}, - "source": [ - "Python also allows chained assignment, which makes it possible to assign the same value to several variables simultaneously:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "9bc7a297", - "metadata": {}, - "outputs": [], - "source": [ - "a = b = c = 300" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "410b6037", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "300 300 300\n" - ] - } - ], - "source": [ - "print(a, b, c)" - ] - }, - { - "cell_type": "markdown", - "id": "e502bf9e", - "metadata": {}, - "source": [ - "The chained assignment above assigns 300 to the variables `a`, `b`, and `c` simultaneously." - ] - }, - { - "cell_type": "markdown", - "id": "1b58f80f", - "metadata": {}, - "source": [ - "## Variable Types in Python\n", - "\n", - "In many programming languages, variables are statically typed. That means a variable is initially declared to have a specific data type, and any value assigned to it during its lifetime must always have that type." - ] - }, - { - "cell_type": "markdown", - "id": "ef366d10", - "metadata": {}, - "source": [ - "Variables in Python are not subject to this restriction. In Python, a variable may be assigned a value of one type and then later re-assigned a value of a different type:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "62406cb7", - "metadata": {}, - "outputs": [], - "source": [ - "var = 23.5" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "98a95bde", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "float" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(var)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "f60605cf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "23.5\n" - ] - } - ], - "source": [ - "print(var)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "0fa521ba", - "metadata": {}, - "outputs": [], - "source": [ - "var = \"Now I'm a string\"" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "f3e7bb1e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Now I'm a string\n" - ] - } - ], - "source": [ - "print(var)" - ] - }, - { - "cell_type": "markdown", - "id": "62f69cdc", - "metadata": {}, - "source": [ - "## Object References\n", - "\n", - "What is actually happening when you make a variable assignment? This is an important question in Python, because the answer differs somewhat from what you’d find in many other programming languages." - ] - }, - { - "cell_type": "markdown", - "id": "685bda63", - "metadata": {}, - "source": [ - "Python is a highly [object-oriented language](https://realpython.com/python3-object-oriented-programming/). In fact, virtually every item of data in a Python program is an object of a specific type or class. (This point will be reiterated many times over the course of these tutorials.)" - ] - }, - { - "cell_type": "markdown", - "id": "59dca951", - "metadata": {}, - "source": [ - "Consider this code:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "c4762544", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "300\n" - ] - } - ], - "source": [ - "print(300)" - ] - }, - { - "cell_type": "markdown", - "id": "728f46fa", - "metadata": {}, - "source": [ - "When presented with the statement `print(300)`, the interpreter does the following:\n", - "\n", - "- Creates an integer object\n", - "- Gives it the value `300`\n", - "- Displays it to the console" - ] - }, - { - "cell_type": "markdown", - "id": "16e1ea59", - "metadata": {}, - "source": [ - "You can see that an integer object is created using the built-in `type()` function:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "c707a7dd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(300)" - ] - }, - { - "cell_type": "markdown", - "id": "f13f3e7f", - "metadata": {}, - "source": [ - "A Python variable is a symbolic name that is a reference or [pointer](https://realpython.com/pointers-in-python/) to an object. Once an object is assigned to a variable, you can refer to the object by that name. But the data itself is still contained within the object." - ] - }, - { - "cell_type": "markdown", - "id": "ada11109", - "metadata": {}, - "source": [ - "For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "0a722e9e", - "metadata": {}, - "outputs": [], - "source": [ - "n = 300" - ] - }, - { - "cell_type": "markdown", - "id": "b8ca1dee", - "metadata": {}, - "source": [ - "This assignment creates an integer object with the value `300` and assigns the variable `n` to point to that object." - ] - }, - { - "cell_type": "markdown", - "id": "95705a19", - "metadata": {}, - "source": [ - "\"int-pointer\"" - ] - }, - { - "cell_type": "markdown", - "id": "22951859", - "metadata": {}, - "source": [ - "The following code verifies that `n` points to an integer object:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "46ec7241", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(n)" - ] - }, - { - "cell_type": "markdown", - "id": "c7cda3d9", - "metadata": {}, - "source": [ - "Now consider the following statement:" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "1a189f08", - "metadata": {}, - "outputs": [], - "source": [ - "m = n" - ] - }, - { - "cell_type": "markdown", - "id": "027e3b78", - "metadata": {}, - "source": [ - "What happens when it is executed? Python does not create another object. It simply creates a new symbolic name or reference, `m`, which points to the same object that `n` points to." - ] - }, - { - "cell_type": "markdown", - "id": "31b5337d", - "metadata": {}, - "source": [ - "\"int-pointer\"" - ] - }, - { - "cell_type": "markdown", - "id": "9a115aed", - "metadata": {}, - "source": [ - "Next, suppose you do this:" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "a71ed9aa", - "metadata": {}, - "outputs": [], - "source": [ - "m = 400" - ] - }, - { - "cell_type": "markdown", - "id": "3e709f8a", - "metadata": {}, - "source": [ - "Now Python creates a new integer object with the value 400, and m becomes a reference to it." - ] - }, - { - "cell_type": "markdown", - "id": "ae298100", - "metadata": {}, - "source": [ - "\"int-pointer-m-n.png\"" - ] - }, - { - "cell_type": "markdown", - "id": "4c76d609", - "metadata": {}, - "source": [ - "Lastly, suppose this statement is executed next:" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "id": "6d83f4dc", - "metadata": {}, - "outputs": [], - "source": [ - "n = \"foo\"" - ] - }, - { - "cell_type": "markdown", - "id": "84361b93", - "metadata": {}, - "source": [ - "Now Python creates a string object with the value `\"foo\"` and makes `n` reference that." - ] - }, - { - "cell_type": "markdown", - "id": "a2fae845", - "metadata": {}, - "source": [ - "\"int-string-pointer.png\"" - ] - }, - { - "cell_type": "markdown", - "id": "3b740cee", - "metadata": {}, - "source": [ - "There is no longer any reference to the integer object 300. It is orphaned, and there is no way to access it." - ] - }, - { - "cell_type": "markdown", - "id": "f0fc675b", - "metadata": {}, - "source": [ - "Tutorials in this series will occasionally refer to the lifetime of an object. An object’s life begins when it is created, at which time at least one reference to it is created. During an object’s lifetime, additional references to it may be created, as you saw above, and references to it may be deleted as well. An object stays alive, as it were, so long as there is at least one reference to it." - ] - }, - { - "cell_type": "markdown", - "id": "86c07d02", - "metadata": {}, - "source": [ - "When the number of references to an object drops to zero, it is no longer accessible. At that point, its lifetime is over. Python will eventually notice that it is inaccessible and reclaim the allocated memory so it can be used for something else. In computer lingo, this process is referred to as [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29)." - ] - }, - { - "cell_type": "markdown", - "id": "d9cc212c", - "metadata": {}, - "source": [ - "## Object Identity\n", - "\n", - "In Python, every object that is created is given a number that uniquely identifies it. It is guaranteed that no two objects will have the same identifier during any period in which their lifetimes overlap. Once an object’s reference count drops to zero and it is garbage collected, as happened to the `300` object above, then its identifying number becomes available and may be used again." - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "e02aa413", - "metadata": {}, - "outputs": [], - "source": [ - "n = 300" - ] - }, - { - "cell_type": "markdown", - "id": "efe835b7", - "metadata": {}, - "source": [ - "The built-in Python function `id()` returns an object’s integer identifier. Using the `id()` function, you can verify that two variables indeed point to the same object:" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "aee3dbe1", - "metadata": {}, - "outputs": [], - "source": [ - "n = 300\n", - "m = n" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "c1d721b9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "139989024260592" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(n)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "f5457fa1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "139989024260592" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(m)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "dad48b6d", - "metadata": {}, - "outputs": [], - "source": [ - "m = 400" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "467b9feb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "139989024261008" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(m)" - ] - }, - { - "cell_type": "markdown", - "id": "182c51cd", - "metadata": {}, - "source": [ - "After the assignment `m = n`, m and n both point to the same object, confirmed by the fact that `id(m)` and `id(n)` return the same number. Once `m` is reassigned to `400`, `m` and `n` point to different objects with different identities." - ] - }, - { - "cell_type": "markdown", - "id": "4beb1faa", - "metadata": {}, - "source": [ - "> **Deep Dive: Caching Small Integer Values**\n", - ">\n", - "> From what you now know about variable assignment and object references in Python, the following probably won’t surprise you:\n", - ">\n", - ">```bash\n", - ">>> m = 300\n", - ">>> n = 300\n", - ">>> id(m)\n", - "60062304\n", - ">>> id(n)\n", - "60062896\n", - "> ```\n", - "> With the statement m = 300, Python creates an integer object with the value 300 and sets m as a reference to it. n is then similarly assigned to an integer object with value 300—but not the same object. Thus, they have different identities, which you can verify from the values returned by id().\n", - ">\n", - ">But consider this:\n", - ">\n", - ">```bash\n", - ">>> m = 30\n", - ">>> n = 30\n", - ">>> id(m)\n", - "1405569120\n", - ">>> id(n)\n", - "1405569120\n", - ">```\n", - ">\n", - "> Here, m and n are separately assigned to integer objects having value 30. But in this case, id(m) and id(n) are identical!\n", - "> \n", - "> For purposes of optimization, the interpreter creates objects for the integers in the range `[-5, 256]` at startup, and then reuses them during program execution. Thus, when you assign separate variables to an integer value in this range, they will actually reference the same object." - ] - }, - { - "cell_type": "markdown", - "id": "554ec3b2", - "metadata": {}, - "source": [ - "## Variable Names\n", - "\n", - "The examples you have seen so far have used short, terse variable names like `m` and `n`. But variable names can be more verbose. In fact, it is usually beneficial if they are because it makes the purpose of the variable more evident at first glance." - ] - }, - { - "cell_type": "markdown", - "id": "e82b25ba", - "metadata": {}, - "source": [ - "Officially, variable names in Python can be any length and can consist of uppercase and lowercase letters (`A-Z, a-z`), digits (`0-9`), and the underscore character (`_`). An additional restriction is that, although a variable name can contain digits, the first character of a variable name cannot be a digit." - ] - }, - { - "cell_type": "markdown", - "id": "0613da94", - "metadata": {}, - "source": [ - "For example, all of the following are valid variable names:" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "id": "71ff48d3", - "metadata": {}, - "outputs": [], - "source": [ - "name = \"Bob\"\n", - "Age = 54\n", - "has_W2 = True" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "id": "9262196a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bob 54 True\n" - ] - } - ], - "source": [ - "print(name, Age, has_W2)" - ] - }, - { - "cell_type": "markdown", - "id": "b6186f85", - "metadata": {}, - "source": [ - "But this one is not, because a variable name can’t begin with a digit:" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "b8f5a16d", - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid token (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 1099_filed = False\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid token\n" - ] - } - ], - "source": [ - "1099_filed = False" - ] - }, - { - "cell_type": "markdown", - "id": "357c83fe", - "metadata": {}, - "source": [ - "Note that case is significant. Lowercase and uppercase letters are not the same. Use of the underscore character is significant as well. Each of the following defines a different variable:" - ] - }, - { - "cell_type": "code", - "execution_count": 132, - "id": "30bd1c5e", - "metadata": {}, - "outputs": [], - "source": [ - "age = 1\n", - "Age = 2\n", - "aGe = 3\n", - "AGE = 4\n", - "a_g_e = 5\n", - "_age = 6\n", - "age_ = 7\n", - "_AGE_ = 8" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "id": "73d8b415", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 2 3 4 5 6 7 8\n" - ] - } - ], - "source": [ - "print(age, Age, aGe, AGE, a_g_e, _age, age_, _AGE_)" - ] - }, - { - "cell_type": "markdown", - "id": "5705d917", - "metadata": {}, - "source": [ - "There is nothing stopping you from creating two different variables in the same program called `age` and `Age`, or for that matter `agE`. But it is probably ill-advised. It would certainly be likely to confuse anyone trying to read your code, and even you yourself, after you’d been away from it awhile." - ] - }, - { - "cell_type": "markdown", - "id": "75073119", - "metadata": {}, - "source": [ - "It is worthwhile to give a variable a name that is descriptive enough to make clear what it is being used for. For example, suppose you are tallying the number of people who have graduated college. You could conceivably choose any of the following:" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "0410fffa", - "metadata": {}, - "outputs": [], - "source": [ - "numberofcollegegraduates = 2500\n", - "NUMBEROFCOLLEGEGRADUATES = 2500\n", - "numberOfCollegeGraduates = 2500\n", - "NumberOfCollegeGraduates = 2500\n", - "number_of_college_graduates = 2500" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "e5ccd23e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2500 2500 2500 2500 2500\n" - ] - } - ], - "source": [ - "print(numberofcollegegraduates, NUMBEROFCOLLEGEGRADUATES,\n", - "numberOfCollegeGraduates, NumberOfCollegeGraduates,\n", - "number_of_college_graduates)" - ] - }, - { - "cell_type": "markdown", - "id": "c15edc69", - "metadata": {}, - "source": [ - "All of them are probably better choices than n, or ncg, or the like. At least you can tell from the name what the value of the variable is supposed to represent." - ] - }, - { - "cell_type": "markdown", - "id": "c088f09d", - "metadata": {}, - "source": [ - "On the other hand, they aren’t all necessarily equally legible. As with many things, it is a matter of personal preference, but most people would find the first two examples, where the letters are all shoved together, to be harder to read, particularly the one in all capital letters. The most commonly used methods of constructing a multi-word variable name are the last three examples:\n", - "\n", - "- **Camel Case:** Second and subsequent words are capitalized, to make word boundaries easier to see. (Presumably, it struck someone at some point that the capital letters strewn throughout the variable name vaguely resemble camel humps.)\n", - " - Example: `numberOfCollegeGraduates`\n", - "- **Pascal Case:** Identical to Camel Case, except the first word is also capitalized.\n", - " - Example: `NumberOfCollegeGraduates`\n", - "- **Snake Case:** Words are separated by underscores.\n", - " - Example: `number_of_college_graduates`\n", - " " - ] - }, - { - "cell_type": "markdown", - "id": "7c3741c2", - "metadata": {}, - "source": [ - "Programmers debate hotly, with surprising fervor, which of these is preferable. Decent arguments can be made for all of them. Use whichever of the three is most visually appealing to you. Pick one and use it consistently." - ] - }, - { - "cell_type": "markdown", - "id": "b23e6fa7", - "metadata": {}, - "source": [ - "You will see later that variables aren’t the only things that can be given names. You can also name functions, classes, modules, and so on. The rules that apply to variable names also apply to identifiers, the more general term for names given to program objects." - ] - }, - { - "cell_type": "markdown", - "id": "5ef84fed", - "metadata": {}, - "source": [ - "The [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/), also known as [PEP 8](https://www.python.org/dev/peps/pep-0008/#naming-conventions), contains Naming Conventions that list suggested standards for names of different object types. PEP 8 includes the following recommendations:\n", - "\n", - "- **Snake Case** should be used for functions and variable names.\n", - "- **Pascal Case** should be used for class names. (PEP 8 refers to this as the “CapWords” convention.)" - ] - }, - { - "cell_type": "markdown", - "id": "2e62149e", - "metadata": {}, - "source": [ - "## Reserved Words (Keywords)\n", - "There is one more restriction on identifier names. The Python language reserves a small set of keywords that designate special language functionality. No object can have the same name as a reserved word." - ] - }, - { - "cell_type": "markdown", - "id": "7fc64770", - "metadata": {}, - "source": [ - "In Python 3.6, there are 33 reserved keywords:" - ] - }, - { - "cell_type": "markdown", - "id": "e27da392", - "metadata": {}, - "source": [ - "| Python Keywords| | | |\n", - "|:--|:--|:--|:--|\n", - "|`False`|`def`|`if`|`raise`|\n", - "|`None`|`del`|`import`|`return`|\n", - "|`True`|`elif`|`in`|`try`|\n", - "|`and`|`else`|`is`|`while`|\n", - "|`as`|`except`|`lambda`|`with`|\n", - "|`assert`|`finally`|`nonlocal`|`yield`|\n", - "|`break`|`for`|`not`|\n", - "|`class`|`from`|`or`|\n", - "|`continue`|`global`|`pass`|" - ] - }, - { - "cell_type": "markdown", - "id": "4c47d2ef", - "metadata": {}, - "source": [ - "You can see this list any time by typing `help(\"keywords\")` to the Python interpreter. Reserved words are case-sensitive and must be used exactly as shown. They are all entirely lowercase, except for `False`, `None`, and `True`." - ] - }, - { - "cell_type": "code", - "execution_count": 140, - "id": "f2512ced", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Here is a list of the Python keywords. Enter any keyword to get more help.\n", - "\n", - "False class from or\n", - "None continue global pass\n", - "True def if raise\n", - "and del import return\n", - "as elif in try\n", - "assert else is while\n", - "async except lambda with\n", - "await finally nonlocal yield\n", - "break for not \n", - "\n" - ] - } - ], - "source": [ - "help('keywords')" - ] - }, - { - "cell_type": "markdown", - "id": "aee81202", - "metadata": {}, - "source": [ - "Trying to create a variable with the same name as any reserved word results in an error:" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "id": "bef74b45", - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m for = 3\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "for = 3" - ] - }, - { - "cell_type": "markdown", - "id": "273d69e2", - "metadata": {}, - "source": [ - "## Conclusion\n", - "\n", - "This section covered the basics of Python **variables**, including object references and identity, and naming of Python identifiers." - ] - }, - { - "cell_type": "markdown", - "id": "e5278d8f", - "metadata": {}, - "source": [ - "You now have a good understanding of some of Python’s data types and know how to create variables that reference objects of those types." - ] - }, - { - "cell_type": "markdown", - "id": "05f507d5", - "metadata": {}, - "source": [ - "Next, you will see how to combine data objects into **expressions** involving various **operations**." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "a55f4b8f", "metadata": {}, "source": ["# Variables in Python\n", "\n", "In the previous tutorial on Basic Data Types in Python, you saw how values of various Python data types can be created. But so far, all the values shown have been literal or constant values:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Variable Assignment](#variable_assignment)\n* [Variable Types in Python](#variable_types_in_python)\n* [Object References](#object_references)\n* [Object Identity](#object_identity)\n* [Variable Names](#variable_names)\n* [Reserved Words (Keywords)](#reserved_words_(keywords))\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "code", "execution_count": 1, "id": "73ada819", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["5.3\n"]}], "source": ["print(5.3)"]}, {"cell_type": "markdown", "id": "a369bcd2", "metadata": {}, "source": ["If you\u2019re writing more complex code, your program will need data that can change as program execution proceeds."]}, {"cell_type": "markdown", "id": "90e3c3d7", "metadata": {}, "source": ["", "\n", "## Variable Assignment\n", "\n", "Think of a variable as a name attached to a particular object. In Python, variables need not be declared or defined in advance, as is the case in many other programming languages. To create a variable, you just assign it a value and then start using it. Assignment is done with a single equals sign (`=`):"]}, {"cell_type": "code", "execution_count": 4, "id": "b6f94fff", "metadata": {}, "outputs": [], "source": ["n = 300"]}, {"cell_type": "markdown", "id": "e4f4f1fa", "metadata": {}, "source": ["This is read or interpreted as \u201cn is assigned the value 300.\u201d Once this is done, n can be used in a statement or expression, and its value will be substituted:"]}, {"cell_type": "code", "execution_count": 6, "id": "659a5389", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["300\n"]}], "source": ["print(n)"]}, {"cell_type": "markdown", "id": "5f17dad1", "metadata": {}, "source": ["Just as a literal value can be displayed directly from the interpreter prompt in a REPL session without the need for `print()`, so can a variable:"]}, {"cell_type": "code", "execution_count": 4, "id": "2a6a7f6d", "metadata": {}, "outputs": [{"data": {"text/plain": ["300"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["n"]}, {"cell_type": "markdown", "id": "9d6c6a97", "metadata": {}, "source": ["Later, if you change the value of `n` and use it again, the new value will be substituted instead:"]}, {"cell_type": "code", "execution_count": 5, "id": "6bd9d37e", "metadata": {}, "outputs": [], "source": ["n = 1000"]}, {"cell_type": "code", "execution_count": 6, "id": "1aa1a866", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1000\n"]}], "source": ["print(n)"]}, {"cell_type": "code", "execution_count": 7, "id": "4556ebb9", "metadata": {}, "outputs": [{"data": {"text/plain": ["1000"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["n"]}, {"cell_type": "markdown", "id": "62a2e72c", "metadata": {}, "source": ["Python also allows chained assignment, which makes it possible to assign the same value to several variables simultaneously:"]}, {"cell_type": "code", "execution_count": 15, "id": "9bc7a297", "metadata": {}, "outputs": [], "source": ["a = b = c = 300"]}, {"cell_type": "code", "execution_count": 16, "id": "410b6037", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["300 300 300\n"]}], "source": ["print(a, b, c)"]}, {"cell_type": "markdown", "id": "e502bf9e", "metadata": {}, "source": ["The chained assignment above assigns 300 to the variables `a`, `b`, and `c` simultaneously."]}, {"cell_type": "markdown", "id": "1b58f80f", "metadata": {}, "source": ["", "\n", "## Variable Types in Python\n", "\n", "In many programming languages, variables are statically typed. That means a variable is initially declared to have a specific data type, and any value assigned to it during its lifetime must always have that type."]}, {"cell_type": "markdown", "id": "ef366d10", "metadata": {}, "source": ["Variables in Python are not subject to this restriction. In Python, a variable may be assigned a value of one type and then later re-assigned a value of a different type:"]}, {"cell_type": "code", "execution_count": 17, "id": "62406cb7", "metadata": {}, "outputs": [], "source": ["var = 23.5"]}, {"cell_type": "code", "execution_count": 18, "id": "98a95bde", "metadata": {}, "outputs": [{"data": {"text/plain": ["float"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["type(var)"]}, {"cell_type": "code", "execution_count": 18, "id": "f60605cf", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["23.5\n"]}], "source": ["print(var)"]}, {"cell_type": "code", "execution_count": 19, "id": "0fa521ba", "metadata": {}, "outputs": [], "source": ["var = \"Now I'm a string\""]}, {"cell_type": "code", "execution_count": 20, "id": "f3e7bb1e", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Now I'm a string\n"]}], "source": ["print(var)"]}, {"cell_type": "markdown", "id": "62f69cdc", "metadata": {}, "source": ["", "\n", "## Object References\n", "\n", "What is actually happening when you make a variable assignment? This is an important question in Python, because the answer differs somewhat from what you\u2019d find in many other programming languages."]}, {"cell_type": "markdown", "id": "685bda63", "metadata": {}, "source": ["Python is a highly [object-oriented language](https://realpython.com/python3-object-oriented-programming/). In fact, virtually every item of data in a Python program is an object of a specific type or class. (This point will be reiterated many times over the course of these tutorials.)"]}, {"cell_type": "markdown", "id": "59dca951", "metadata": {}, "source": ["Consider this code:"]}, {"cell_type": "code", "execution_count": 5, "id": "c4762544", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["300\n"]}], "source": ["print(300)"]}, {"cell_type": "markdown", "id": "728f46fa", "metadata": {}, "source": ["When presented with the statement `print(300)`, the interpreter does the following:\n", "\n", "- Creates an integer object\n", "- Gives it the value `300`\n", "- Displays it to the console"]}, {"cell_type": "markdown", "id": "16e1ea59", "metadata": {}, "source": ["You can see that an integer object is created using the built-in `type()` function:"]}, {"cell_type": "code", "execution_count": 22, "id": "c707a7dd", "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["type(300)"]}, {"cell_type": "markdown", "id": "f13f3e7f", "metadata": {}, "source": ["A Python variable is a symbolic name that is a reference or [pointer](https://realpython.com/pointers-in-python/) to an object. Once an object is assigned to a variable, you can refer to the object by that name. But the data itself is still contained within the object."]}, {"cell_type": "markdown", "id": "ada11109", "metadata": {}, "source": ["For example:"]}, {"cell_type": "code", "execution_count": 40, "id": "0a722e9e", "metadata": {}, "outputs": [], "source": ["n = 300"]}, {"cell_type": "markdown", "id": "b8ca1dee", "metadata": {}, "source": ["This assignment creates an integer object with the value `300` and assigns the variable `n` to point to that object."]}, {"cell_type": "markdown", "id": "95705a19", "metadata": {}, "source": ["\"int-pointer\""]}, {"cell_type": "markdown", "id": "22951859", "metadata": {}, "source": ["The following code verifies that `n` points to an integer object:"]}, {"cell_type": "code", "execution_count": 23, "id": "46ec7241", "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["type(n)"]}, {"cell_type": "markdown", "id": "c7cda3d9", "metadata": {}, "source": ["Now consider the following statement:"]}, {"cell_type": "code", "execution_count": 26, "id": "1a189f08", "metadata": {}, "outputs": [], "source": ["m = n"]}, {"cell_type": "markdown", "id": "027e3b78", "metadata": {}, "source": ["What happens when it is executed? Python does not create another object. It simply creates a new symbolic name or reference, `m`, which points to the same object that `n` points to."]}, {"cell_type": "markdown", "id": "31b5337d", "metadata": {}, "source": ["\"int-pointer\""]}, {"cell_type": "markdown", "id": "9a115aed", "metadata": {}, "source": ["Next, suppose you do this:"]}, {"cell_type": "code", "execution_count": 27, "id": "a71ed9aa", "metadata": {}, "outputs": [], "source": ["m = 400"]}, {"cell_type": "markdown", "id": "3e709f8a", "metadata": {}, "source": ["Now Python creates a new integer object with the value 400, and m becomes a reference to it."]}, {"cell_type": "markdown", "id": "ae298100", "metadata": {}, "source": ["\"int-pointer-m-n.png\""]}, {"cell_type": "markdown", "id": "4c76d609", "metadata": {}, "source": ["Lastly, suppose this statement is executed next:"]}, {"cell_type": "code", "execution_count": 75, "id": "6d83f4dc", "metadata": {}, "outputs": [], "source": ["n = \"foo\""]}, {"cell_type": "markdown", "id": "84361b93", "metadata": {}, "source": ["Now Python creates a string object with the value `\"foo\"` and makes `n` reference that."]}, {"cell_type": "markdown", "id": "a2fae845", "metadata": {}, "source": ["\"int-string-pointer.png\""]}, {"cell_type": "markdown", "id": "3b740cee", "metadata": {}, "source": ["There is no longer any reference to the integer object 300. It is orphaned, and there is no way to access it."]}, {"cell_type": "markdown", "id": "f0fc675b", "metadata": {}, "source": ["Tutorials in this series will occasionally refer to the lifetime of an object. An object\u2019s life begins when it is created, at which time at least one reference to it is created. During an object\u2019s lifetime, additional references to it may be created, as you saw above, and references to it may be deleted as well. An object stays alive, as it were, so long as there is at least one reference to it."]}, {"cell_type": "markdown", "id": "86c07d02", "metadata": {}, "source": ["When the number of references to an object drops to zero, it is no longer accessible. At that point, its lifetime is over. Python will eventually notice that it is inaccessible and reclaim the allocated memory so it can be used for something else. In computer lingo, this process is referred to as [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29)."]}, {"cell_type": "markdown", "id": "d9cc212c", "metadata": {}, "source": ["", "\n", "## Object Identity\n", "\n", "In Python, every object that is created is given a number that uniquely identifies it. It is guaranteed that no two objects will have the same identifier during any period in which their lifetimes overlap. Once an object\u2019s reference count drops to zero and it is garbage collected, as happened to the `300` object above, then its identifying number becomes available and may be used again."]}, {"cell_type": "code", "execution_count": 1, "id": "e02aa413", "metadata": {}, "outputs": [], "source": ["n = 300"]}, {"cell_type": "markdown", "id": "efe835b7", "metadata": {}, "source": ["The built-in Python function `id()` returns an object\u2019s integer identifier. Using the `id()` function, you can verify that two variables indeed point to the same object:"]}, {"cell_type": "code", "execution_count": 2, "id": "aee3dbe1", "metadata": {}, "outputs": [], "source": ["n = 300\n", "m = n"]}, {"cell_type": "code", "execution_count": 5, "id": "c1d721b9", "metadata": {}, "outputs": [{"data": {"text/plain": ["140238739082320"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["id(n)"]}, {"cell_type": "code", "execution_count": 7, "id": "f5457fa1", "metadata": {}, "outputs": [{"data": {"text/plain": ["140238739082320"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["id(m)"]}, {"cell_type": "code", "execution_count": 9, "id": "297e9884-b867-4093-a89c-50d11c4b14b1", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["m is n"]}, {"cell_type": "code", "execution_count": 10, "id": "9e2c3a75-eb4e-451f-bb9c-ab9150f2ca17", "metadata": {}, "outputs": [], "source": ["m = 300"]}, {"cell_type": "code", "execution_count": 12, "id": "059d0653-b8ba-4ade-b362-184c5bdd7da0", "metadata": {}, "outputs": [{"data": {"text/plain": ["140238472208624"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["id(m)"]}, {"cell_type": "code", "execution_count": 30, "id": "dad48b6d", "metadata": {}, "outputs": [], "source": ["m = 400"]}, {"cell_type": "code", "execution_count": 31, "id": "467b9feb", "metadata": {}, "outputs": [{"data": {"text/plain": ["139989024261008"]}, "execution_count": 31, "metadata": {}, "output_type": "execute_result"}], "source": ["id(m)"]}, {"cell_type": "markdown", "id": "182c51cd", "metadata": {}, "source": ["After the assignment `m = n`, m and n both point to the same object, confirmed by the fact that `id(m)` and `id(n)` return the same number. Once `m` is reassigned to `400`, `m` and `n` point to different objects with different identities."]}, {"cell_type": "markdown", "id": "4beb1faa", "metadata": {}, "source": ["> **Deep Dive: Caching Small Integer Values**\n", ">\n", "> From what you now know about variable assignment and object references in Python, the following probably won\u2019t surprise you:\n", ">\n", ">```bash\n", ">>> m = 300\n", ">>> n = 300\n", ">>> id(m)\n", "60062304\n", ">>> id(n)\n", "60062896\n", "> ```\n", "> With the statement m = 300, Python creates an integer object with the value 300 and sets m as a reference to it. n is then similarly assigned to an integer object with value 300\u2014but not the same object. Thus, they have different identities, which you can verify from the values returned by id().\n", ">\n", ">But consider this:\n", ">\n", ">```bash\n", ">>> m = 30\n", ">>> n = 30\n", ">>> id(m)\n", "1405569120\n", ">>> id(n)\n", "1405569120\n", ">```\n", ">\n", "> Here, m and n are separately assigned to integer objects having value 30. But in this case, id(m) and id(n) are identical!\n", "> \n", "> For purposes of optimization, the interpreter creates objects for the integers in the range `[-5, 256]` at startup, and then reuses them during program execution. Thus, when you assign separate variables to an integer value in this range, they will actually reference the same object."]}, {"cell_type": "markdown", "id": "554ec3b2", "metadata": {}, "source": ["", "\n", "## Variable Names\n", "\n", "The examples you have seen so far have used short, terse variable names like `m` and `n`. But variable names can be more verbose. In fact, it is usually beneficial if they are because it makes the purpose of the variable more evident at first glance."]}, {"cell_type": "markdown", "id": "e82b25ba", "metadata": {}, "source": ["Officially, variable names in Python can be any length and can consist of uppercase and lowercase letters (`A-Z, a-z`), digits (`0-9`), and the underscore character (`_`). An additional restriction is that, although a variable name can contain digits, the first character of a variable name cannot be a digit."]}, {"cell_type": "markdown", "id": "0613da94", "metadata": {}, "source": ["For example, all of the following are valid variable names:"]}, {"cell_type": "code", "execution_count": 124, "id": "71ff48d3", "metadata": {}, "outputs": [], "source": ["name = \"Bob\"\n", "Age = 54\n", "has_W2 = True"]}, {"cell_type": "code", "execution_count": 125, "id": "9262196a", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Bob 54 True\n"]}], "source": ["print(name, Age, has_W2)"]}, {"cell_type": "markdown", "id": "b6186f85", "metadata": {}, "source": ["But this one is not, because a variable name can\u2019t begin with a digit:"]}, {"cell_type": "code", "execution_count": 64, "id": "b8f5a16d", "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid token (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 1099_filed = False\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid token\n"]}], "source": ["1099_filed = False"]}, {"cell_type": "markdown", "id": "357c83fe", "metadata": {}, "source": ["Note that case is significant. Lowercase and uppercase letters are not the same. Use of the underscore character is significant as well. Each of the following defines a different variable:"]}, {"cell_type": "code", "execution_count": 132, "id": "30bd1c5e", "metadata": {}, "outputs": [], "source": ["age = 1\n", "Age = 2\n", "aGe = 3\n", "AGE = 4\n", "a_g_e = 5\n", "_age = 6\n", "age_ = 7\n", "_AGE_ = 8"]}, {"cell_type": "code", "execution_count": 133, "id": "73d8b415", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1 2 3 4 5 6 7 8\n"]}], "source": ["print(age, Age, aGe, AGE, a_g_e, _age, age_, _AGE_)"]}, {"cell_type": "markdown", "id": "5705d917", "metadata": {}, "source": ["There is nothing stopping you from creating two different variables in the same program called `age` and `Age`, or for that matter `agE`. But it is probably ill-advised. It would certainly be likely to confuse anyone trying to read your code, and even you yourself, after you\u2019d been away from it awhile."]}, {"cell_type": "markdown", "id": "75073119", "metadata": {}, "source": ["It is worthwhile to give a variable a name that is descriptive enough to make clear what it is being used for. For example, suppose you are tallying the number of people who have graduated college. You could conceivably choose any of the following:"]}, {"cell_type": "code", "execution_count": 37, "id": "0410fffa", "metadata": {}, "outputs": [], "source": ["numberofcollegegraduates = 2500\n", "NUMBEROFCOLLEGEGRADUATES = 2500\n", "numberOfCollegeGraduates = 2500\n", "NumberOfCollegeGraduates = 2500\n", "number_of_college_graduates = 2500"]}, {"cell_type": "code", "execution_count": 38, "id": "e5ccd23e", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["2500 2500 2500 2500 2500\n"]}], "source": ["print(numberofcollegegraduates, NUMBEROFCOLLEGEGRADUATES,\n", "numberOfCollegeGraduates, NumberOfCollegeGraduates,\n", "number_of_college_graduates)"]}, {"cell_type": "markdown", "id": "c15edc69", "metadata": {}, "source": ["All of them are probably better choices than n, or ncg, or the like. At least you can tell from the name what the value of the variable is supposed to represent."]}, {"cell_type": "markdown", "id": "c088f09d", "metadata": {}, "source": ["On the other hand, they aren\u2019t all necessarily equally legible. As with many things, it is a matter of personal preference, but most people would find the first two examples, where the letters are all shoved together, to be harder to read, particularly the one in all capital letters. The most commonly used methods of constructing a multi-word variable name are the last three examples:\n", "\n", "- **Camel Case:** Second and subsequent words are capitalized, to make word boundaries easier to see. (Presumably, it struck someone at some point that the capital letters strewn throughout the variable name vaguely resemble camel humps.)\n", " - Example: `numberOfCollegeGraduates`\n", "- **Pascal Case:** Identical to Camel Case, except the first word is also capitalized.\n", " - Example: `NumberOfCollegeGraduates`\n", "- **Snake Case:** Words are separated by underscores.\n", " - Example: `number_of_college_graduates`\n", " "]}, {"cell_type": "markdown", "id": "7c3741c2", "metadata": {}, "source": ["Programmers debate hotly, with surprising fervor, which of these is preferable. Decent arguments can be made for all of them. Use whichever of the three is most visually appealing to you. Pick one and use it consistently."]}, {"cell_type": "markdown", "id": "b23e6fa7", "metadata": {}, "source": ["You will see later that variables aren\u2019t the only things that can be given names. You can also name functions, classes, modules, and so on. The rules that apply to variable names also apply to identifiers, the more general term for names given to program objects."]}, {"cell_type": "markdown", "id": "5ef84fed", "metadata": {}, "source": ["The [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/), also known as [PEP 8](https://www.python.org/dev/peps/pep-0008/#naming-conventions), contains Naming Conventions that list suggested standards for names of different object types. PEP 8 includes the following recommendations:\n", "\n", "- **Snake Case** should be used for functions and variable names.\n", "- **Pascal Case** should be used for class names. (PEP 8 refers to this as the \u201cCapWords\u201d convention.)"]}, {"cell_type": "markdown", "id": "2e62149e", "metadata": {}, "source": ["", "\n", "## Reserved Words (Keywords)\n", "There is one more restriction on identifier names. The Python language reserves a small set of keywords that designate special language functionality. No object can have the same name as a reserved word."]}, {"cell_type": "markdown", "id": "7fc64770", "metadata": {}, "source": ["In Python 3.6, there are 33 reserved keywords:"]}, {"cell_type": "markdown", "id": "e27da392", "metadata": {}, "source": ["| Python Keywords| | | |\n", "|:--|:--|:--|:--|\n", "|`False`|`def`|`if`|`raise`|\n", "|`None`|`del`|`import`|`return`|\n", "|`True`|`elif`|`in`|`try`|\n", "|`and`|`else`|`is`|`while`|\n", "|`as`|`except`|`lambda`|`with`|\n", "|`assert`|`finally`|`nonlocal`|`yield`|\n", "|`break`|`for`|`not`|\n", "|`class`|`from`|`or`|\n", "|`continue`|`global`|`pass`|"]}, {"cell_type": "markdown", "id": "4c47d2ef", "metadata": {}, "source": ["You can see this list any time by typing `help(\"keywords\")` to the Python interpreter. Reserved words are case-sensitive and must be used exactly as shown. They are all entirely lowercase, except for `False`, `None`, and `True`."]}, {"cell_type": "code", "execution_count": 140, "id": "f2512ced", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\n", "Here is a list of the Python keywords. Enter any keyword to get more help.\n", "\n", "False class from or\n", "None continue global pass\n", "True def if raise\n", "and del import return\n", "as elif in try\n", "assert else is while\n", "async except lambda with\n", "await finally nonlocal yield\n", "break for not \n", "\n"]}], "source": ["help('keywords')"]}, {"cell_type": "markdown", "id": "aee81202", "metadata": {}, "source": ["Trying to create a variable with the same name as any reserved word results in an error:"]}, {"cell_type": "code", "execution_count": 103, "id": "bef74b45", "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m for = 3\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["for = 3"]}, {"cell_type": "markdown", "id": "273d69e2", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "\n", "This section covered the basics of Python **variables**, including object references and identity, and naming of Python identifiers."]}, {"cell_type": "markdown", "id": "e5278d8f", "metadata": {}, "source": ["You now have a good understanding of some of Python\u2019s data types and know how to create variables that reference objects of those types."]}, {"cell_type": "markdown", "id": "05f507d5", "metadata": {}, "source": ["Next, you will see how to combine data objects into **expressions** involving various **operations**."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/python/01. Basics/06 Operators and Expressions.ipynb b/python/01. Basics/06 Operators and Expressions.ipynb index e89c745..2757cbf 100755 --- a/python/01. Basics/06 Operators and Expressions.ipynb +++ b/python/01. Basics/06 Operators and Expressions.ipynb @@ -1,1633 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f8651a61", - "metadata": {}, - "source": [ - "# Operators and Expressions\n", - "\n", - "In Python, operators are special symbols that designate that some sort of computation should be performed. The values that an operator acts on are called **operands**." - ] - }, - { - "cell_type": "markdown", - "id": "b78854e4", - "metadata": {}, - "source": [ - "Here is an example:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "5512030a", - "metadata": {}, - "outputs": [], - "source": [ - "a = 10\n", - "b = 20" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "f44b233c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "30" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a + b" - ] - }, - { - "cell_type": "markdown", - "id": "03565296", - "metadata": {}, - "source": [ - "In this case, the `+` operator adds the operands `a` and `b` together. An operand can be either a literal value or a variable that references an object:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e24a4145", - "metadata": {}, - "outputs": [], - "source": [ - "a = 10\n", - "b = 20" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "9078d73c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "25" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a + b - 5" - ] - }, - { - "cell_type": "markdown", - "id": "22b29bb5", - "metadata": {}, - "source": [ - "A sequence of operands and operators, like `a + b - 5`, is called an **expression**. Python supports many operators for combining data objects into expressions. These are explored below." - ] - }, - { - "cell_type": "markdown", - "id": "303a9ee7", - "metadata": {}, - "source": [ - "## Arithmetic Operators" - ] - }, - { - "cell_type": "markdown", - "id": "04837e1a", - "metadata": {}, - "source": [ - "The following table lists the arithmetic operators supported by Python:\n", - "\n", - "\n", - "|Operator | Example | Meaning | Result|\n", - "|:--|:--|:--|:--|\n", - "|`+` (unary) |\t`+a`\t| **Unary Positive** | `a` In other words, it doesn’t really do anything. It mostly exists for the sake of completeness, to complement Unary Negation.|\n", - "|`+` (binary) |\t`a + b`\t| **Addition** |\tSum of `a` and `b` |\n", - "|`-` (unary) |\t`-a`\t| **Unary Negation** |\tValue equal to `a` but opposite in sign |\n", - "|`-` (binary) |\t`a - b`\t| **Subtraction** | `b` subtracted from `a` |\n", - "|`*`|\t`a * b`\t| **Multiplication** | Product of `a` and `b` |\n", - "|`/`|\t`a / b`\t| **Division** | Quotient when `a` is divided by `b`. The result always has type float. |\n", - "|`%`|\t`a % b`\t| **Modulo** | Remainder when `a` is divided by `b` |\n", - "|`//`|\t`a // b`\t| **Floor Division** | (also called Integer Division)\tQuotient when `a` is divided by `b`, rounded to the next smallest whole number |\n", - "|`**`|\t`a ** b`\t| **Exponentiation** | `a` raised to the power of `b` |" - ] - }, - { - "cell_type": "markdown", - "id": "375a058e", - "metadata": {}, - "source": [ - "Here are some examples of these operators in use:" - ] - }, - { - "cell_type": "code", - "execution_count": 104, - "id": "a4de71c8", - "metadata": {}, - "outputs": [], - "source": [ - "a = 4\n", - "b = 3" - ] - }, - { - "cell_type": "code", - "execution_count": 105, - "id": "5f5d03cd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4" - ] - }, - "execution_count": 105, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "+a" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "65c205ce", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "-3" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "-b" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "9b0cbbd3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a + b" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "246ae037", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a - b" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "00f73585", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "12" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a * b" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "b6e7f296", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.3333333333333333" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a / b" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "7382b6dd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a % b" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "388d3e91", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "64" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a ** b" - ] - }, - { - "cell_type": "markdown", - "id": "83dbcf0b", - "metadata": {}, - "source": [ - "The result of standard division (`/`) is always a `float`, even if the dividend is evenly divisible by the divisor:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "624752ff", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2.0" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "10 / 5" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "e004f456", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "float" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(10 / 5)" - ] - }, - { - "cell_type": "markdown", - "id": "a173be58", - "metadata": {}, - "source": [ - "When the result of floor division (`//`) is positive, it is as though the fractional portion is truncated off, leaving only the integer portion. When the result is negative, the result is rounded down to the next smallest (greater negative) integer:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "b700d679", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2.5" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "10 / 4" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "0b6ca1e8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "10 // 4" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "c0f3863a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "-3" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "10 // -4" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "9a6f1503", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "-3" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "-10 // 4" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "d48fb428", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "-10 // -4" - ] - }, - { - "cell_type": "markdown", - "id": "2fef3c6c", - "metadata": {}, - "source": [ - "## Comparison Operators\n", - "\n", - "|Operator |\tExample |\tMeaning |\tResult |\n", - "|:--|:--|:--|:--|\n", - "|`==` |\t`a == b` |\t**Equal to** | `True` if the value of `a` is equal to the value of `b`. `False` otherwise |\n", - "|`!=` |\t`a != b` |\t**Not equal to** | `True` if `a` is not equal to `b`. `False` otherwise |\n", - "|`<` |\t`a < b` |\t**Less than** | `True` if `a` is less than `b`. `False` otherwise |\n", - "|`<=` |\t`a <= b` |\t**Less than or equal to** | `True` if `a` is less than or equal to `b`. `False` otherwise |\n", - "|`>` |\t`a > b` |\t**Greater than** | `True` if `a` is greater than `b`. `False` otherwise |\n", - "|`>=` |\t`a >= b` |\t**Greater than or equal to** | `True` if `a` is greater than or equal to `b`. `False` otherwise |" - ] - }, - { - "cell_type": "markdown", - "id": "fc3710b3", - "metadata": {}, - "source": [ - "Here are examples of the comparison operators in use:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "b3f2f9f3", - "metadata": {}, - "outputs": [], - "source": [ - "a = 10\n", - "b = 20" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "56dc7d50", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a == b" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "76a974d8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a != b" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "61605dab", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a <= b" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "891c5f7d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a >= b" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "1cb729fa", - "metadata": {}, - "outputs": [], - "source": [ - "a = 30\n", - "b = 30" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "ffd289cd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a == b" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "695a4c00", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a <= b" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "2047b30a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a >= b" - ] - }, - { - "cell_type": "markdown", - "id": "aa8f7c1f", - "metadata": {}, - "source": [ - "Comparison operators are typically used in Boolean contexts like conditional and loop statements to direct program flow, as you will see later." - ] - }, - { - "cell_type": "markdown", - "id": "737dd052", - "metadata": {}, - "source": [ - "### Equality Comparison on Floating-Point Values\n", - "\n", - "Recall from the earlier discussion of floating-point numbers that the value stored internally for a float object may not be precisely what you’d think it would be. For that reason, it is poor practice to compare floating-point values for exact equality. Consider this example:" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "f9a93596", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = 1.1 + 2.2\n", - "x == 3.3" - ] - }, - { - "cell_type": "markdown", - "id": "b228ea16", - "metadata": {}, - "source": [ - "Yikes! The internal representations of the addition operands are not exactly equal to `1.1` and `2.2`, so you cannot rely on x to compare exactly to `3.3`." - ] - }, - { - "cell_type": "markdown", - "id": "47dc1cee", - "metadata": {}, - "source": [ - "The preferred way to determine whether two floating-point values are “equal” is to compute whether they are close to one another, given some tolerance. Take a look at this example:" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "id": "7390ff8f", - "metadata": {}, - "outputs": [], - "source": [ - "tolerance = 0.00001" - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "id": "0fd7b119", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 128, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "abs(x - 3.3) < tolerance" - ] - }, - { - "cell_type": "markdown", - "id": "fb041d2e", - "metadata": {}, - "source": [ - "`abs()` returns absolute value. If the absolute value of the difference between the two numbers is less than the specified tolerance, they are close enough to one another to be considered equal." - ] - }, - { - "cell_type": "markdown", - "id": "497e4d2a", - "metadata": {}, - "source": [ - "## Logical Operators\n", - "\n", - "The logical operators `not`, `or`, `and` and modify and join together expressions evaluated in Boolean context to create more complex conditions." - ] - }, - { - "cell_type": "markdown", - "id": "cba77d31", - "metadata": {}, - "source": [ - "### Logical Expressions Involving Boolean Operands\n", - "\n", - "As you have seen, some objects and expressions in Python actually are of Boolean type. That is, they are equal to one of the Python objects `True` or `False`." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "aabf38a1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = 5\n", - "x < 10" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "4d2afeb9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "bool" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(x < 10)" - ] - }, - { - "cell_type": "markdown", - "id": "86fab03a", - "metadata": {}, - "source": [ - "|Operator |\tExample\t |Meaning |\n", - "|:--|:--|:--|\n", - "|`not` | `not x` | `True` if `x` is `False`. `False` if `x` is `True` (Logically reverses the sense of `x`) |\n", - "|`or` | `x or y` | `True` if either `x` or `y` is `True`. `False` otherwise. |\n", - "|`and` | `x and y` | `True` if both `x` and `y` are `True`. `False` otherwise. |" - ] - }, - { - "cell_type": "markdown", - "id": "4febd04c", - "metadata": {}, - "source": [ - "Take a look at how they work in practice below." - ] - }, - { - "cell_type": "code", - "execution_count": 137, - "id": "b41c32a6", - "metadata": {}, - "outputs": [], - "source": [ - "x = 5" - ] - }, - { - "cell_type": "code", - "execution_count": 138, - "id": "a1c405d3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 138, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "not x < 10" - ] - }, - { - "cell_type": "code", - "execution_count": 139, - "id": "704e8a42", - "metadata": {}, - "outputs": [], - "source": [ - "x = 5" - ] - }, - { - "cell_type": "code", - "execution_count": 140, - "id": "9f3f352a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 140, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x < 10 or x > 10" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "689e5edb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x < 10 and x > 10" - ] - }, - { - "cell_type": "markdown", - "id": "c2e4557d", - "metadata": {}, - "source": [ - "### Evaluation of Non-Boolean Values in Boolean Context\n", - "\n", - "Many objects and expressions are not equal to True or False. Nonetheless, they may still be evaluated in Boolean context and determined to be “truthy” or “falsy.”" - ] - }, - { - "cell_type": "markdown", - "id": "6681ab29", - "metadata": {}, - "source": [ - "So what is true and what isn’t? As a philosophical question, that is outside the scope of this tutorial!" - ] - }, - { - "cell_type": "markdown", - "id": "7c1bddeb", - "metadata": {}, - "source": [ - "But in Python, it is well-defined. All the following are considered false when evaluated in Boolean context:\n", - "- The Boolean value `False`\n", - "- Any value that is numerically zero (`0`, `0.0`, `0.0+0.0j`)\n", - "- An empty string\n", - "- An object of a built-in composite data type which is empty (see later section)\n", - "- The special value denoted by the Python keyword `None`" - ] - }, - { - "cell_type": "markdown", - "id": "ef2285d4", - "metadata": {}, - "source": [ - "Virtually any other object built into Python is regarded as `True`." - ] - }, - { - "cell_type": "markdown", - "id": "c3933c47", - "metadata": {}, - "source": [ - "You can determine the “truthiness” of an object or expression with the built-in `bool()` function. `bool()` returns `True` if its argument is truthy and `False` if it is falsy." - ] - }, - { - "cell_type": "markdown", - "id": "3950c626", - "metadata": {}, - "source": [ - "#### Numeric Value\n", - "- A zero value is false.\n", - "- A non-zero value is true." - ] - }, - { - "cell_type": "code", - "execution_count": 154, - "id": "e9050915", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False False False\n" - ] - } - ], - "source": [ - "print(bool(0), bool(0.0), bool(0.0+0j))" - ] - }, - { - "cell_type": "code", - "execution_count": 155, - "id": "96c8a566", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True True True\n" - ] - } - ], - "source": [ - "print(bool(-3), bool(3.14159), bool(1.0+1j))" - ] - }, - { - "cell_type": "markdown", - "id": "0c37818b", - "metadata": {}, - "source": [ - "#### String\n", - "- An empty string is false.\n", - "- A non-empty string is true." - ] - }, - { - "cell_type": "code", - "execution_count": 156, - "id": "8f27bdff", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False False False\n" - ] - } - ], - "source": [ - "print(bool(''), bool(\"\"), bool(\"\"\"\"\"\"))" - ] - }, - { - "cell_type": "code", - "execution_count": 157, - "id": "c348a752", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True True True\n" - ] - } - ], - "source": [ - "print(bool('foo'), bool(\" \"), bool(''' '''))" - ] - }, - { - "cell_type": "markdown", - "id": "0a36f504", - "metadata": {}, - "source": [ - "#### Built-In Composite Data Object\n", - "> Python provides built-in composite data types called `list`, `tuple`, `dict`, and `set` (and some more). These are “container” types that contain other objects. An object of one of these types is considered false if it is empty and true if it is non-empty.\n", - ">\n", - ">The examples below demonstrate this for the list type. (Lists are defined in Python with square brackets.)\n", - ">\n", - ">For more information on the `list`, `tuple`, `dict`, `set`, etc. types, see the upcoming sections." - ] - }, - { - "cell_type": "code", - "execution_count": 158, - "id": "d99a9d30", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "list" - ] - }, - "execution_count": 158, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type([])" - ] - }, - { - "cell_type": "code", - "execution_count": 159, - "id": "70bafc98", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 159, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bool([])" - ] - }, - { - "cell_type": "code", - "execution_count": 160, - "id": "1ba859a9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "list" - ] - }, - "execution_count": 160, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type([1, 2, 3])" - ] - }, - { - "cell_type": "code", - "execution_count": 161, - "id": "c27e0e0c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 161, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bool([1, 2, 3])" - ] - }, - { - "cell_type": "markdown", - "id": "b3317357", - "metadata": {}, - "source": [ - "#### The `None` Keyword\n", - "- `None` is always false:" - ] - }, - { - "cell_type": "code", - "execution_count": 162, - "id": "0eb097aa", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 162, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bool(None)" - ] - }, - { - "cell_type": "markdown", - "id": "b31651f2", - "metadata": {}, - "source": [ - "## Bitwise Operators\n", - "\n", - "Bitwise operators treat operands as sequences of binary digits and operate on them bit by bit. Bitwise operators will be addressed fully later." - ] - }, - { - "cell_type": "markdown", - "id": "ba596fec", - "metadata": {}, - "source": [ - "## Identity Operators\n", - "\n", - "Python provides two operators, `is` and `is not`, that determine whether the given operands have the same identity—that is, refer to the same object. This is not the same thing as equality, which means the two operands refer to objects that contain the same data but are not necessarily the same object." - ] - }, - { - "cell_type": "markdown", - "id": "70c352df", - "metadata": {}, - "source": [ - "Here is an example of two object that are equal but not identical:" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "9ed4cf85", - "metadata": {}, - "outputs": [], - "source": [ - "x = 1001\n", - "y = 1000 + 1" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "beae0879", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1001 1001\n" - ] - } - ], - "source": [ - "print(x, y)" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "19ba7b74", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x == y" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "58c101e2", - "metadata": {}, - "outputs": [], - "source": [ - "x is y" - ] - }, - { - "cell_type": "markdown", - "id": "e70e17e7", - "metadata": {}, - "source": [ - "Here, `x` and `y` both refer to objects whose value is `1001`. They are equal. But they do not reference the same object, as you can verify:" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "79b3bffa", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "140016350734768" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "116ea605", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "140016350734224" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(y)" - ] - }, - { - "cell_type": "markdown", - "id": "b3743e65", - "metadata": {}, - "source": [ - "`x` and `y` do not have the same identity, and `x` is `y` returns `False`." - ] - }, - { - "cell_type": "markdown", - "id": "7a85a8a4", - "metadata": {}, - "source": [ - "You saw previously that when you make an assignment like `x = y`, Python merely creates a second reference to the same object, and that you could confirm that fact with the `id()` function. You can also confirm it using the `is` operator:" - ] - }, - { - "cell_type": "code", - "execution_count": 112, - "id": "7248d4c3", - "metadata": {}, - "outputs": [], - "source": [ - "a = 'I am a string'\n", - "b = a" - ] - }, - { - "cell_type": "code", - "execution_count": 113, - "id": "eab98ef9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "140078194378544" - ] - }, - "execution_count": 113, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "id": "697bee23", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "140078194378544" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(b)" - ] - }, - { - "cell_type": "code", - "execution_count": 115, - "id": "c9e1462a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 115, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a is b" - ] - }, - { - "cell_type": "code", - "execution_count": 123, - "id": "53c450a3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 123, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a == b" - ] - }, - { - "cell_type": "markdown", - "id": "584a8306", - "metadata": {}, - "source": [ - "In this case, since `a` and `b` reference the same object, it stands to reason that `a` and `b` would be equal as well." - ] - }, - { - "cell_type": "markdown", - "id": "df20743f", - "metadata": {}, - "source": [ - "Unsurprisingly, the opposite of `is` is `is not`:" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "id": "f71d6191", - "metadata": {}, - "outputs": [], - "source": [ - "x = 10\n", - "y = 20" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "15356c11", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x is not y" - ] - }, - { - "cell_type": "markdown", - "id": "2a1251df", - "metadata": {}, - "source": [ - "## Augmented Assignment Operators\n", - "\n", - "You have seen that a single equal sign (`=`) is used to assign a value to a variable. It is, of course, perfectly viable for the value to the right of the assignment to be an expression containing other variables:" - ] - }, - { - "cell_type": "code", - "execution_count": 186, - "id": "70d83a70", - "metadata": {}, - "outputs": [], - "source": [ - "a = 10\n", - "b = 20\n", - "c = a * 5 + b" - ] - }, - { - "cell_type": "code", - "execution_count": 187, - "id": "1446ee97", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "70" - ] - }, - "execution_count": 187, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "c" - ] - }, - { - "cell_type": "markdown", - "id": "7d2b4c96", - "metadata": {}, - "source": [ - "In fact, the expression to the right of the assignment can include references to the variable that is being assigned to:" - ] - }, - { - "cell_type": "markdown", - "id": "29e02ba0", - "metadata": {}, - "source": [ - "Python supports a shorthand augmented assignment notation for these arithmetic and bitwise operators:\n", - "\n", - "|Arithmetic|Bitwise|\n", - "|:--|:--|\n", - "|`+`| `&` |\n", - "|`-`|`|`|\n", - "|`*`|`^`|\n", - "|`/`|`>>`|\n", - "|`%`|`<<`|\n", - "|`//`||\n", - "|`**`||" - ] - }, - { - "cell_type": "markdown", - "id": "608cd54a", - "metadata": {}, - "source": [ - "For these operators, the following are equivalent:\n", - "\n", - "```python\n", - "x = y\n", - "x = x y\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "81bb46ce", - "metadata": {}, - "source": [ - "Take a look at these examples:\n", - "\n", - "|Augmented Assignment || Standard Assignment |\n", - "|:--|:--|:--|\n", - "|`a += 5` | is equivalent to\t| `a = a + 5`|\n", - "|`a /= 10` | is equivalent to\t| `a = a / 10`|\n", - "|`a ^= b` | is equivalent to\t| `a = a ^ b`|" - ] - }, - { - "cell_type": "markdown", - "id": "47b56763", - "metadata": {}, - "source": [ - "## Conclusion\n", - "In this section, you learned about the diverse **operators** Python supports to combine objects into **expressions**." - ] - }, - { - "cell_type": "markdown", - "id": "30d6c1eb", - "metadata": {}, - "source": [ - "Most of the examples you have seen so far have involved only simple atomic data, but you saw a brief introduction to the **string** data type. The next tutorial will explore **string** objects in much more detail." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "f8651a61", "metadata": {}, "source": ["# Operators and Expressions\n", "\n", "In Python, operators are special symbols that designate that some sort of computation should be performed. The values that an operator acts on are called **operands**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Arithmetic Operators](#arithmetic_operators)\n* [Comparison Operators](#comparison_operators)\n * [Equality Comparison on Floating-Point Values](#equality_comparison_on_floating-point_values)\n* [Logical Operators](#logical_operators)\n * [Logical Expressions Involving Boolean Operands](#logical_expressions_involving_boolean_operands)\n * [Evaluation of Non-Boolean Values in Boolean Context](#evaluation_of_non-boolean_values_in_boolean_context)\n* [Bitwise Operators](#bitwise_operators)\n* [Identity Operators](#identity_operators)\n* [Augmented Assignment Operators](#augmented_assignment_operators)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "id": "b78854e4", "metadata": {}, "source": ["Here is an example:"]}, {"cell_type": "code", "execution_count": 2, "id": "5512030a", "metadata": {}, "outputs": [], "source": ["a = 10\n", "b = 20"]}, {"cell_type": "code", "execution_count": 3, "id": "f44b233c", "metadata": {}, "outputs": [{"data": {"text/plain": ["30"]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["a + b"]}, {"cell_type": "markdown", "id": "03565296", "metadata": {}, "source": ["In this case, the `+` operator adds the operands `a` and `b` together. An operand can be either a literal value or a variable that references an object:"]}, {"cell_type": "code", "execution_count": 4, "id": "e24a4145", "metadata": {}, "outputs": [], "source": ["a = 10\n", "b = 20"]}, {"cell_type": "code", "execution_count": 5, "id": "9078d73c", "metadata": {}, "outputs": [{"data": {"text/plain": ["25"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["a + b - 5"]}, {"cell_type": "markdown", "id": "22b29bb5", "metadata": {}, "source": ["A sequence of operands and operators, like `a + b - 5`, is called an **expression**. Python supports many operators for combining data objects into expressions. These are explored below."]}, {"cell_type": "markdown", "id": "303a9ee7", "metadata": {}, "source": ["", "\n", "## Arithmetic Operators"]}, {"cell_type": "markdown", "id": "04837e1a", "metadata": {}, "source": ["The following table lists the arithmetic operators supported by Python:\n", "\n", "\n", "|Operator | Example | Meaning | Result|\n", "|:--|:--|:--|:--|\n", "|`+` (unary) |\t`+a`\t| **Unary Positive** | `a` In other words, it doesn\u2019t really do anything. It mostly exists for the sake of completeness, to complement Unary Negation.|\n", "|`+` (binary) |\t`a + b`\t| **Addition** |\tSum of `a` and `b` |\n", "|`-` (unary) |\t`-a`\t| **Unary Negation** |\tValue equal to `a` but opposite in sign |\n", "|`-` (binary) |\t`a - b`\t| **Subtraction** | `b` subtracted from `a` |\n", "|`*`|\t`a * b`\t| **Multiplication** | Product of `a` and `b` |\n", "|`/`|\t`a / b`\t| **Division** | Quotient when `a` is divided by `b`. The result always has type float. |\n", "|`%`|\t`a % b`\t| **Modulo** | Remainder when `a` is divided by `b` |\n", "|`//`|\t`a // b`\t| **Floor Division** | (also called Integer Division)\tQuotient when `a` is divided by `b`, rounded to the next smallest whole number |\n", "|`**`|\t`a ** b`\t| **Exponentiation** | `a` raised to the power of `b` |"]}, {"cell_type": "markdown", "id": "375a058e", "metadata": {}, "source": ["Here are some examples of these operators in use:"]}, {"cell_type": "code", "execution_count": 104, "id": "a4de71c8", "metadata": {}, "outputs": [], "source": ["a = 4\n", "b = 3"]}, {"cell_type": "code", "execution_count": 105, "id": "5f5d03cd", "metadata": {}, "outputs": [{"data": {"text/plain": ["4"]}, "execution_count": 105, "metadata": {}, "output_type": "execute_result"}], "source": ["+a"]}, {"cell_type": "code", "execution_count": 8, "id": "65c205ce", "metadata": {}, "outputs": [{"data": {"text/plain": ["-3"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["-b"]}, {"cell_type": "code", "execution_count": 9, "id": "9b0cbbd3", "metadata": {}, "outputs": [{"data": {"text/plain": ["7"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["a + b"]}, {"cell_type": "code", "execution_count": 10, "id": "246ae037", "metadata": {}, "outputs": [{"data": {"text/plain": ["1"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["a - b"]}, {"cell_type": "code", "execution_count": 11, "id": "00f73585", "metadata": {}, "outputs": [{"data": {"text/plain": ["12"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["a * b"]}, {"cell_type": "code", "execution_count": 12, "id": "b6e7f296", "metadata": {}, "outputs": [{"data": {"text/plain": ["1.3333333333333333"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["a / b"]}, {"cell_type": "code", "execution_count": 13, "id": "7382b6dd", "metadata": {}, "outputs": [{"data": {"text/plain": ["1"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["a % b"]}, {"cell_type": "code", "execution_count": 14, "id": "388d3e91", "metadata": {}, "outputs": [{"data": {"text/plain": ["64"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["a ** b"]}, {"cell_type": "markdown", "id": "83dbcf0b", "metadata": {}, "source": ["The result of standard division (`/`) is always a `float`, even if the dividend is evenly divisible by the divisor:"]}, {"cell_type": "code", "execution_count": 15, "id": "624752ff", "metadata": {}, "outputs": [{"data": {"text/plain": ["2.0"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["10 / 5"]}, {"cell_type": "code", "execution_count": 16, "id": "e004f456", "metadata": {}, "outputs": [{"data": {"text/plain": ["float"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["type(10 / 5)"]}, {"cell_type": "markdown", "id": "a173be58", "metadata": {}, "source": ["When the result of floor division (`//`) is positive, it is as though the fractional portion is truncated off, leaving only the integer portion. When the result is negative, the result is rounded down to the next smallest (greater negative) integer:"]}, {"cell_type": "code", "execution_count": 17, "id": "b700d679", "metadata": {}, "outputs": [{"data": {"text/plain": ["2.5"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["10 / 4"]}, {"cell_type": "code", "execution_count": 18, "id": "0b6ca1e8", "metadata": {}, "outputs": [{"data": {"text/plain": ["2"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["10 // 4"]}, {"cell_type": "code", "execution_count": 19, "id": "c0f3863a", "metadata": {}, "outputs": [{"data": {"text/plain": ["-3"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["10 // -4"]}, {"cell_type": "code", "execution_count": 20, "id": "9a6f1503", "metadata": {}, "outputs": [{"data": {"text/plain": ["-3"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["-10 // 4"]}, {"cell_type": "code", "execution_count": 21, "id": "d48fb428", "metadata": {}, "outputs": [{"data": {"text/plain": ["2"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["-10 // -4"]}, {"cell_type": "markdown", "id": "2fef3c6c", "metadata": {}, "source": ["", "\n", "## Comparison Operators\n", "\n", "|Operator |\tExample |\tMeaning |\tResult |\n", "|:--|:--|:--|:--|\n", "|`==` |\t`a == b` |\t**Equal to** | `True` if the value of `a` is equal to the value of `b`. `False` otherwise |\n", "|`!=` |\t`a != b` |\t**Not equal to** | `True` if `a` is not equal to `b`. `False` otherwise |\n", "|`<` |\t`a < b` |\t**Less than** | `True` if `a` is less than `b`. `False` otherwise |\n", "|`<=` |\t`a <= b` |\t**Less than or equal to** | `True` if `a` is less than or equal to `b`. `False` otherwise |\n", "|`>` |\t`a > b` |\t**Greater than** | `True` if `a` is greater than `b`. `False` otherwise |\n", "|`>=` |\t`a >= b` |\t**Greater than or equal to** | `True` if `a` is greater than or equal to `b`. `False` otherwise |"]}, {"cell_type": "markdown", "id": "fc3710b3", "metadata": {}, "source": ["Here are examples of the comparison operators in use:"]}, {"cell_type": "code", "execution_count": 23, "id": "b3f2f9f3", "metadata": {}, "outputs": [], "source": ["a = 10\n", "b = 20"]}, {"cell_type": "code", "execution_count": 24, "id": "56dc7d50", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["a == b"]}, {"cell_type": "code", "execution_count": 25, "id": "76a974d8", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 25, "metadata": {}, "output_type": "execute_result"}], "source": ["a != b"]}, {"cell_type": "code", "execution_count": 26, "id": "61605dab", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 26, "metadata": {}, "output_type": "execute_result"}], "source": ["a <= b"]}, {"cell_type": "code", "execution_count": 27, "id": "891c5f7d", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 27, "metadata": {}, "output_type": "execute_result"}], "source": ["a >= b"]}, {"cell_type": "code", "execution_count": 28, "id": "1cb729fa", "metadata": {}, "outputs": [], "source": ["a = 30\n", "b = 30"]}, {"cell_type": "code", "execution_count": 29, "id": "ffd289cd", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["a == b"]}, {"cell_type": "code", "execution_count": 30, "id": "695a4c00", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 30, "metadata": {}, "output_type": "execute_result"}], "source": ["a <= b"]}, {"cell_type": "code", "execution_count": 31, "id": "2047b30a", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 31, "metadata": {}, "output_type": "execute_result"}], "source": ["a >= b"]}, {"cell_type": "markdown", "id": "aa8f7c1f", "metadata": {}, "source": ["Comparison operators are typically used in Boolean contexts like conditional and loop statements to direct program flow, as you will see later."]}, {"cell_type": "markdown", "id": "737dd052", "metadata": {}, "source": ["", "\n", "### Equality Comparison on Floating-Point Values\n", "\n", "Recall from the earlier discussion of floating-point numbers that the value stored internally for a float object may not be precisely what you\u2019d think it would be. For that reason, it is poor practice to compare floating-point values for exact equality. Consider this example:"]}, {"cell_type": "code", "execution_count": 2, "id": "f9a93596", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["x = 1.1 + 2.2\n", "x == 3.3"]}, {"cell_type": "markdown", "id": "b228ea16", "metadata": {}, "source": ["Yikes! The internal representations of the addition operands are not exactly equal to `1.1` and `2.2`, so you cannot rely on x to compare exactly to `3.3`."]}, {"cell_type": "markdown", "id": "47dc1cee", "metadata": {}, "source": ["The preferred way to determine whether two floating-point values are \u201cequal\u201d is to compute whether they are close to one another, given some tolerance. Take a look at this example:"]}, {"cell_type": "code", "execution_count": 127, "id": "7390ff8f", "metadata": {}, "outputs": [], "source": ["tolerance = 0.00001"]}, {"cell_type": "code", "execution_count": 128, "id": "0fd7b119", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 128, "metadata": {}, "output_type": "execute_result"}], "source": ["abs(x - 3.3) < tolerance"]}, {"cell_type": "markdown", "id": "fb041d2e", "metadata": {}, "source": ["`abs()` returns absolute value. If the absolute value of the difference between the two numbers is less than the specified tolerance, they are close enough to one another to be considered equal."]}, {"cell_type": "markdown", "id": "497e4d2a", "metadata": {}, "source": ["", "\n", "## Logical Operators\n", "\n", "The logical operators `not`, `or`, `and` and modify and join together expressions evaluated in Boolean context to create more complex conditions."]}, {"cell_type": "markdown", "id": "cba77d31", "metadata": {}, "source": ["", "\n", "### Logical Expressions Involving Boolean Operands\n", "\n", "As you have seen, some objects and expressions in Python actually are of Boolean type. That is, they are equal to one of the Python objects `True` or `False`."]}, {"cell_type": "code", "execution_count": 35, "id": "aabf38a1", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 35, "metadata": {}, "output_type": "execute_result"}], "source": ["x = 5\n", "x < 10"]}, {"cell_type": "code", "execution_count": 41, "id": "4d2afeb9", "metadata": {}, "outputs": [{"data": {"text/plain": ["bool"]}, "execution_count": 41, "metadata": {}, "output_type": "execute_result"}], "source": ["type(x < 10)"]}, {"cell_type": "markdown", "id": "86fab03a", "metadata": {}, "source": ["|Operator |\tExample\t |Meaning |\n", "|:--|:--|:--|\n", "|`not` | `not x` | `True` if `x` is `False`. `False` if `x` is `True` (Logically reverses the sense of `x`) |\n", "|`or` | `x or y` | `True` if either `x` or `y` is `True`. `False` otherwise. |\n", "|`and` | `x and y` | `True` if both `x` and `y` are `True`. `False` otherwise. |"]}, {"cell_type": "markdown", "id": "4febd04c", "metadata": {}, "source": ["Take a look at how they work in practice below."]}, {"cell_type": "code", "execution_count": 137, "id": "b41c32a6", "metadata": {}, "outputs": [], "source": ["x = 5"]}, {"cell_type": "code", "execution_count": 138, "id": "a1c405d3", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 138, "metadata": {}, "output_type": "execute_result"}], "source": ["not x < 10"]}, {"cell_type": "code", "execution_count": 139, "id": "704e8a42", "metadata": {}, "outputs": [], "source": ["x = 5"]}, {"cell_type": "code", "execution_count": 140, "id": "9f3f352a", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 140, "metadata": {}, "output_type": "execute_result"}], "source": ["x < 10 or x > 10"]}, {"cell_type": "code", "execution_count": 58, "id": "689e5edb", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 58, "metadata": {}, "output_type": "execute_result"}], "source": ["x < 10 and x > 10"]}, {"cell_type": "markdown", "id": "c2e4557d", "metadata": {}, "source": ["", "\n", "### Evaluation of Non-Boolean Values in Boolean Context\n", "\n", "Many objects and expressions are not equal to True or False. Nonetheless, they may still be evaluated in Boolean context and determined to be \u201ctruthy\u201d or \u201cfalsy.\u201d"]}, {"cell_type": "markdown", "id": "6681ab29", "metadata": {}, "source": ["So what is true and what isn\u2019t? As a philosophical question, that is outside the scope of this tutorial!"]}, {"cell_type": "markdown", "id": "7c1bddeb", "metadata": {}, "source": ["But in Python, it is well-defined. All the following are considered false when evaluated in Boolean context:\n", "- The Boolean value `False`\n", "- Any value that is numerically zero (`0`, `0.0`, `0.0+0.0j`)\n", "- An empty string\n", "- An object of a built-in composite data type which is empty (see later section)\n", "- The special value denoted by the Python keyword `None`"]}, {"cell_type": "markdown", "id": "ef2285d4", "metadata": {}, "source": ["Virtually any other object built into Python is regarded as `True`."]}, {"cell_type": "markdown", "id": "c3933c47", "metadata": {}, "source": ["You can determine the \u201ctruthiness\u201d of an object or expression with the built-in `bool()` function. `bool()` returns `True` if its argument is truthy and `False` if it is falsy."]}, {"cell_type": "markdown", "id": "3950c626", "metadata": {}, "source": ["#### Numeric Value\n", "- A zero value is false.\n", "- A non-zero value is true."]}, {"cell_type": "code", "execution_count": 154, "id": "e9050915", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["False False False\n"]}], "source": ["print(bool(0), bool(0.0), bool(0.0+0j))"]}, {"cell_type": "code", "execution_count": 155, "id": "96c8a566", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["True True True\n"]}], "source": ["print(bool(-3), bool(3.14159), bool(1.0+1j))"]}, {"cell_type": "markdown", "id": "0c37818b", "metadata": {}, "source": ["#### String\n", "- An empty string is false.\n", "- A non-empty string is true."]}, {"cell_type": "code", "execution_count": 156, "id": "8f27bdff", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["False False False\n"]}], "source": ["print(bool(''), bool(\"\"), bool(\"\"\"\"\"\"))"]}, {"cell_type": "code", "execution_count": 157, "id": "c348a752", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["True True True\n"]}], "source": ["print(bool('foo'), bool(\" \"), bool(''' '''))"]}, {"cell_type": "markdown", "id": "0a36f504", "metadata": {}, "source": ["#### Built-In Composite Data Object\n", "> Python provides built-in composite data types called `list`, `tuple`, `dict`, and `set` (and some more). These are \u201ccontainer\u201d types that contain other objects. An object of one of these types is considered false if it is empty and true if it is non-empty.\n", ">\n", ">The examples below demonstrate this for the list type. (Lists are defined in Python with square brackets.)\n", ">\n", ">For more information on the `list`, `tuple`, `dict`, `set`, etc. types, see the upcoming sections."]}, {"cell_type": "code", "execution_count": 158, "id": "d99a9d30", "metadata": {}, "outputs": [{"data": {"text/plain": ["list"]}, "execution_count": 158, "metadata": {}, "output_type": "execute_result"}], "source": ["type([])"]}, {"cell_type": "code", "execution_count": 159, "id": "70bafc98", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 159, "metadata": {}, "output_type": "execute_result"}], "source": ["bool([])"]}, {"cell_type": "code", "execution_count": 160, "id": "1ba859a9", "metadata": {}, "outputs": [{"data": {"text/plain": ["list"]}, "execution_count": 160, "metadata": {}, "output_type": "execute_result"}], "source": ["type([1, 2, 3])"]}, {"cell_type": "code", "execution_count": 161, "id": "c27e0e0c", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 161, "metadata": {}, "output_type": "execute_result"}], "source": ["bool([1, 2, 3])"]}, {"cell_type": "markdown", "id": "b3317357", "metadata": {}, "source": ["#### The `None` Keyword\n", "- `None` is always false:"]}, {"cell_type": "code", "execution_count": 162, "id": "0eb097aa", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 162, "metadata": {}, "output_type": "execute_result"}], "source": ["bool(None)"]}, {"cell_type": "markdown", "id": "b31651f2", "metadata": {}, "source": ["", "\n", "## Bitwise Operators\n", "\n", "Bitwise operators treat operands as sequences of binary digits and operate on them bit by bit. Bitwise operators will be addressed fully later."]}, {"cell_type": "markdown", "id": "ba596fec", "metadata": {}, "source": ["", "\n", "## Identity Operators\n", "\n", "Python provides two operators, `is` and `is not`, that determine whether the given operands have the same identity\u2014that is, refer to the same object. This is not the same thing as equality, which means the two operands refer to objects that contain the same data but are not necessarily the same object."]}, {"cell_type": "markdown", "id": "70c352df", "metadata": {}, "source": ["Here is an example of two object that are equal but not identical:"]}, {"cell_type": "code", "execution_count": 64, "id": "9ed4cf85", "metadata": {}, "outputs": [], "source": ["x = 1001\n", "y = 1000 + 1"]}, {"cell_type": "code", "execution_count": 65, "id": "beae0879", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1001 1001\n"]}], "source": ["print(x, y)"]}, {"cell_type": "code", "execution_count": 66, "id": "19ba7b74", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 66, "metadata": {}, "output_type": "execute_result"}], "source": ["x == y"]}, {"cell_type": "code", "execution_count": 4, "id": "58c101e2", "metadata": {}, "outputs": [], "source": ["x is y"]}, {"cell_type": "markdown", "id": "e70e17e7", "metadata": {}, "source": ["Here, `x` and `y` both refer to objects whose value is `1001`. They are equal. But they do not reference the same object, as you can verify:"]}, {"cell_type": "code", "execution_count": 68, "id": "79b3bffa", "metadata": {}, "outputs": [{"data": {"text/plain": ["140016350734768"]}, "execution_count": 68, "metadata": {}, "output_type": "execute_result"}], "source": ["id(x)"]}, {"cell_type": "code", "execution_count": 69, "id": "116ea605", "metadata": {}, "outputs": [{"data": {"text/plain": ["140016350734224"]}, "execution_count": 69, "metadata": {}, "output_type": "execute_result"}], "source": ["id(y)"]}, {"cell_type": "markdown", "id": "b3743e65", "metadata": {}, "source": ["`x` and `y` do not have the same identity, and `x` is `y` returns `False`."]}, {"cell_type": "markdown", "id": "7a85a8a4", "metadata": {}, "source": ["You saw previously that when you make an assignment like `x = y`, Python merely creates a second reference to the same object, and that you could confirm that fact with the `id()` function. You can also confirm it using the `is` operator:"]}, {"cell_type": "code", "execution_count": 112, "id": "7248d4c3", "metadata": {}, "outputs": [], "source": ["a = 'I am a string'\n", "b = a"]}, {"cell_type": "code", "execution_count": 113, "id": "eab98ef9", "metadata": {}, "outputs": [{"data": {"text/plain": ["140078194378544"]}, "execution_count": 113, "metadata": {}, "output_type": "execute_result"}], "source": ["id(a)"]}, {"cell_type": "code", "execution_count": 114, "id": "697bee23", "metadata": {}, "outputs": [{"data": {"text/plain": ["140078194378544"]}, "execution_count": 114, "metadata": {}, "output_type": "execute_result"}], "source": ["id(b)"]}, {"cell_type": "code", "execution_count": 115, "id": "c9e1462a", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 115, "metadata": {}, "output_type": "execute_result"}], "source": ["a is b"]}, {"cell_type": "code", "execution_count": 123, "id": "53c450a3", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 123, "metadata": {}, "output_type": "execute_result"}], "source": ["a == b"]}, {"cell_type": "markdown", "id": "584a8306", "metadata": {}, "source": ["In this case, since `a` and `b` reference the same object, it stands to reason that `a` and `b` would be equal as well."]}, {"cell_type": "markdown", "id": "df20743f", "metadata": {}, "source": ["Unsurprisingly, the opposite of `is` is `is not`:"]}, {"cell_type": "code", "execution_count": 75, "id": "f71d6191", "metadata": {}, "outputs": [], "source": ["x = 10\n", "y = 20"]}, {"cell_type": "code", "execution_count": 126, "id": "15356c11", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 126, "metadata": {}, "output_type": "execute_result"}], "source": ["x is not y"]}, {"cell_type": "markdown", "id": "2a1251df", "metadata": {}, "source": ["", "\n", "## Augmented Assignment Operators\n", "\n", "You have seen that a single equal sign (`=`) is used to assign a value to a variable. It is, of course, perfectly viable for the value to the right of the assignment to be an expression containing other variables:"]}, {"cell_type": "code", "execution_count": 186, "id": "70d83a70", "metadata": {}, "outputs": [], "source": ["a = 10\n", "b = 20\n", "c = a * 5 + b"]}, {"cell_type": "code", "execution_count": 187, "id": "1446ee97", "metadata": {}, "outputs": [{"data": {"text/plain": ["70"]}, "execution_count": 187, "metadata": {}, "output_type": "execute_result"}], "source": ["c"]}, {"cell_type": "markdown", "id": "7d2b4c96", "metadata": {}, "source": ["In fact, the expression to the right of the assignment can include references to the variable that is being assigned to:"]}, {"cell_type": "markdown", "id": "29e02ba0", "metadata": {}, "source": ["Python supports a shorthand augmented assignment notation for these arithmetic and bitwise operators:\n", "\n", "|Arithmetic|Bitwise|\n", "|:--|:--|\n", "|`+`| `&` |\n", "|`-`|`|`|\n", "|`*`|`^`|\n", "|`/`|`>>`|\n", "|`%`|`<<`|\n", "|`//`||\n", "|`**`||"]}, {"cell_type": "markdown", "id": "608cd54a", "metadata": {}, "source": ["For these operators, the following are equivalent:\n", "\n", "```python\n", "x = y\n", "x = x y\n", "```"]}, {"cell_type": "markdown", "id": "81bb46ce", "metadata": {}, "source": ["Take a look at these examples:\n", "\n", "|Augmented Assignment || Standard Assignment |\n", "|:--|:--|:--|\n", "|`a += 5` | is equivalent to\t| `a = a + 5`|\n", "|`a /= 10` | is equivalent to\t| `a = a / 10`|\n", "|`a ^= b` | is equivalent to\t| `a = a ^ b`|"]}, {"cell_type": "markdown", "id": "47b56763", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "In this section, you learned about the diverse **operators** Python supports to combine objects into **expressions**."]}, {"cell_type": "markdown", "id": "30d6c1eb", "metadata": {}, "source": ["Most of the examples you have seen so far have involved only simple atomic data, but you saw a brief introduction to the **string** data type. The next tutorial will explore **string** objects in much more detail."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/python/01. Basics/07 Strings.ipynb b/python/01. Basics/07 Strings.ipynb index 875ebe7..120e217 100755 --- a/python/01. Basics/07 Strings.ipynb +++ b/python/01. Basics/07 Strings.ipynb @@ -1,2192 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "23184e8c", - "metadata": {}, - "source": [ - "# Strings\n", - "\n", - "In the section on Basic Data Types in Python, you learned how to define **strings**: objects that contain sequences of character data. Processing character data is integral to programming. It is a rare application that doesn’t need to manipulate strings at least to some extent." - ] - }, - { - "cell_type": "markdown", - "id": "fa10c681", - "metadata": {}, - "source": [ - "## String Manipulation\n", - "\n", - "The sections below highlight the operators, methods, and functions that are available for working with strings." - ] - }, - { - "cell_type": "markdown", - "id": "5f662515", - "metadata": {}, - "source": [ - "### String Operators\n", - "\n", - "You have already seen the operators `+` and `*` applied to numeric operands in the section on Operators and Expressions in Python. These two operators can be applied to strings as well." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "304f586c", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foo'\n", - "t = 'bar'\n", - "u = 'baz'" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "c19e1260", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foobar'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s + t" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "390915d3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foobarbaz'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s + t + u" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "4f7187bc", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Go team!!!\n" - ] - } - ], - "source": [ - "print('Go team' + '!!!')" - ] - }, - { - "cell_type": "markdown", - "id": "9ae0c9fd", - "metadata": {}, - "source": [ - "### The * Operator\n", - "\n", - "The `*` operator creates multiple copies of a string. If `s` is a string and `n` is an integer, either of the following expressions returns a string consisting of `n` concatenated copies of `s`:\n", - "\n", - "```python\n", - "s * n\n", - "n * s\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "35fcc197", - "metadata": {}, - "source": [ - "Here are examples of both forms:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "5fee7681", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foo.'" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "a91d4e2c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo.foo.foo.foo.'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s * 4" - ] - }, - { - "cell_type": "code", - "execution_count": 109, - "id": "29b880af", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo.foo.foo.foo.'" - ] - }, - "execution_count": 109, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "4 * s" - ] - }, - { - "cell_type": "markdown", - "id": "aa601859", - "metadata": {}, - "source": [ - "The multiplier operand `n` must be an integer. You’d think it would be required to be a positive integer, but amusingly, it can be zero or negative, in which case the result is an empty string:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "eb8f0829", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "''" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'foo' * -8" - ] - }, - { - "cell_type": "markdown", - "id": "94f37fc7", - "metadata": {}, - "source": [ - "If you were to create a string variable and initialize it to the empty string by assigning it the value `'foo' * -8`, anyone would rightly think you were a bit daft. But it would work." - ] - }, - { - "cell_type": "markdown", - "id": "6c2dec9a", - "metadata": {}, - "source": [ - "### The in Operator\n", - "\n", - "Python also provides a membership operator that can be used with strings. The in operator returns `True` if the first operand is contained within the second, and `False` otherwise:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aa92d506", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foo'" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "e9590c4e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s in 'That\\'s food for thought.'" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "7fd79b34", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s in 'That\\'s good for now.'" - ] - }, - { - "cell_type": "markdown", - "id": "c46218b6", - "metadata": {}, - "source": [ - "There is also a `not in` operator, which does the opposite:" - ] - }, - { - "cell_type": "code", - "execution_count": 119, - "id": "4b61a741", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 119, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'z' not in 'abc'" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "bb36289f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'z' in 'xyz'" - ] - }, - { - "cell_type": "markdown", - "id": "99da370e", - "metadata": {}, - "source": [ - "### Built-in String Functions\n", - "\n", - "As you saw in the tutorial on Basic Data Types in Python, Python provides many functions that are built-in to the interpreter and always available. Here are a few that work with strings:\n", - "\n", - "\n", - "|Function | Description|\n", - "|:--|:--|\n", - "|`chr()` | Converts an integer to a character |\n", - "|`ord()` | Converts a character to an integer |\n", - "|`len()` | Returns the length of a string |\n", - "|`str()` | Returns a string representation of an object |" - ] - }, - { - "cell_type": "markdown", - "id": "9c16daa2", - "metadata": {}, - "source": [ - "These are explored more fully below." - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "065a5ffa", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "63" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ord('?')" - ] - }, - { - "cell_type": "markdown", - "id": "144abae1", - "metadata": {}, - "source": [ - "#### `ord(c)`\n", - "> Returns an integer value for the given character." - ] - }, - { - "cell_type": "markdown", - "id": "258d19cb", - "metadata": {}, - "source": [ - "At the most basic level, computers store all information as numbers. To represent character data, a translation scheme is used which maps each character to its representative number." - ] - }, - { - "cell_type": "markdown", - "id": "e5aade2b", - "metadata": {}, - "source": [ - "The simplest scheme in common use is called [ASCII](https://en.wikipedia.org/wiki/ASCII). It covers the common Latin characters you are probably most accustomed to working with. For these characters, ord(c) returns the ASCII value for character c:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "c27fbf59", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "97" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ord('a')" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "3a02c7cc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "35" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ord('#')" - ] - }, - { - "cell_type": "markdown", - "id": "7e8e3c5f", - "metadata": {}, - "source": [ - "ASCII is fine as far as it goes. But there are many different languages in use in the world and countless symbols and glyphs that appear in digital media. The full set of characters that potentially may need to be represented in computer code far surpasses the ordinary Latin letters, numbers, and symbols you usually see." - ] - }, - { - "cell_type": "markdown", - "id": "b04c4073", - "metadata": {}, - "source": [ - "[Unicode](http://www.unicode.org/standard/WhatIsUnicode.html) is an ambitious standard that attempts to provide a numeric code for every possible character, in every possible language, on every possible platform. Python 3 supports Unicode extensively, including allowing Unicode characters within strings." - ] - }, - { - "cell_type": "markdown", - "id": "4de6aad9", - "metadata": {}, - "source": [ - "As long as you stay in the domain of the common characters, there is little practical difference between ASCII and Unicode. But the `ord()` function will return numeric values for [Unicode characters](https://realpython.com/courses/python-unicode/) as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "id": "0cd71268", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8364" - ] - }, - "execution_count": 127, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ord('€')" - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "id": "c6b714d9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "8721" - ] - }, - "execution_count": 128, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ord('∑')" - ] - }, - { - "cell_type": "markdown", - "id": "e408ba9e", - "metadata": {}, - "source": [ - "#### `chr(n)`\n", - "\n", - "> Returns a character value for the given integer." - ] - }, - { - "cell_type": "markdown", - "id": "334fa1cf", - "metadata": {}, - "source": [ - "`chr()` does the reverse of `ord()`. Given a numeric value `n`, `chr(n)` returns a string representing the character that corresponds to `n`:" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "id": "ef2c4a45", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a'" - ] - }, - "execution_count": 133, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chr(97)" - ] - }, - { - "cell_type": "code", - "execution_count": 134, - "id": "ada4d5f7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'#'" - ] - }, - "execution_count": 134, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chr(35)" - ] - }, - { - "cell_type": "markdown", - "id": "3f7c454d", - "metadata": {}, - "source": [ - "`chr()` handles Unicode characters as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 135, - "id": "d80a064b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'€'" - ] - }, - "execution_count": 135, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chr(8364)" - ] - }, - { - "cell_type": "code", - "execution_count": 136, - "id": "80200ecb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'∑'" - ] - }, - "execution_count": 136, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "chr(8721)" - ] - }, - { - "cell_type": "markdown", - "id": "eb12b3f4", - "metadata": {}, - "source": [ - "#### len(s)\n", - "\n", - "With `len()`, you can check Python string length. `len(s)` returns the number of characters in `s`:" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "37161877", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "14" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = 'I am a string.'\n", - "len(s)" - ] - }, - { - "cell_type": "markdown", - "id": "0cb9afd4", - "metadata": {}, - "source": [ - "#### `str(obj)`\n", - "\n", - "> Returns a string representation of an object." - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "d2ba5dc5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'2'" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str(2)" - ] - }, - { - "cell_type": "markdown", - "id": "a45eae4a", - "metadata": {}, - "source": [ - "Virtually any object in Python can be rendered as a string. `str(obj)` returns the string representation of object obj:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "8e7ba22f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'49.2'" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str(49.2)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "f9d91ce6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(3+4j)'" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str(3+4j)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "427eb452", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'32'" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str(3 + 29)" - ] - }, - { - "cell_type": "code", - "execution_count": 146, - "id": "7f80df9f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 146, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "str('foo')" - ] - }, - { - "cell_type": "markdown", - "id": "0b114fd4", - "metadata": {}, - "source": [ - "## String Indexing\n", - "\n", - "Often in programming languages, individual items in an ordered set of data can be accessed directly using a numeric index or key value. This process is referred to as indexing." - ] - }, - { - "cell_type": "markdown", - "id": "d3318f34", - "metadata": {}, - "source": [ - "In Python, strings are ordered sequences of character data, and thus can be indexed in this way. Individual characters in a string can be accessed by specifying the string name followed by a number in square brackets (`[]`)." - ] - }, - { - "cell_type": "markdown", - "id": "62417aa5", - "metadata": {}, - "source": [ - "String indexing in Python is zero-based: the first character in the string has index 0, the next has index 1, and so on. The index of the last character will be the length of the string minus one." - ] - }, - { - "cell_type": "markdown", - "id": "8572a66d", - "metadata": {}, - "source": [ - "For example, a schematic diagram of the indices of the string 'foobar' would look like this:" - ] - }, - { - "cell_type": "markdown", - "id": "19f6db4d", - "metadata": {}, - "source": [ - "\"string" - ] - }, - { - "cell_type": "markdown", - "id": "0a8f26d4", - "metadata": {}, - "source": [ - "The individual characters can be accessed by index as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "eaf4fef3", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "dbd0ce02", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'f'" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "c62afc05", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'o'" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "fb34188f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'b'" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[3]" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "67c96720", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(s)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "964f4c3d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'r'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[len(s)-1]" - ] - }, - { - "cell_type": "markdown", - "id": "d84b6e53", - "metadata": {}, - "source": [ - "Attempting to index beyond the end of the string results in an error:" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "29394047", - "metadata": {}, - "outputs": [ - { - "ename": "IndexError", - "evalue": "string index out of range", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mIndexError\u001b[0m: string index out of range" - ] - } - ], - "source": [ - "s[6]" - ] - }, - { - "cell_type": "markdown", - "id": "7c3045a1", - "metadata": {}, - "source": [ - "String indices can also be specified with negative numbers, in which case indexing occurs from the end of the string backward: `-1` refers to the last character, `-2` the second-to-last character, and so on. Here is the same diagram showing both the positive and negative indices into the string `'foobar'`:\n", - "\n", - "\"negative" - ] - }, - { - "cell_type": "markdown", - "id": "fa634d72", - "metadata": {}, - "source": [ - "Here are some examples of negative indexing:" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "b926b461", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "0dad316d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'r'" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "a0fc50e7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a'" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[-2]" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "e33e707a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(s)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "4e774bd8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'f'" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[-len(s)]" - ] - }, - { - "cell_type": "markdown", - "id": "e88d687d", - "metadata": {}, - "source": [ - "Attempting to index with negative numbers beyond the start of the string results in an error:" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "7b114e51", - "metadata": {}, - "outputs": [ - { - "ename": "IndexError", - "evalue": "string index out of range", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m7\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mIndexError\u001b[0m: string index out of range" - ] - } - ], - "source": [ - "s[-7]" - ] - }, - { - "cell_type": "markdown", - "id": "fe12ee7a", - "metadata": {}, - "source": [ - "For any non-empty string `s`, `s[len(s)-1]` and `s[-1]` both return the last character. There isn’t any index that makes sense for an empty string." - ] - }, - { - "cell_type": "markdown", - "id": "1d844f12", - "metadata": {}, - "source": [ - "## String Slicing\n", - "\n", - "Python also allows a form of indexing syntax that extracts substrings from a string, known as string slicing. If `s` is a string, an expression of the form `s[m:n]` returns the portion of `s` starting with position `m`, and up to but not including position `n`:" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "dc1c8c8d", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "9caac50f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'oba'" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[2:5]" - ] - }, - { - "cell_type": "markdown", - "id": "3c460a46", - "metadata": {}, - "source": [ - "> **Remember:** String indices are zero-based. The first character in a string has index `0`. This applies to both standard indexing and slicing." - ] - }, - { - "cell_type": "markdown", - "id": "6bc29431", - "metadata": {}, - "source": [ - "Again, the second index specifies the first character that is not included in the result—the character `'r'` (`s[5]`) in the example above. That may seem slightly unintuitive, but it produces this result which makes sense: the expression `s[m:n]` will return a substring that is `n - m` characters in length, in this case, `5 - 2 = 3`." - ] - }, - { - "cell_type": "markdown", - "id": "3c19e834", - "metadata": {}, - "source": [ - "If you omit the first index, the slice starts at the beginning of the string. Thus, `s[:m]` and `s[0:m]` are equivalent:" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "65e54921", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "6a476644", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foob'" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[:4]" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "7ec12414", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foob'" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[0:4]" - ] - }, - { - "cell_type": "markdown", - "id": "4bb9b797", - "metadata": {}, - "source": [ - "Similarly, if you omit the second index as in `s[n:]`, the slice extends from the first index through the end of the string. This is a nice, concise alternative to the more cumbersome `s[n:len(s)]`:" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "72ef55f9", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "be68a664", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'obar'" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[2:]" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "a38390ee", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'obar'" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[2:len(s)]" - ] - }, - { - "cell_type": "markdown", - "id": "e02f081a", - "metadata": {}, - "source": [ - "For any string `s` and any integer `n` (`0 ≤ n ≤ len(s)`), `s[:n]` + `s[n:]` will be equal to `s`:" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "c783d1ba", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "3a8bda17", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foobar'" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[:4] + s[4:]" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "4287977f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[:4] + s[4:] == s" - ] - }, - { - "cell_type": "markdown", - "id": "3d1c6c3b", - "metadata": {}, - "source": [ - "Omitting both indices returns the original string, in its entirety. Literally. It’s not a copy, it’s a reference to the original string:" - ] - }, - { - "cell_type": "code", - "execution_count": 139, - "id": "99526ddd", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'\n", - "t = s[:]" - ] - }, - { - "cell_type": "code", - "execution_count": 140, - "id": "5935f149", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "140343766368944" - ] - }, - "execution_count": 140, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(s)" - ] - }, - { - "cell_type": "code", - "execution_count": 141, - "id": "9f89d290", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "140343766368944" - ] - }, - "execution_count": 141, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(t)" - ] - }, - { - "cell_type": "code", - "execution_count": 122, - "id": "f6b7252c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 122, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s is t" - ] - }, - { - "cell_type": "markdown", - "id": "1e2b086f", - "metadata": {}, - "source": [ - "If the first index in a slice is greater than or equal to the second index, Python returns an empty string. This is yet another obfuscated way to generate an empty string, in case you were looking for one:" - ] - }, - { - "cell_type": "code", - "execution_count": 123, - "id": "2bd7e4d5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "''" - ] - }, - "execution_count": 123, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[2:2]" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "id": "416cac6b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "''" - ] - }, - "execution_count": 124, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[4:2]" - ] - }, - { - "cell_type": "markdown", - "id": "a4cfee25", - "metadata": {}, - "source": [ - "Negative indices can be used with slicing as well. `-1` refers to the last character, `-2` the second-to-last, and so on, just as with simple indexing. The diagram below shows how to slice the substring `'oob'` from the string `'foobar'` using both positive and negative indices:" - ] - }, - { - "cell_type": "markdown", - "id": "e6534e11", - "metadata": {}, - "source": [ - "\"negative" - ] - }, - { - "cell_type": "markdown", - "id": "a5f795f0", - "metadata": {}, - "source": [ - "Here is the corresponding Python code:" - ] - }, - { - "cell_type": "code", - "execution_count": 97, - "id": "ed873371", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 98, - "id": "8bada5f2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'oob'" - ] - }, - "execution_count": 98, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[-5:-2]" - ] - }, - { - "cell_type": "code", - "execution_count": 99, - "id": "bc825852", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'oob'" - ] - }, - "execution_count": 99, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[1:4]" - ] - }, - { - "cell_type": "code", - "execution_count": 100, - "id": "da0b7858", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 100, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[-5:-2] == s[1:4]" - ] - }, - { - "cell_type": "markdown", - "id": "5d217458", - "metadata": {}, - "source": [ - "### Specifying a Stride in a String Slice\n", - "\n", - "There is one more variant of the slicing syntax to discuss. Adding an additional : and a third index designates a stride (also called a step), which indicates how many characters to jump after retrieving each character in the slice." - ] - }, - { - "cell_type": "markdown", - "id": "131003a6", - "metadata": {}, - "source": [ - "For example, for the string `'foobar'`, the slice `0:6:2` starts with the first character and ends with the last character (the whole string), and every second character is skipped. This is shown in the following diagram:" - ] - }, - { - "cell_type": "markdown", - "id": "5d1f9376", - "metadata": {}, - "source": [ - "\"negative" - ] - }, - { - "cell_type": "markdown", - "id": "cc84ca16", - "metadata": {}, - "source": [ - "Similarly, `1:6:2` specifies a slice starting with the second character (index 1) and ending with the last character, and again the stride value 2 causes every other character to be skipped:" - ] - }, - { - "cell_type": "markdown", - "id": "74269e50", - "metadata": {}, - "source": [ - "\"negative" - ] - }, - { - "cell_type": "markdown", - "id": "5a71519e", - "metadata": {}, - "source": [ - "The illustrative REPL code is shown here:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "d081aefb", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "fac11ecc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foa'" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[0:6:2]" - ] - }, - { - "cell_type": "code", - "execution_count": 150, - "id": "511dfc17", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'obr'" - ] - }, - "execution_count": 150, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[1:6:2]" - ] - }, - { - "cell_type": "markdown", - "id": "8eb3fb70", - "metadata": {}, - "source": [ - "As with any slicing, the first and second indices can be omitted, and default to the first and last characters respectively:" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "9d29edff", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'1234512345123451234512345'" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = '12345' * 5\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "0ecd60d3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'11111'" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[::5]" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "bf177775", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'55555'" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[4::5]" - ] - }, - { - "cell_type": "markdown", - "id": "8840ec22", - "metadata": {}, - "source": [ - "You can specify a negative stride value as well, in which case Python steps backward through the string. In that case, the starting/first index should be greater than the ending/second index:" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "33b0d776", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "8369d371", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'rbo'" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[5:0:-2]" - ] - }, - { - "cell_type": "markdown", - "id": "29eb0e9c", - "metadata": {}, - "source": [ - "In the above example, `5:0:-2` means “start at the last character and step backward by 2, up to but not including the first character.”" - ] - }, - { - "cell_type": "markdown", - "id": "f4881569", - "metadata": {}, - "source": [ - "When you are stepping backward, if the first and second indices are omitted, the defaults are reversed in an intuitive way: the first index defaults to the end of the string, and the second index defaults to the beginning. Here is an example:" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "2695ac21", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'1234512345123451234512345'" - ] - }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = '12345' * 5\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "c61e970d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'55555'" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[::-5]" - ] - }, - { - "cell_type": "markdown", - "id": "a693b6e0", - "metadata": {}, - "source": [ - "This is a common paradigm for reversing a string:" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "60613308", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'.thgir eb tsum ti ,ti syas noelopaN edarmoC fI'" - ] - }, - "execution_count": 81, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = 'If Comrade Napoleon says it, it must be right.'\n", - "s[::-1]" - ] - }, - { - "cell_type": "markdown", - "id": "79e56be3", - "metadata": {}, - "source": [ - "### Interpolating Variables Into a String\n", - "\n", - "In Python version 3.6, a new string formatting mechanism was introduced. This feature is formally named the Formatted String Literal, but is more usually referred to by its nickname **f-string**." - ] - }, - { - "cell_type": "markdown", - "id": "77adf220", - "metadata": {}, - "source": [ - "One simple feature of f-strings you can start using right away is variable interpolation. You can specify a variable name directly within an f-string literal, and Python will replace the name with the corresponding value." - ] - }, - { - "cell_type": "markdown", - "id": "38ca79f3", - "metadata": {}, - "source": [ - "For example, suppose you want to display the result of an arithmetic calculation. You can do this with a straightforward `print()` statement, separating numeric values and string literals by commas:" - ] - }, - { - "cell_type": "code", - "execution_count": 173, - "id": "4ef35286", - "metadata": {}, - "outputs": [], - "source": [ - "n = 20\n", - "m = 25\n", - "prod = n * m" - ] - }, - { - "cell_type": "code", - "execution_count": 174, - "id": "0e7c2ac3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The product of 20 and 25 is 500\n" - ] - } - ], - "source": [ - "print('The product of', n, 'and', m, 'is', prod)" - ] - }, - { - "cell_type": "markdown", - "id": "b9400efe", - "metadata": {}, - "source": [ - "But this is cumbersome. To accomplish the same thing using an f-string:\n", - "\n", - "- Specify either a lowercase `f` or uppercase `F` directly before the opening quote of the string literal. This tells Python it is an f-string instead of a standard string.\n", - "- Specify any variables to be interpolated in curly braces (`{}`)." - ] - }, - { - "cell_type": "markdown", - "id": "a300882d", - "metadata": {}, - "source": [ - "Recast using an f-string, the above example looks much cleaner:" - ] - }, - { - "cell_type": "code", - "execution_count": 182, - "id": "1476ff7f", - "metadata": {}, - "outputs": [], - "source": [ - "n = 20\n", - "m = 25\n", - "prod = n * m" - ] - }, - { - "cell_type": "code", - "execution_count": 181, - "id": "8981e5fd", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The product of 20.293742397423973 and 25 is 507.34355993559933\n" - ] - } - ], - "source": [ - "print(f'The product of {n} and {m} is {prod}')" - ] - }, - { - "cell_type": "markdown", - "id": "2a58dedc", - "metadata": {}, - "source": [ - "Any of Python’s three quoting mechanisms can be used to define an f-string:" - ] - }, - { - "cell_type": "code", - "execution_count": 131, - "id": "a622099d", - "metadata": {}, - "outputs": [], - "source": [ - "var = 'Bark'" - ] - }, - { - "cell_type": "code", - "execution_count": 132, - "id": "a6b78d81", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A dog says Bark!\n" - ] - } - ], - "source": [ - "print(f'A dog says {var}!')" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "id": "85026c41", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A dog says Bark!\n" - ] - } - ], - "source": [ - "print(f\"A dog says {var}!\")" - ] - }, - { - "cell_type": "code", - "execution_count": 134, - "id": "086a85df", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "A dog says Bark!\n" - ] - } - ], - "source": [ - "print(f'''A dog says {var}!''')" - ] - }, - { - "cell_type": "markdown", - "id": "ddd555bf", - "metadata": {}, - "source": [ - "### Modifying Strings\n", - "\n", - "In a nutshell, you can’t. Strings are one of the data types Python considers immutable, meaning not able to be changed. In fact, all the data types you have seen so far are immutable. (Python does provide data types that are mutable, as you will soon see.)" - ] - }, - { - "cell_type": "markdown", - "id": "b4be2765", - "metadata": {}, - "source": [ - "A statement like this will cause an error:" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "9f475df5", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 193, - "id": "3df90174", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'str' object does not support item assignment", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'x'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" - ] - } - ], - "source": [ - "s[3] = 'x'" - ] - }, - { - "cell_type": "markdown", - "id": "857cda55", - "metadata": {}, - "source": [ - "In truth, there really isn’t much need to modify strings. You can usually easily accomplish what you want by generating a copy of the original string that has the desired change in place. There are very many ways to do this in Python. Here is one possibility:" - ] - }, - { - "cell_type": "code", - "execution_count": 93, - "id": "066fbc51", - "metadata": {}, - "outputs": [], - "source": [ - "s = s[:3] + 'x' + s[4:]" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "id": "78dd04d6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'fooxar'" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "markdown", - "id": "2b2f1422", - "metadata": {}, - "source": [ - "## Conclusion\n", - "This tutorial provided an in-depth look at the many different mechanisms Python provides for string handling, including string operators, built-in functions, indexing, slicing, and built-in methods. You also were introduced to the bytes and bytearray types." - ] - }, - { - "cell_type": "markdown", - "id": "04c7a670", - "metadata": {}, - "source": [ - "These types are the first types you have examined that are composite—built from a collection of smaller parts. Python provides several composite built-in types. In the next tutorial, you will explore two of the most frequently used: `lists` and `tuples`." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "23184e8c", "metadata": {}, "source": ["# Strings\n", "\n", "In the section on Basic Data Types in Python, you learned how to define **strings**: objects that contain sequences of character data. Processing character data is integral to programming. It is a rare application that doesn\u2019t need to manipulate strings at least to some extent."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [String Manipulation](#string_manipulation)\n * [String Operators](#string_operators)\n * [The * Operator](#the_*_operator)\n * [The in Operator](#the_in_operator)\n * [Built-in String Functions](#built-in_string_functions)\n* [String Indexing](#string_indexing)\n* [String Slicing](#string_slicing)\n * [Specifying a Stride in a String Slice](#specifying_a_stride_in_a_string_slice)\n * [Interpolating Variables Into a String](#interpolating_variables_into_a_string)\n * [Modifying Strings](#modifying_strings)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "id": "fa10c681", "metadata": {}, "source": ["", "\n", "## String Manipulation\n", "\n", "The sections below highlight the operators, methods, and functions that are available for working with strings."]}, {"cell_type": "markdown", "id": "5f662515", "metadata": {}, "source": ["", "\n", "### String Operators\n", "\n", "You have already seen the operators `+` and `*` applied to numeric operands in the section on Operators and Expressions in Python. These two operators can be applied to strings as well."]}, {"cell_type": "code", "execution_count": 13, "id": "304f586c", "metadata": {}, "outputs": [], "source": ["s = 'foo'\n", "t = 'bar'\n", "u = 'baz'"]}, {"cell_type": "code", "execution_count": 14, "id": "c19e1260", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foobar'"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["s + t"]}, {"cell_type": "code", "execution_count": 15, "id": "390915d3", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foobarbaz'"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["s + t + u"]}, {"cell_type": "code", "execution_count": 16, "id": "4f7187bc", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Go team!!!\n"]}], "source": ["print('Go team' + '!!!')"]}, {"cell_type": "markdown", "id": "9ae0c9fd", "metadata": {}, "source": ["", "\n", "### The * Operator\n", "\n", "The `*` operator creates multiple copies of a string. If `s` is a string and `n` is an integer, either of the following expressions returns a string consisting of `n` concatenated copies of `s`:\n", "\n", "```python\n", "s * n\n", "n * s\n", "```"]}, {"cell_type": "markdown", "id": "35fcc197", "metadata": {}, "source": ["Here are examples of both forms:"]}, {"cell_type": "code", "execution_count": 1, "id": "5fee7681", "metadata": {}, "outputs": [], "source": ["s = 'foo.'"]}, {"cell_type": "code", "execution_count": 2, "id": "a91d4e2c", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo.foo.foo.foo.'"]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["s * 4"]}, {"cell_type": "code", "execution_count": 109, "id": "29b880af", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo.foo.foo.foo.'"]}, "execution_count": 109, "metadata": {}, "output_type": "execute_result"}], "source": ["4 * s"]}, {"cell_type": "markdown", "id": "aa601859", "metadata": {}, "source": ["The multiplier operand `n` must be an integer. You\u2019d think it would be required to be a positive integer, but amusingly, it can be zero or negative, in which case the result is an empty string:"]}, {"cell_type": "code", "execution_count": 19, "id": "eb8f0829", "metadata": {}, "outputs": [{"data": {"text/plain": ["''"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["'foo' * -8"]}, {"cell_type": "markdown", "id": "94f37fc7", "metadata": {}, "source": ["If you were to create a string variable and initialize it to the empty string by assigning it the value `'foo' * -8`, anyone would rightly think you were a bit daft. But it would work."]}, {"cell_type": "markdown", "id": "6c2dec9a", "metadata": {}, "source": ["", "\n", "### The in Operator\n", "\n", "Python also provides a membership operator that can be used with strings. The in operator returns `True` if the first operand is contained within the second, and `False` otherwise:"]}, {"cell_type": "code", "execution_count": 10, "id": "aa92d506", "metadata": {}, "outputs": [], "source": ["s = 'foo'"]}, {"cell_type": "code", "execution_count": 11, "id": "e9590c4e", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["s in 'That\\'s food for thought.'"]}, {"cell_type": "code", "execution_count": 12, "id": "7fd79b34", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["s in 'That\\'s good for now.'"]}, {"cell_type": "markdown", "id": "c46218b6", "metadata": {}, "source": ["There is also a `not in` operator, which does the opposite:"]}, {"cell_type": "code", "execution_count": 119, "id": "4b61a741", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 119, "metadata": {}, "output_type": "execute_result"}], "source": ["'z' not in 'abc'"]}, {"cell_type": "code", "execution_count": 34, "id": "bb36289f", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 34, "metadata": {}, "output_type": "execute_result"}], "source": ["'z' in 'xyz'"]}, {"cell_type": "markdown", "id": "99da370e", "metadata": {}, "source": ["", "\n", "### Built-in String Functions\n", "\n", "As you saw in the tutorial on Basic Data Types in Python, Python provides many functions that are built-in to the interpreter and always available. Here are a few that work with strings:\n", "\n", "\n", "|Function | Description|\n", "|:--|:--|\n", "|`chr()` | Converts an integer to a character |\n", "|`ord()` | Converts a character to an integer |\n", "|`len()` | Returns the length of a string |\n", "|`str()` | Returns a string representation of an object |"]}, {"cell_type": "markdown", "id": "9c16daa2", "metadata": {}, "source": ["These are explored more fully below."]}, {"cell_type": "code", "execution_count": 126, "id": "065a5ffa", "metadata": {}, "outputs": [{"data": {"text/plain": ["63"]}, "execution_count": 126, "metadata": {}, "output_type": "execute_result"}], "source": ["ord('?')"]}, {"cell_type": "markdown", "id": "144abae1", "metadata": {}, "source": ["#### `ord(c)`\n", "> Returns an integer value for the given character."]}, {"cell_type": "markdown", "id": "258d19cb", "metadata": {}, "source": ["At the most basic level, computers store all information as numbers. To represent character data, a translation scheme is used which maps each character to its representative number."]}, {"cell_type": "markdown", "id": "e5aade2b", "metadata": {}, "source": ["The simplest scheme in common use is called [ASCII](https://en.wikipedia.org/wiki/ASCII). It covers the common Latin characters you are probably most accustomed to working with. For these characters, ord(c) returns the ASCII value for character c:"]}, {"cell_type": "code", "execution_count": 15, "id": "c27fbf59", "metadata": {}, "outputs": [{"data": {"text/plain": ["97"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["ord('a')"]}, {"cell_type": "code", "execution_count": 16, "id": "3a02c7cc", "metadata": {}, "outputs": [{"data": {"text/plain": ["35"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["ord('#')"]}, {"cell_type": "markdown", "id": "7e8e3c5f", "metadata": {}, "source": ["ASCII is fine as far as it goes. But there are many different languages in use in the world and countless symbols and glyphs that appear in digital media. The full set of characters that potentially may need to be represented in computer code far surpasses the ordinary Latin letters, numbers, and symbols you usually see."]}, {"cell_type": "markdown", "id": "b04c4073", "metadata": {}, "source": ["[Unicode](http://www.unicode.org/standard/WhatIsUnicode.html) is an ambitious standard that attempts to provide a numeric code for every possible character, in every possible language, on every possible platform. Python 3 supports Unicode extensively, including allowing Unicode characters within strings."]}, {"cell_type": "markdown", "id": "4de6aad9", "metadata": {}, "source": ["As long as you stay in the domain of the common characters, there is little practical difference between ASCII and Unicode. But the `ord()` function will return numeric values for [Unicode characters](https://realpython.com/courses/python-unicode/) as well:"]}, {"cell_type": "code", "execution_count": 127, "id": "0cd71268", "metadata": {}, "outputs": [{"data": {"text/plain": ["8364"]}, "execution_count": 127, "metadata": {}, "output_type": "execute_result"}], "source": ["ord('\u20ac')"]}, {"cell_type": "code", "execution_count": 128, "id": "c6b714d9", "metadata": {}, "outputs": [{"data": {"text/plain": ["8721"]}, "execution_count": 128, "metadata": {}, "output_type": "execute_result"}], "source": ["ord('\u2211')"]}, {"cell_type": "markdown", "id": "e408ba9e", "metadata": {}, "source": ["#### `chr(n)`\n", "\n", "> Returns a character value for the given integer."]}, {"cell_type": "markdown", "id": "334fa1cf", "metadata": {}, "source": ["`chr()` does the reverse of `ord()`. Given a numeric value `n`, `chr(n)` returns a string representing the character that corresponds to `n`:"]}, {"cell_type": "code", "execution_count": 133, "id": "ef2c4a45", "metadata": {}, "outputs": [{"data": {"text/plain": ["'a'"]}, "execution_count": 133, "metadata": {}, "output_type": "execute_result"}], "source": ["chr(97)"]}, {"cell_type": "code", "execution_count": 134, "id": "ada4d5f7", "metadata": {}, "outputs": [{"data": {"text/plain": ["'#'"]}, "execution_count": 134, "metadata": {}, "output_type": "execute_result"}], "source": ["chr(35)"]}, {"cell_type": "markdown", "id": "3f7c454d", "metadata": {}, "source": ["`chr()` handles Unicode characters as well:"]}, {"cell_type": "code", "execution_count": 135, "id": "d80a064b", "metadata": {}, "outputs": [{"data": {"text/plain": ["'\u20ac'"]}, "execution_count": 135, "metadata": {}, "output_type": "execute_result"}], "source": ["chr(8364)"]}, {"cell_type": "code", "execution_count": 136, "id": "80200ecb", "metadata": {}, "outputs": [{"data": {"text/plain": ["'\u2211'"]}, "execution_count": 136, "metadata": {}, "output_type": "execute_result"}], "source": ["chr(8721)"]}, {"cell_type": "markdown", "id": "eb12b3f4", "metadata": {}, "source": ["#### len(s)\n", "\n", "With `len()`, you can check Python string length. `len(s)` returns the number of characters in `s`:"]}, {"cell_type": "code", "execution_count": 28, "id": "37161877", "metadata": {}, "outputs": [{"data": {"text/plain": ["14"]}, "execution_count": 28, "metadata": {}, "output_type": "execute_result"}], "source": ["s = 'I am a string.'\n", "len(s)"]}, {"cell_type": "markdown", "id": "0cb9afd4", "metadata": {}, "source": ["#### `str(obj)`\n", "\n", "> Returns a string representation of an object."]}, {"cell_type": "code", "execution_count": 30, "id": "d2ba5dc5", "metadata": {}, "outputs": [{"data": {"text/plain": ["'2'"]}, "execution_count": 30, "metadata": {}, "output_type": "execute_result"}], "source": ["str(2)"]}, {"cell_type": "markdown", "id": "a45eae4a", "metadata": {}, "source": ["Virtually any object in Python can be rendered as a string. `str(obj)` returns the string representation of object obj:"]}, {"cell_type": "code", "execution_count": 24, "id": "8e7ba22f", "metadata": {}, "outputs": [{"data": {"text/plain": ["'49.2'"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["str(49.2)"]}, {"cell_type": "code", "execution_count": 25, "id": "f9d91ce6", "metadata": {}, "outputs": [{"data": {"text/plain": ["'(3+4j)'"]}, "execution_count": 25, "metadata": {}, "output_type": "execute_result"}], "source": ["str(3+4j)"]}, {"cell_type": "code", "execution_count": 26, "id": "427eb452", "metadata": {}, "outputs": [{"data": {"text/plain": ["'32'"]}, "execution_count": 26, "metadata": {}, "output_type": "execute_result"}], "source": ["str(3 + 29)"]}, {"cell_type": "code", "execution_count": 146, "id": "7f80df9f", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 146, "metadata": {}, "output_type": "execute_result"}], "source": ["str('foo')"]}, {"cell_type": "markdown", "id": "0b114fd4", "metadata": {}, "source": ["", "\n", "## String Indexing\n", "\n", "Often in programming languages, individual items in an ordered set of data can be accessed directly using a numeric index or key value. This process is referred to as indexing."]}, {"cell_type": "markdown", "id": "d3318f34", "metadata": {}, "source": ["In Python, strings are ordered sequences of character data, and thus can be indexed in this way. Individual characters in a string can be accessed by specifying the string name followed by a number in square brackets (`[]`)."]}, {"cell_type": "markdown", "id": "62417aa5", "metadata": {}, "source": ["String indexing in Python is zero-based: the first character in the string has index 0, the next has index 1, and so on. The index of the last character will be the length of the string minus one."]}, {"cell_type": "markdown", "id": "8572a66d", "metadata": {}, "source": ["For example, a schematic diagram of the indices of the string 'foobar' would look like this:"]}, {"cell_type": "markdown", "id": "19f6db4d", "metadata": {}, "source": ["\"string"]}, {"cell_type": "markdown", "id": "0a8f26d4", "metadata": {}, "source": ["The individual characters can be accessed by index as follows:"]}, {"cell_type": "code", "execution_count": 28, "id": "eaf4fef3", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 29, "id": "dbd0ce02", "metadata": {}, "outputs": [{"data": {"text/plain": ["'f'"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["s[0]"]}, {"cell_type": "code", "execution_count": 30, "id": "c62afc05", "metadata": {}, "outputs": [{"data": {"text/plain": ["'o'"]}, "execution_count": 30, "metadata": {}, "output_type": "execute_result"}], "source": ["s[1]"]}, {"cell_type": "code", "execution_count": 31, "id": "fb34188f", "metadata": {}, "outputs": [{"data": {"text/plain": ["'b'"]}, "execution_count": 31, "metadata": {}, "output_type": "execute_result"}], "source": ["s[3]"]}, {"cell_type": "code", "execution_count": 32, "id": "67c96720", "metadata": {}, "outputs": [{"data": {"text/plain": ["6"]}, "execution_count": 32, "metadata": {}, "output_type": "execute_result"}], "source": ["len(s)"]}, {"cell_type": "code", "execution_count": 33, "id": "964f4c3d", "metadata": {}, "outputs": [{"data": {"text/plain": ["'r'"]}, "execution_count": 33, "metadata": {}, "output_type": "execute_result"}], "source": ["s[len(s)-1]"]}, {"cell_type": "markdown", "id": "d84b6e53", "metadata": {}, "source": ["Attempting to index beyond the end of the string results in an error:"]}, {"cell_type": "code", "execution_count": 65, "id": "29394047", "metadata": {}, "outputs": [{"ename": "IndexError", "evalue": "string index out of range", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mIndexError\u001b[0m: string index out of range"]}], "source": ["s[6]"]}, {"cell_type": "markdown", "id": "7c3045a1", "metadata": {}, "source": ["String indices can also be specified with negative numbers, in which case indexing occurs from the end of the string backward: `-1` refers to the last character, `-2` the second-to-last character, and so on. Here is the same diagram showing both the positive and negative indices into the string `'foobar'`:\n", "\n", "\"negative"]}, {"cell_type": "markdown", "id": "fa634d72", "metadata": {}, "source": ["Here are some examples of negative indexing:"]}, {"cell_type": "code", "execution_count": 36, "id": "b926b461", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 37, "id": "0dad316d", "metadata": {}, "outputs": [{"data": {"text/plain": ["'r'"]}, "execution_count": 37, "metadata": {}, "output_type": "execute_result"}], "source": ["s[-1]"]}, {"cell_type": "code", "execution_count": 38, "id": "a0fc50e7", "metadata": {}, "outputs": [{"data": {"text/plain": ["'a'"]}, "execution_count": 38, "metadata": {}, "output_type": "execute_result"}], "source": ["s[-2]"]}, {"cell_type": "code", "execution_count": 39, "id": "e33e707a", "metadata": {}, "outputs": [{"data": {"text/plain": ["6"]}, "execution_count": 39, "metadata": {}, "output_type": "execute_result"}], "source": ["len(s)"]}, {"cell_type": "code", "execution_count": 40, "id": "4e774bd8", "metadata": {}, "outputs": [{"data": {"text/plain": ["'f'"]}, "execution_count": 40, "metadata": {}, "output_type": "execute_result"}], "source": ["s[-len(s)]"]}, {"cell_type": "markdown", "id": "e88d687d", "metadata": {}, "source": ["Attempting to index with negative numbers beyond the start of the string results in an error:"]}, {"cell_type": "code", "execution_count": 42, "id": "7b114e51", "metadata": {}, "outputs": [{"ename": "IndexError", "evalue": "string index out of range", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m7\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mIndexError\u001b[0m: string index out of range"]}], "source": ["s[-7]"]}, {"cell_type": "markdown", "id": "fe12ee7a", "metadata": {}, "source": ["For any non-empty string `s`, `s[len(s)-1]` and `s[-1]` both return the last character. There isn\u2019t any index that makes sense for an empty string."]}, {"cell_type": "markdown", "id": "1d844f12", "metadata": {}, "source": ["", "\n", "## String Slicing\n", "\n", "Python also allows a form of indexing syntax that extracts substrings from a string, known as string slicing. If `s` is a string, an expression of the form `s[m:n]` returns the portion of `s` starting with position `m`, and up to but not including position `n`:"]}, {"cell_type": "code", "execution_count": 43, "id": "dc1c8c8d", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 44, "id": "9caac50f", "metadata": {}, "outputs": [{"data": {"text/plain": ["'oba'"]}, "execution_count": 44, "metadata": {}, "output_type": "execute_result"}], "source": ["s[2:5]"]}, {"cell_type": "markdown", "id": "3c460a46", "metadata": {}, "source": ["> **Remember:** String indices are zero-based. The first character in a string has index `0`. This applies to both standard indexing and slicing."]}, {"cell_type": "markdown", "id": "6bc29431", "metadata": {}, "source": ["Again, the second index specifies the first character that is not included in the result\u2014the character `'r'` (`s[5]`) in the example above. That may seem slightly unintuitive, but it produces this result which makes sense: the expression `s[m:n]` will return a substring that is `n - m` characters in length, in this case, `5 - 2 = 3`."]}, {"cell_type": "markdown", "id": "3c19e834", "metadata": {}, "source": ["If you omit the first index, the slice starts at the beginning of the string. Thus, `s[:m]` and `s[0:m]` are equivalent:"]}, {"cell_type": "code", "execution_count": 45, "id": "65e54921", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 46, "id": "6a476644", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foob'"]}, "execution_count": 46, "metadata": {}, "output_type": "execute_result"}], "source": ["s[:4]"]}, {"cell_type": "code", "execution_count": 47, "id": "7ec12414", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foob'"]}, "execution_count": 47, "metadata": {}, "output_type": "execute_result"}], "source": ["s[0:4]"]}, {"cell_type": "markdown", "id": "4bb9b797", "metadata": {}, "source": ["Similarly, if you omit the second index as in `s[n:]`, the slice extends from the first index through the end of the string. This is a nice, concise alternative to the more cumbersome `s[n:len(s)]`:"]}, {"cell_type": "code", "execution_count": 48, "id": "72ef55f9", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 49, "id": "be68a664", "metadata": {}, "outputs": [{"data": {"text/plain": ["'obar'"]}, "execution_count": 49, "metadata": {}, "output_type": "execute_result"}], "source": ["s[2:]"]}, {"cell_type": "code", "execution_count": 50, "id": "a38390ee", "metadata": {}, "outputs": [{"data": {"text/plain": ["'obar'"]}, "execution_count": 50, "metadata": {}, "output_type": "execute_result"}], "source": ["s[2:len(s)]"]}, {"cell_type": "markdown", "id": "e02f081a", "metadata": {}, "source": ["For any string `s` and any integer `n` (`0 \u2264 n \u2264 len(s)`), `s[:n]` + `s[n:]` will be equal to `s`:"]}, {"cell_type": "code", "execution_count": 51, "id": "c783d1ba", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 52, "id": "3a8bda17", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foobar'"]}, "execution_count": 52, "metadata": {}, "output_type": "execute_result"}], "source": ["s[:4] + s[4:]"]}, {"cell_type": "code", "execution_count": 53, "id": "4287977f", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 53, "metadata": {}, "output_type": "execute_result"}], "source": ["s[:4] + s[4:] == s"]}, {"cell_type": "markdown", "id": "3d1c6c3b", "metadata": {}, "source": ["Omitting both indices returns the original string, in its entirety. Literally. It\u2019s not a copy, it\u2019s a reference to the original string:"]}, {"cell_type": "code", "execution_count": 139, "id": "99526ddd", "metadata": {}, "outputs": [], "source": ["s = 'foobar'\n", "t = s[:]"]}, {"cell_type": "code", "execution_count": 140, "id": "5935f149", "metadata": {}, "outputs": [{"data": {"text/plain": ["140343766368944"]}, "execution_count": 140, "metadata": {}, "output_type": "execute_result"}], "source": ["id(s)"]}, {"cell_type": "code", "execution_count": 141, "id": "9f89d290", "metadata": {}, "outputs": [{"data": {"text/plain": ["140343766368944"]}, "execution_count": 141, "metadata": {}, "output_type": "execute_result"}], "source": ["id(t)"]}, {"cell_type": "code", "execution_count": 122, "id": "f6b7252c", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 122, "metadata": {}, "output_type": "execute_result"}], "source": ["s is t"]}, {"cell_type": "markdown", "id": "1e2b086f", "metadata": {}, "source": ["If the first index in a slice is greater than or equal to the second index, Python returns an empty string. This is yet another obfuscated way to generate an empty string, in case you were looking for one:"]}, {"cell_type": "code", "execution_count": 123, "id": "2bd7e4d5", "metadata": {}, "outputs": [{"data": {"text/plain": ["''"]}, "execution_count": 123, "metadata": {}, "output_type": "execute_result"}], "source": ["s[2:2]"]}, {"cell_type": "code", "execution_count": 124, "id": "416cac6b", "metadata": {}, "outputs": [{"data": {"text/plain": ["''"]}, "execution_count": 124, "metadata": {}, "output_type": "execute_result"}], "source": ["s[4:2]"]}, {"cell_type": "markdown", "id": "a4cfee25", "metadata": {}, "source": ["Negative indices can be used with slicing as well. `-1` refers to the last character, `-2` the second-to-last, and so on, just as with simple indexing. The diagram below shows how to slice the substring `'oob'` from the string `'foobar'` using both positive and negative indices:"]}, {"cell_type": "markdown", "id": "e6534e11", "metadata": {}, "source": ["\"negative"]}, {"cell_type": "markdown", "id": "a5f795f0", "metadata": {}, "source": ["Here is the corresponding Python code:"]}, {"cell_type": "code", "execution_count": 97, "id": "ed873371", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 98, "id": "8bada5f2", "metadata": {}, "outputs": [{"data": {"text/plain": ["'oob'"]}, "execution_count": 98, "metadata": {}, "output_type": "execute_result"}], "source": ["s[-5:-2]"]}, {"cell_type": "code", "execution_count": 99, "id": "bc825852", "metadata": {}, "outputs": [{"data": {"text/plain": ["'oob'"]}, "execution_count": 99, "metadata": {}, "output_type": "execute_result"}], "source": ["s[1:4]"]}, {"cell_type": "code", "execution_count": 100, "id": "da0b7858", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 100, "metadata": {}, "output_type": "execute_result"}], "source": ["s[-5:-2] == s[1:4]"]}, {"cell_type": "markdown", "id": "5d217458", "metadata": {}, "source": ["", "\n", "### Specifying a Stride in a String Slice\n", "\n", "There is one more variant of the slicing syntax to discuss. Adding an additional : and a third index designates a stride (also called a step), which indicates how many characters to jump after retrieving each character in the slice."]}, {"cell_type": "markdown", "id": "131003a6", "metadata": {}, "source": ["For example, for the string `'foobar'`, the slice `0:6:2` starts with the first character and ends with the last character (the whole string), and every second character is skipped. This is shown in the following diagram:"]}, {"cell_type": "markdown", "id": "5d1f9376", "metadata": {}, "source": ["\"negative"]}, {"cell_type": "markdown", "id": "cc84ca16", "metadata": {}, "source": ["Similarly, `1:6:2` specifies a slice starting with the second character (index 1) and ending with the last character, and again the stride value 2 causes every other character to be skipped:"]}, {"cell_type": "markdown", "id": "74269e50", "metadata": {}, "source": ["\"negative"]}, {"cell_type": "markdown", "id": "5a71519e", "metadata": {}, "source": ["The illustrative REPL code is shown here:"]}, {"cell_type": "code", "execution_count": 3, "id": "d081aefb", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 4, "id": "fac11ecc", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foa'"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["s[0:6:2]"]}, {"cell_type": "code", "execution_count": 150, "id": "511dfc17", "metadata": {}, "outputs": [{"data": {"text/plain": ["'obr'"]}, "execution_count": 150, "metadata": {}, "output_type": "execute_result"}], "source": ["s[1:6:2]"]}, {"cell_type": "markdown", "id": "8eb3fb70", "metadata": {}, "source": ["As with any slicing, the first and second indices can be omitted, and default to the first and last characters respectively:"]}, {"cell_type": "code", "execution_count": 69, "id": "9d29edff", "metadata": {}, "outputs": [{"data": {"text/plain": ["'1234512345123451234512345'"]}, "execution_count": 69, "metadata": {}, "output_type": "execute_result"}], "source": ["s = '12345' * 5\n", "s"]}, {"cell_type": "code", "execution_count": 70, "id": "0ecd60d3", "metadata": {}, "outputs": [{"data": {"text/plain": ["'11111'"]}, "execution_count": 70, "metadata": {}, "output_type": "execute_result"}], "source": ["s[::5]"]}, {"cell_type": "code", "execution_count": 71, "id": "bf177775", "metadata": {}, "outputs": [{"data": {"text/plain": ["'55555'"]}, "execution_count": 71, "metadata": {}, "output_type": "execute_result"}], "source": ["s[4::5]"]}, {"cell_type": "markdown", "id": "8840ec22", "metadata": {}, "source": ["You can specify a negative stride value as well, in which case Python steps backward through the string. In that case, the starting/first index should be greater than the ending/second index:"]}, {"cell_type": "code", "execution_count": 73, "id": "33b0d776", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 74, "id": "8369d371", "metadata": {}, "outputs": [{"data": {"text/plain": ["'rbo'"]}, "execution_count": 74, "metadata": {}, "output_type": "execute_result"}], "source": ["s[5:0:-2]"]}, {"cell_type": "markdown", "id": "29eb0e9c", "metadata": {}, "source": ["In the above example, `5:0:-2` means \u201cstart at the last character and step backward by 2, up to but not including the first character.\u201d"]}, {"cell_type": "markdown", "id": "f4881569", "metadata": {}, "source": ["When you are stepping backward, if the first and second indices are omitted, the defaults are reversed in an intuitive way: the first index defaults to the end of the string, and the second index defaults to the beginning. Here is an example:"]}, {"cell_type": "code", "execution_count": 79, "id": "2695ac21", "metadata": {}, "outputs": [{"data": {"text/plain": ["'1234512345123451234512345'"]}, "execution_count": 79, "metadata": {}, "output_type": "execute_result"}], "source": ["s = '12345' * 5\n", "s"]}, {"cell_type": "code", "execution_count": 80, "id": "c61e970d", "metadata": {}, "outputs": [{"data": {"text/plain": ["'55555'"]}, "execution_count": 80, "metadata": {}, "output_type": "execute_result"}], "source": ["s[::-5]"]}, {"cell_type": "markdown", "id": "a693b6e0", "metadata": {}, "source": ["This is a common paradigm for reversing a string:"]}, {"cell_type": "code", "execution_count": 81, "id": "60613308", "metadata": {}, "outputs": [{"data": {"text/plain": ["'.thgir eb tsum ti ,ti syas noelopaN edarmoC fI'"]}, "execution_count": 81, "metadata": {}, "output_type": "execute_result"}], "source": ["s = 'If Comrade Napoleon says it, it must be right.'\n", "s[::-1]"]}, {"cell_type": "markdown", "id": "79e56be3", "metadata": {}, "source": ["", "\n", "### Interpolating Variables Into a String\n", "\n", "In Python version 3.6, a new string formatting mechanism was introduced. This feature is formally named the Formatted String Literal, but is more usually referred to by its nickname **f-string**."]}, {"cell_type": "markdown", "id": "77adf220", "metadata": {}, "source": ["One simple feature of f-strings you can start using right away is variable interpolation. You can specify a variable name directly within an f-string literal, and Python will replace the name with the corresponding value."]}, {"cell_type": "markdown", "id": "38ca79f3", "metadata": {}, "source": ["For example, suppose you want to display the result of an arithmetic calculation. You can do this with a straightforward `print()` statement, separating numeric values and string literals by commas:"]}, {"cell_type": "code", "execution_count": 173, "id": "4ef35286", "metadata": {}, "outputs": [], "source": ["n = 20\n", "m = 25\n", "prod = n * m"]}, {"cell_type": "code", "execution_count": 174, "id": "0e7c2ac3", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["The product of 20 and 25 is 500\n"]}], "source": ["print('The product of', n, 'and', m, 'is', prod)"]}, {"cell_type": "markdown", "id": "b9400efe", "metadata": {}, "source": ["But this is cumbersome. To accomplish the same thing using an f-string:\n", "\n", "- Specify either a lowercase `f` or uppercase `F` directly before the opening quote of the string literal. This tells Python it is an f-string instead of a standard string.\n", "- Specify any variables to be interpolated in curly braces (`{}`)."]}, {"cell_type": "markdown", "id": "a300882d", "metadata": {}, "source": ["Recast using an f-string, the above example looks much cleaner:"]}, {"cell_type": "code", "execution_count": 182, "id": "1476ff7f", "metadata": {}, "outputs": [], "source": ["n = 20\n", "m = 25\n", "prod = n * m"]}, {"cell_type": "code", "execution_count": 181, "id": "8981e5fd", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["The product of 20.293742397423973 and 25 is 507.34355993559933\n"]}], "source": ["print(f'The product of {n} and {m} is {prod}')"]}, {"cell_type": "markdown", "id": "2a58dedc", "metadata": {}, "source": ["Any of Python\u2019s three quoting mechanisms can be used to define an f-string:"]}, {"cell_type": "code", "execution_count": 131, "id": "a622099d", "metadata": {}, "outputs": [], "source": ["var = 'Bark'"]}, {"cell_type": "code", "execution_count": 132, "id": "a6b78d81", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["A dog says Bark!\n"]}], "source": ["print(f'A dog says {var}!')"]}, {"cell_type": "code", "execution_count": 133, "id": "85026c41", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["A dog says Bark!\n"]}], "source": ["print(f\"A dog says {var}!\")"]}, {"cell_type": "code", "execution_count": 134, "id": "086a85df", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["A dog says Bark!\n"]}], "source": ["print(f'''A dog says {var}!''')"]}, {"cell_type": "markdown", "id": "ddd555bf", "metadata": {}, "source": ["", "\n", "### Modifying Strings\n", "\n", "In a nutshell, you can\u2019t. Strings are one of the data types Python considers immutable, meaning not able to be changed. In fact, all the data types you have seen so far are immutable. (Python does provide data types that are mutable, as you will soon see.)"]}, {"cell_type": "markdown", "id": "b4be2765", "metadata": {}, "source": ["A statement like this will cause an error:"]}, {"cell_type": "code", "execution_count": 191, "id": "9f475df5", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 193, "id": "3df90174", "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'str' object does not support item assignment", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'x'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment"]}], "source": ["s[3] = 'x'"]}, {"cell_type": "markdown", "id": "857cda55", "metadata": {}, "source": ["In truth, there really isn\u2019t much need to modify strings. You can usually easily accomplish what you want by generating a copy of the original string that has the desired change in place. There are very many ways to do this in Python. Here is one possibility:"]}, {"cell_type": "code", "execution_count": 93, "id": "066fbc51", "metadata": {}, "outputs": [], "source": ["s = s[:3] + 'x' + s[4:]"]}, {"cell_type": "code", "execution_count": 94, "id": "78dd04d6", "metadata": {}, "outputs": [{"data": {"text/plain": ["'fooxar'"]}, "execution_count": 94, "metadata": {}, "output_type": "execute_result"}], "source": ["s"]}, {"cell_type": "markdown", "id": "2b2f1422", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "This tutorial provided an in-depth look at the many different mechanisms Python provides for string handling, including string operators, built-in functions, indexing, slicing, and built-in methods. You also were introduced to the bytes and bytearray types."]}, {"cell_type": "markdown", "id": "04c7a670", "metadata": {}, "source": ["These types are the first types you have examined that are composite\u2014built from a collection of smaller parts. Python provides several composite built-in types. In the next tutorial, you will explore two of the most frequently used: `lists` and `tuples`."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb b/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb index 9a0251f..043a545 100755 --- a/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb +++ b/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb @@ -1,4188 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "5731f133", - "metadata": {}, - "source": [ - "# Lists and Tuples in Python\n", - "\n", - "Lists and tuples are arguably Python’s most versatile, useful data types. You will find them in virtually every nontrivial Python program.\n", - "\n", - "* [Python Lists](#lists)\n", - "* [Python Tuples](#tuples)" - ] - }, - { - "cell_type": "markdown", - "id": "f28d785b", - "metadata": {}, - "source": [ - "\n", - "## Python Lists\n", - "In short, a list is a collection of arbitrary objects, somewhat akin to an array in many other programming languages but more flexible. Lists are defined in Python by enclosing a comma-separated sequence of objects in square brackets (`[]`), as shown below:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "224fa3d1", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux']" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "944b8e8e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux']" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "9a664dba", - "metadata": {}, - "source": [ - "The important characteristics of Python lists are as follows:\n", - "\n", - "- Lists are ordered.\n", - "- Lists can contain any arbitrary objects.\n", - "- List elements can be accessed by index.\n", - "- Lists can be nested to arbitrary depth.\n", - "- Lists are mutable.\n", - "- Lists are dynamic.\n", - "\n", - "Each of these features is examined in more detail below." - ] - }, - { - "cell_type": "markdown", - "id": "8fcc63ff", - "metadata": {}, - "source": [ - "### 1. Lists Are Ordered\n", - "\n", - "A list is not merely a collection of objects. It is an ordered collection of objects. The order in which you specify the elements when you define a list is an innate characteristic of that list and is maintained for that list’s lifetime. (You will see a Python data type that is not ordered in the next tutorial on dictionaries.)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "53905c3b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "False\n" - ] - } - ], - "source": [ - "x = [1, 2, 3]\n", - "y = [3, 2, 1]\n", - "\n", - "print(x == y)\n", - "print(x is y)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "f39383c3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n", - "False\n" - ] - } - ], - "source": [ - "x = [1, 2, 3]\n", - "y = [1, 2, 3]\n", - "\n", - "print(x == y)\n", - "print(x is y)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "781d0d7f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n", - "True\n" - ] - } - ], - "source": [ - "x = [1, 2, 3]\n", - "y = x\n", - "\n", - "print(x == y)\n", - "print(x is y)" - ] - }, - { - "cell_type": "markdown", - "id": "edef844e", - "metadata": {}, - "source": [ - "Lists that have the same elements in a different order are not the same:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "72304bd7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux']\n", - "b = ['baz', 'qux', 'bar', 'foo']\n", - "a == b" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "3260c4af", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a is b" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "e15600e5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[1, 2, 3, 4] == [4, 1, 3, 2]" - ] - }, - { - "cell_type": "markdown", - "id": "0730d1ba", - "metadata": {}, - "source": [ - "### 2. Lists Can Contain Arbitrary Objects\n", - "\n", - "A list can contain any assortment of objects. The elements of a list can all be the same type:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "ecb1aea3", - "metadata": {}, - "outputs": [], - "source": [ - "a = [2, 4, 6, 8]" - ] - }, - { - "cell_type": "markdown", - "id": "b649d22a", - "metadata": {}, - "source": [ - "Or the elements can be of varying types:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "bc2d44ac", - "metadata": {}, - "outputs": [], - "source": [ - "a = [21.42, 'foobar', 3, 4, 'bark', False, 3.14159]" - ] - }, - { - "cell_type": "markdown", - "id": "c3dea005", - "metadata": {}, - "source": [ - "Lists can even contain complex objects, like functions, classes, and modules, which you will learn about in upcoming sections:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "163b0ecc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "int" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "e60eef24", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "0aff05d4", - "metadata": {}, - "outputs": [], - "source": [ - "def foo():\n", - " pass" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "3cea8915", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "foo" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "4eb83630", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import math\n", - "math" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "3e5e59ca", - "metadata": {}, - "outputs": [], - "source": [ - "a = [int, len, foo, math]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "128d97e1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[int,\n", - " ,\n", - " ,\n", - " ]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "778f7f8e", - "metadata": {}, - "source": [ - "A list can contain any number of objects, from zero to as many as your computer’s memory will allow:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "084b9669", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = []\n", - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "8f6f663e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo']" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = [ 'foo' ]\n", - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "afd84114", - "metadata": {}, - "outputs": [], - "source": [ - "a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n", - "21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n", - "41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n", - "61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n", - "81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]" - ] - }, - { - "cell_type": "markdown", - "id": "fbd823f5", - "metadata": {}, - "source": [ - "> A list with a single object is sometimes referred to as a singleton list." - ] - }, - { - "cell_type": "markdown", - "id": "83ed1c59", - "metadata": {}, - "source": [ - "List objects needn’t be unique. A given object can appear in a list multiple times:\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "1e372e7d", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']" - ] - }, - { - "cell_type": "markdown", - "id": "f363f673", - "metadata": {}, - "source": [ - "### 3. List Elements Can Be Accessed by Index\n", - "\n", - "Individual elements in a list can be accessed using an index in square brackets. This is exactly analogous to accessing individual characters in a string. List indexing is zero-based as it is with strings." - ] - }, - { - "cell_type": "markdown", - "id": "75516647", - "metadata": {}, - "source": [ - "Consider the following list:" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "1238b74b", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "markdown", - "id": "68b1c05e", - "metadata": {}, - "source": [ - "The indices for the elements in a are shown below:" - ] - }, - { - "cell_type": "markdown", - "id": "76be95f6", - "metadata": {}, - "source": [ - "\"string" - ] - }, - { - "cell_type": "markdown", - "id": "daa07526", - "metadata": {}, - "source": [ - "Here is Python code to access some elements of a:" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "448bffb0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "ca66f33a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'baz'" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "id": "ce6610ee", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'corge'" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[5]" - ] - }, - { - "cell_type": "markdown", - "id": "5806ee80", - "metadata": {}, - "source": [ - "Virtually everything about string indexing works similarly for lists. For example, a negative list index counts from the end of the list:" - ] - }, - { - "cell_type": "markdown", - "id": "f4e80df9", - "metadata": {}, - "source": [ - "\"string" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "f471f429", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'corge'" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "d71d5047", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'quux'" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[-2]" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "9a9c8dc6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[-5]" - ] - }, - { - "cell_type": "markdown", - "id": "24e25038", - "metadata": {}, - "source": [ - "Slicing also works. If a is a list, the expression `a[m:n]` returns the portion of a from index `m` to, but not including, index `n`:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "2470be05", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "ec76a7a8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['baz', 'qux', 'quux']" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[2:5]" - ] - }, - { - "cell_type": "markdown", - "id": "92e8b2b7", - "metadata": {}, - "source": [ - "Other features of string slicing work analogously for list slicing as well:\n", - "\n", - "- Both positive and negative indices can be specified:" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "186bff88", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bar', 'baz', 'qux']" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[-5:-2]" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "2be72101", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bar', 'baz', 'qux']" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[1:4]" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "3271375e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[-5:-2] == a[1:4]" - ] - }, - { - "cell_type": "markdown", - "id": "e4ec255c", - "metadata": {}, - "source": [ - "- Omitting the first index starts the slice at the beginning of the list, and omitting the second index extends the slice to the end of the list:" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "f0245a1e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "([], [])" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[:4], a[0:4]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "be388ba4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(['baz', 'qux', 'quux', 'corge'], ['baz', 'qux', 'quux', 'corge'])" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[2:], a[2:len(a)]" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "ca046fc9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[:4] + a[4:]" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "49b8dc08", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[:4] + a[4:] == a" - ] - }, - { - "cell_type": "markdown", - "id": "6e2815b6", - "metadata": {}, - "source": [ - "- You can specify a stride—either positive or negative:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "29c7bfe1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'baz', 'quux']" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[0:6:2]" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "079d8938", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bar', 'qux', 'corge']" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[1:6:2]" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "b9dbfed7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['corge', 'qux', 'bar']" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[6:0:-2]" - ] - }, - { - "cell_type": "markdown", - "id": "bb2d086b", - "metadata": {}, - "source": [ - "- The syntax for reversing a list works the same way it does for strings:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "ea5539a8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['corge', 'quux', 'qux', 'baz', 'bar', 'foo']" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[::-1]" - ] - }, - { - "cell_type": "markdown", - "id": "2a2024a9", - "metadata": {}, - "source": [ - "The `[:]` syntax works for lists. However, there is an important difference between how this operation works with a list and how it works with a string." - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "67e73393", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobar'" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "730ff483", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foobar'" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[:]" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "5e2ab6a8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s[:] is s" - ] - }, - { - "cell_type": "markdown", - "id": "f00040e0", - "metadata": {}, - "source": [ - "Conversely, if a is a list, `a[:]` returns a new object that is a copy of `a`:" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "f80028f3", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "cb40d715", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[:]" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "e3bf2d76", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[:] is a" - ] - }, - { - "cell_type": "markdown", - "id": "fcf87db3", - "metadata": {}, - "source": [ - "Several Python operators and built-in functions can also be used with lists in ways that are analogous to strings:" - ] - }, - { - "cell_type": "markdown", - "id": "bfbe8474", - "metadata": {}, - "source": [ - "- The `in` and `not in` operators:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "5d0cc53f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'qux' in a" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "5175dcf1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'thud' not in a" - ] - }, - { - "cell_type": "markdown", - "id": "baa92b09", - "metadata": {}, - "source": [ - "- The concatenation (`+`) and replication (`*`) operators:" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "da5445ce", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "8f052203", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a + ['grault', 'garply']" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "e975dda3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo',\n", - " 'bar',\n", - " 'baz',\n", - " 'qux',\n", - " 'quux',\n", - " 'corge',\n", - " 'foo',\n", - " 'bar',\n", - " 'baz',\n", - " 'qux',\n", - " 'quux',\n", - " 'corge']" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a * 2" - ] - }, - { - "cell_type": "markdown", - "id": "477f6546", - "metadata": {}, - "source": [ - "- The `len()`, `min()`, and `max(`) functions:" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "8f61ce86", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "19230651", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "a1465ad4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "min(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "73689bec", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'qux'" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(a)" - ] - }, - { - "cell_type": "markdown", - "id": "5bd17e5b", - "metadata": {}, - "source": [ - "It’s not an accident that strings and lists behave so similarly. They are both special cases of a more general object type called an iterable, which you will encounter in more detail in the upcoming tutorial on definite iteration." - ] - }, - { - "cell_type": "markdown", - "id": "5024671e", - "metadata": {}, - "source": [ - "By the way, in each example above, the list is always assigned to a variable before an operation is performed on it. But you can operate on a list literal as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "2e58770c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'baz'" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][2]" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "349a8106", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['corge', 'quux', 'qux', 'baz', 'bar', 'foo']" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "id": "6f28b0fd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'quux' in ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "2224aa12", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "['foo', 'bar', 'baz'] + ['qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "id": "097e60a7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1])" - ] - }, - { - "cell_type": "markdown", - "id": "0661e9b1", - "metadata": {}, - "source": [ - "For that matter, you can do likewise with a string literal:" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "id": "bf6c14f6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'.thgir eb tsum ti ,ti syas noelopaN edarmoC fI'" - ] - }, - "execution_count": 124, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'If Comrade Napoleon says it, it must be right.'[::-1]" - ] - }, - { - "cell_type": "markdown", - "id": "825e5a91", - "metadata": {}, - "source": [ - "### 4. Lists Can Be Nested\n", - "\n", - "You have seen that an element in a list can be any sort of object. That includes another list. A list can contain sublists, which in turn can contain sublists themselves, and so on to arbitrary depth." - ] - }, - { - "cell_type": "markdown", - "id": "f2c80983", - "metadata": {}, - "source": [ - "Consider this (admittedly contrived) example:" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "509d8e21", - "metadata": {}, - "outputs": [], - "source": [ - "x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']" - ] - }, - { - "cell_type": "markdown", - "id": "ff778fc9", - "metadata": {}, - "source": [ - "The object structure that x references is diagrammed below:" - ] - }, - { - "cell_type": "markdown", - "id": "7b681953", - "metadata": {}, - "source": [ - "\"nested" - ] - }, - { - "cell_type": "markdown", - "id": "cf3b3523", - "metadata": {}, - "source": [ - "`x[0]`, `x[2]`, and `x[4]` are strings, each one character long:" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "f7d30716", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('a', 'g', 'j')" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[0], x[2], x[4]" - ] - }, - { - "cell_type": "markdown", - "id": "faa8b1de", - "metadata": {}, - "source": [ - "But `x[1]` and `x[3]` are sublists:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "bd2afbad", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bb', ['ccc', 'ddd'], 'ee', 'ff']" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "id": "9b0bbf8d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['hh', 'ii']" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[3]" - ] - }, - { - "cell_type": "markdown", - "id": "14b8a84b", - "metadata": {}, - "source": [ - "To access the items in a sublist, simply append an additional index:" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "e539e131", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bb', ['ccc', 'ddd'], 'ee', 'ff']" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "7ffdb3b7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bb'" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][0]" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "id": "3189540d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['ccc', 'ddd']" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][1]" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "a22d1a11", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ee'" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][2]" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "id": "61b051cf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ff'" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][3]" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "id": "008ef48d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['hh', 'ii']" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[3]" - ] - }, - { - "cell_type": "markdown", - "id": "2e8c0f2d", - "metadata": {}, - "source": [ - "`x[1][1]` is yet another sublist, so adding one more index accesses its elements:" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "e21d0bfa", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['ccc', 'ddd']" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][1]" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "id": "1089635f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ccc'" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][1][0]" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "c4f7356c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ddd'" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][1][1]" - ] - }, - { - "cell_type": "markdown", - "id": "ba86c2fe", - "metadata": {}, - "source": [ - "There is no limit, short of the extent of your computer’s memory, to the depth or complexity with which lists can be nested in this way." - ] - }, - { - "cell_type": "markdown", - "id": "8eb1e152", - "metadata": {}, - "source": [ - "All the usual syntax regarding indices and slicing applies to sublists as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "67b5631b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ddd'" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][1][-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "4f9714c4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[['ccc', 'ddd'], 'ee']" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1][1:3]" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "81a1dd51", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['ii', 'hh']" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[3][::-1]" - ] - }, - { - "cell_type": "markdown", - "id": "54539219", - "metadata": {}, - "source": [ - "However, be aware that operators and functions apply to only the list at the level you specify and are not recursive. Consider what happens when you query the length of `x` using `len()`:" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "3e78a3f3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "9b4e8070", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "0d39cd2b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a'" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "id": "46a1e57f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bb', ['ccc', 'ddd'], 'ee', 'ff']" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "2bc7ba3b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'g'" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "e35f116f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['hh', 'ii']" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[3]" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "32578a6b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'j'" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[4]" - ] - }, - { - "cell_type": "markdown", - "id": "c1afc28b", - "metadata": {}, - "source": [ - "`x` has only five elements—three strings and two sublists. The individual elements in the sublists don’t count toward `x`’s length." - ] - }, - { - "cell_type": "markdown", - "id": "73e857bf", - "metadata": {}, - "source": [ - "You’d encounter a similar situation when using the in operator:" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "70d8feb6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'ddd' in x" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "4b79b4a8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'ddd' in x[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "0d691d61", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'ddd' in x[1][1]" - ] - }, - { - "cell_type": "markdown", - "id": "0f83d93c", - "metadata": {}, - "source": [ - "`'ddd'` is not one of the elements in `x` or `x[1]`. It is only directly an element in the sublist `x[1][1]`. An individual element in a sublist does not count as an element of the parent `list(s)`." - ] - }, - { - "cell_type": "markdown", - "id": "ea5e4006", - "metadata": {}, - "source": [ - "### 5. Lists Are Mutable\n", - "Most of the data types you have encountered so far have been atomic types. Integer or float objects, for example, are primitive units that can’t be further broken down. These types are immutable, meaning that they can’t be changed once they have been assigned. It doesn’t make much sense to think of changing the value of an integer. If you want a different integer, you just assign a different one." - ] - }, - { - "cell_type": "markdown", - "id": "2034dc7c", - "metadata": {}, - "source": [ - "By contrast, the string type is a composite type. Strings are reducible to smaller parts—the component characters. It might make sense to think of changing the characters in a string. But you can’t. In Python, strings are also immutable." - ] - }, - { - "cell_type": "markdown", - "id": "01e81a5a", - "metadata": {}, - "source": [ - "The list is the first mutable data type you have encountered. Once a list has been created, elements can be added, deleted, shifted, and moved around at will. Python provides a wide range of ways to modify lists." - ] - }, - { - "cell_type": "markdown", - "id": "4d6f90a7", - "metadata": {}, - "source": [ - "#### Modifying a Single List Value\n", - "A single value in a list can be replaced by indexing and simple assignment:" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "id": "cc6bb5c6", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "2e5c019a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 85, - "id": "82256a14", - "metadata": {}, - "outputs": [], - "source": [ - "a[2] = 10" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "id": "3375ed03", - "metadata": {}, - "outputs": [], - "source": [ - "a[-1] = 20" - ] - }, - { - "cell_type": "code", - "execution_count": 87, - "id": "67f42e68", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 10, 'qux', 'quux', 20]" - ] - }, - "execution_count": 87, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "72ccef34", - "metadata": {}, - "source": [ - "You may recall from the section on Strings and Character Data in Python that you can’t do this with a string:" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "5e0d7fcb", - "metadata": {}, - "outputs": [], - "source": [ - "s = 'foobarbaz'" - ] - }, - { - "cell_type": "code", - "execution_count": 90, - "id": "7b2952e4", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'str' object does not support item assignment", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'x'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" - ] - } - ], - "source": [ - "s[2] = 'x'" - ] - }, - { - "cell_type": "markdown", - "id": "2b911673", - "metadata": {}, - "source": [ - "A list item can be deleted with the `del` command:" - ] - }, - { - "cell_type": "code", - "execution_count": 92, - "id": "18d15d1f", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 93, - "id": "d8caa2b0", - "metadata": {}, - "outputs": [], - "source": [ - "del a[3]" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "id": "de0c5d08", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'quux', 'corge']" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "cbe55162", - "metadata": {}, - "source": [ - "#### Modifying Multiple List Values\n", - "\n", - "What if you want to change several contiguous elements in a list at one time? Python allows this with slice assignment, which has the following syntax:\n", - "\n", - "```python\n", - "a[m:n] = \n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "4a99e7fc", - "metadata": {}, - "source": [ - "Again, for the moment, think of an iterable as a list. This assignment replaces the specified slice of a with ``:" - ] - }, - { - "cell_type": "code", - "execution_count": 242, - "id": "74da295b", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 243, - "id": "5aae64b9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bar', 'baz', 'qux']" - ] - }, - "execution_count": 243, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[1:4]" - ] - }, - { - "cell_type": "code", - "execution_count": 244, - "id": "7ea4c9c2", - "metadata": {}, - "outputs": [], - "source": [ - "a[1:4] = [1.1, 2.2, 3.3, 4.4, 5.5]" - ] - }, - { - "cell_type": "code", - "execution_count": 245, - "id": "76994c62", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']" - ] - }, - "execution_count": 245, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 99, - "id": "b56fecb6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1.1, 2.2, 3.3, 4.4, 5.5]" - ] - }, - "execution_count": 99, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[1:6]" - ] - }, - { - "cell_type": "code", - "execution_count": 100, - "id": "aaf1a477", - "metadata": {}, - "outputs": [], - "source": [ - "a[1:6] = ['Bark!']" - ] - }, - { - "cell_type": "code", - "execution_count": 101, - "id": "b23cf51b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'Bark!', 'quux', 'corge']" - ] - }, - "execution_count": 101, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "1cbe3508", - "metadata": {}, - "source": [ - "The number of elements inserted need not be equal to the number replaced. Python just grows or shrinks the list as needed." - ] - }, - { - "cell_type": "markdown", - "id": "0f9fd23a", - "metadata": {}, - "source": [ - "You can insert multiple elements in place of a single element—just use a slice that denotes only one element:" - ] - }, - { - "cell_type": "code", - "execution_count": 102, - "id": "246ce51d", - "metadata": {}, - "outputs": [], - "source": [ - "a = [1, 2, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "id": "6b83bcc5", - "metadata": {}, - "outputs": [], - "source": [ - "a[1:2] = [2.1, 2.2, 2.3]" - ] - }, - { - "cell_type": "code", - "execution_count": 104, - "id": "f55f6bdd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 2.1, 2.2, 2.3, 3]" - ] - }, - "execution_count": 104, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "f49b0899", - "metadata": {}, - "source": [ - "Note that this is not the same as replacing the single element with a list:" - ] - }, - { - "cell_type": "code", - "execution_count": 106, - "id": "949ce113", - "metadata": {}, - "outputs": [], - "source": [ - "a = [1, 2, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": 107, - "id": "11c7f9f6", - "metadata": {}, - "outputs": [], - "source": [ - "a[1] = [2.1, 2.2, 2.3]" - ] - }, - { - "cell_type": "code", - "execution_count": 108, - "id": "8d58652b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, [2.1, 2.2, 2.3], 3]" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "5d73ed33", - "metadata": {}, - "source": [ - "You can also insert elements into a list without removing anything. Simply specify a slice of the form `[n:n]` (a zero-length slice) at the desired index:" - ] - }, - { - "cell_type": "code", - "execution_count": 109, - "id": "1a9c2a32", - "metadata": {}, - "outputs": [], - "source": [ - "a = [1, 2, 7, 8]" - ] - }, - { - "cell_type": "code", - "execution_count": 110, - "id": "d0626b56", - "metadata": {}, - "outputs": [], - "source": [ - "a[2:2] = [3, 4, 5, 6]" - ] - }, - { - "cell_type": "code", - "execution_count": 111, - "id": "4e7c3244", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 2, 3, 4, 5, 6, 7, 8]" - ] - }, - "execution_count": 111, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "8bba76d8", - "metadata": {}, - "source": [ - "You can delete multiple elements out of the middle of a list by assigning the appropriate slice to an empty list. You can also use the del statement with the same slice:" - ] - }, - { - "cell_type": "code", - "execution_count": 115, - "id": "7bcf5f1f", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 116, - "id": "99f2580f", - "metadata": {}, - "outputs": [], - "source": [ - "a[1:5] = []" - ] - }, - { - "cell_type": "code", - "execution_count": 117, - "id": "d047bbff", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'corge']" - ] - }, - "execution_count": 117, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "id": "6c54c55b", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 119, - "id": "9dfeb0e2", - "metadata": {}, - "outputs": [], - "source": [ - "del a[1:5]" - ] - }, - { - "cell_type": "code", - "execution_count": 246, - "id": "38b8462e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']" - ] - }, - "execution_count": 246, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "b7219cc5", - "metadata": {}, - "source": [ - "#### Prepending or Appending Items to a List\n", - "\n", - "Additional items can be added to the start or end of a list using the + concatenation operator or the `+=` augmented assignment operator:" - ] - }, - { - "cell_type": "code", - "execution_count": 121, - "id": "0d66853f", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 122, - "id": "43e20929", - "metadata": {}, - "outputs": [], - "source": [ - "a += ['grault', 'garply']" - ] - }, - { - "cell_type": "code", - "execution_count": 123, - "id": "15bde346", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']" - ] - }, - "execution_count": 123, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "id": "3a607bd9", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "id": "797c39bb", - "metadata": {}, - "outputs": [], - "source": [ - "a = [10, 20] + a" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "11c45a8b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[10, 20, 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "12bbfca7", - "metadata": {}, - "source": [ - "Note that a list must be concatenated with another list, so if you want to add only one element, you need to specify it as a singleton list:" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "id": "6169fab4", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'int' object is not iterable", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'qux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'quux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'corge'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable" - ] - } - ], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']\n", - "a += 20 " - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "id": "8168bcf0", - "metadata": {}, - "outputs": [], - "source": [ - "a += [20]" - ] - }, - { - "cell_type": "code", - "execution_count": 119, - "id": "53ec6cc3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']" - ] - }, - "execution_count": 119, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "c432ab55", - "metadata": {}, - "source": [ - "> **Note:** Technically, it isn’t quite correct to say a list must be concatenated with another list. More precisely, a list must be concatenated with an object that is iterable. Of course, lists are iterable, so it works to concatenate a list with another list.\n", - ">\n", - ">Strings are iterable also. But watch what happens when you concatenate a string onto a list:\n", - ">```python\n", - "a = ['foo', 'bar', 'baz', 'qux', 'quux']\n", - "a += 'corge'\n", - "a\n", - ">```\n", - ">This result is perhaps not quite what you expected. When a string is iterated through, the result is a list of its component characters. In the above example, what gets concatenated onto list a is a list of the characters in the string `'corge'`.\n", - ">\n", - ">If you really want to add just the single string 'corge' to the end of the list, you need to specify it as a singleton list:\n", - ">```python\n", - "a = ['foo', 'bar', 'baz', 'qux', 'quux']\n", - "a += ['corge']\n", - "a\n", - ">```\n", - "> If this seems mysterious, don’t fret too much. You’ll learn about the ins and outs of iterables in the tutorial on definite iteration." - ] - }, - { - "cell_type": "markdown", - "id": "3c679f5f", - "metadata": {}, - "source": [ - "### 6. Lists Are Dynamic\n", - "This tutorial began with a list of six defining characteristics of Python lists. The last one is that lists are dynamic. You have seen many examples of this in the sections above. When items are added to a list, it grows as needed:" - ] - }, - { - "cell_type": "code", - "execution_count": 135, - "id": "07222c9a", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 136, - "id": "90e7fd91", - "metadata": {}, - "outputs": [], - "source": [ - "a[2:2] = [1, 2, 3]" - ] - }, - { - "cell_type": "code", - "execution_count": 137, - "id": "c860669c", - "metadata": {}, - "outputs": [], - "source": [ - "a += [3.14159]" - ] - }, - { - "cell_type": "code", - "execution_count": 138, - "id": "59f45737", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 1, 2, 3, 'baz', 'qux', 'quux', 'corge', 3.14159]" - ] - }, - "execution_count": 138, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "efebeb5e", - "metadata": {}, - "source": [ - "Similarly, a list shrinks to accommodate the removal of items:" - ] - }, - { - "cell_type": "code", - "execution_count": 139, - "id": "9e8025f4", - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']" - ] - }, - { - "cell_type": "code", - "execution_count": 140, - "id": "1bfa206c", - "metadata": {}, - "outputs": [], - "source": [ - "a[2:3] = []" - ] - }, - { - "cell_type": "code", - "execution_count": 141, - "id": "bcb842d3", - "metadata": {}, - "outputs": [], - "source": [ - "del a[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 279, - "id": "c7f29cd7", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']" - ] - }, - "execution_count": 279, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "id": "779ebac7", - "metadata": {}, - "source": [ - "\n", - "## Python Tuples\n", - "\n", - "Python provides another type that is an ordered collection of objects, called a tuple." - ] - }, - { - "cell_type": "markdown", - "id": "9d19ee98", - "metadata": {}, - "source": [ - "### Defining and Using Tuples\n", - "Tuples are identical to lists in all respects, except for the following properties:\n", - "\n", - "- Tuples are defined by enclosing the elements in parentheses (`()`) instead of square brackets `[]`).\n", - "- Tuples are immutable." - ] - }, - { - "cell_type": "markdown", - "id": "58fc91ae", - "metadata": {}, - "source": [ - "Here is a short example showing a tuple definition, indexing, and slicing:" - ] - }, - { - "cell_type": "code", - "execution_count": 299, - "id": "8a21fd5f", - "metadata": {}, - "outputs": [], - "source": [ - "t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')" - ] - }, - { - "cell_type": "code", - "execution_count": 300, - "id": "4b5c124e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 'bar', 'baz', 'qux', 'quux', 'corge')" - ] - }, - "execution_count": 300, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t" - ] - }, - { - "cell_type": "code", - "execution_count": 301, - "id": "e7cd310e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 301, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 302, - "id": "b447fd42", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'corge'" - ] - }, - "execution_count": 302, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 303, - "id": "4a97577a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('bar', 'qux', 'corge')" - ] - }, - "execution_count": 303, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[1::2]" - ] - }, - { - "cell_type": "markdown", - "id": "aa9a0f3b", - "metadata": {}, - "source": [ - "Never fear! Our favorite string and list reversal mechanism works for tuples as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 304, - "id": "c0e9af40", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('corge', 'quux', 'qux', 'baz', 'bar', 'foo')" - ] - }, - "execution_count": 304, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[::-1]" - ] - }, - { - "cell_type": "markdown", - "id": "fdb1c32a", - "metadata": {}, - "source": [ - "> Note: Even though tuples are defined using parentheses, you still index and slice tuples using square brackets, just as for strings and lists." - ] - }, - { - "cell_type": "markdown", - "id": "ca8d5e75", - "metadata": {}, - "source": [ - "Everything you’ve learned about lists—they are ordered, they can contain arbitrary objects, they can be indexed and sliced, they can be nested—is true of tuples as well. But they can’t be modified:" - ] - }, - { - "cell_type": "code", - "execution_count": 305, - "id": "29c14a99", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'tuple' object does not support item assignment", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'qux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'quux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'corge'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'Bark!'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" - ] - } - ], - "source": [ - "t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')\n", - "t[2] = 'Bark!'" - ] - }, - { - "cell_type": "markdown", - "id": "d3c309c0", - "metadata": {}, - "source": [ - "Why use a tuple instead of a list?\n", - "\n", - "- Program execution is faster when manipulating a tuple than it is for the equivalent list. (This is probably not going to be noticeable when the list or tuple is small.)\n", - "\n", - "- Sometimes you don’t want data to be modified. If the values in the collection are meant to remain constant for the life of the program, using a tuple instead of a list guards against accidental modification.\n", - "\n", - "- There is another Python data type that you will encounter shortly called a dictionary, which requires as one of its components a value that is of an immutable type. A tuple can be used for this purpose, whereas a list can’t be." - ] - }, - { - "cell_type": "markdown", - "id": "77c610d9", - "metadata": {}, - "source": [ - "In a Python REPL session, you can display the values of several objects simultaneously by entering them directly at the `>>>` prompt, separated by commas:" - ] - }, - { - "cell_type": "code", - "execution_count": 150, - "id": "ab20cb42", - "metadata": {}, - "outputs": [], - "source": [ - "a = 'foo'" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "id": "33a267f4", - "metadata": {}, - "outputs": [], - "source": [ - "b = 42" - ] - }, - { - "cell_type": "code", - "execution_count": 152, - "id": "0ca51e51", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 3.14159, 42)" - ] - }, - "execution_count": 152, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a, 3.14159, b" - ] - }, - { - "cell_type": "markdown", - "id": "dca838bf", - "metadata": {}, - "source": [ - "Python displays the response in parentheses because it is implicitly interpreting the input as a tuple." - ] - }, - { - "cell_type": "markdown", - "id": "1a4ca1ce", - "metadata": {}, - "source": [ - "There is one peculiarity regarding tuple definition that you should be aware of. There is no ambiguity when defining an empty tuple, nor one with two or more elements. Python knows you are defining a tuple:" - ] - }, - { - "cell_type": "code", - "execution_count": 346, - "id": "71c13a4e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tuple" - ] - }, - "execution_count": 346, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = ()\n", - "type(t)" - ] - }, - { - "cell_type": "code", - "execution_count": 347, - "id": "9182eb81", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tuple" - ] - }, - "execution_count": 347, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = (1, 2)\n", - "type(t)" - ] - }, - { - "cell_type": "code", - "execution_count": 348, - "id": "0f792121", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tuple" - ] - }, - "execution_count": 348, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = (1, 2, 3, 4, 5)\n", - "type(t)" - ] - }, - { - "cell_type": "markdown", - "id": "94149463", - "metadata": {}, - "source": [ - "But what happens when you try to define a tuple with one item:" - ] - }, - { - "cell_type": "code", - "execution_count": 349, - "id": "482ddc41", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 349, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = (2)\n", - "type(t)" - ] - }, - { - "cell_type": "markdown", - "id": "278c54f2", - "metadata": {}, - "source": [ - "Doh! Since parentheses are also used to define operator precedence in expressions, Python evaluates the expression `(2)` as simply the integer `2` and creates an int object. To tell Python that you really want to define a singleton tuple, include a trailing comma `(,)` just before the closing parenthesis:" - ] - }, - { - "cell_type": "code", - "execution_count": 350, - "id": "978af638", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "tuple" - ] - }, - "execution_count": 350, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = (2,)\n", - "type(t)" - ] - }, - { - "cell_type": "code", - "execution_count": 351, - "id": "dc15be8f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 351, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 352, - "id": "221ed952", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 352, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[-1]" - ] - }, - { - "cell_type": "markdown", - "id": "e67604f3", - "metadata": {}, - "source": [ - "You probably won’t need to define a singleton tuple often, but there has to be a way." - ] - }, - { - "cell_type": "markdown", - "id": "f1c8e7d6", - "metadata": {}, - "source": [ - "When you display a singleton tuple, Python includes the comma, to remind you that it’s a tuple:" - ] - }, - { - "cell_type": "code", - "execution_count": 166, - "id": "fc8bc0fc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2,)" - ] - }, - "execution_count": 166, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t" - ] - }, - { - "cell_type": "markdown", - "id": "89dd7789", - "metadata": {}, - "source": [ - "### Tuple Assignment, Packing, and Unpacking\n", - "\n", - "As you have already seen above, a literal tuple containing several items can be assigned to a single object:" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "b4bdef2f", - "metadata": {}, - "outputs": [], - "source": [ - "t = ('foo', 'bar', 'baz', 'qux')" - ] - }, - { - "cell_type": "markdown", - "id": "303f6805", - "metadata": {}, - "source": [ - "\"tuple-packing\"" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "9db2d631", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 'bar', 'baz', 'qux')" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "7a298e62", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "8e9180a0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'qux'" - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t[-1]" - ] - }, - { - "cell_type": "markdown", - "id": "7d2ce889", - "metadata": {}, - "source": [ - "If that “packed” object is subsequently assigned to a new tuple, the individual items are “unpacked” into the objects in the tuple:" - ] - }, - { - "cell_type": "markdown", - "id": "2cf73f03", - "metadata": {}, - "source": [ - "\"tuple-unpacking\"" - ] - }, - { - "cell_type": "code", - "execution_count": 174, - "id": "022d4f57", - "metadata": {}, - "outputs": [], - "source": [ - "(s1, s2, s3, s4) = t" - ] - }, - { - "cell_type": "code", - "execution_count": 175, - "id": "bf059422", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 175, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1" - ] - }, - { - "cell_type": "code", - "execution_count": 176, - "id": "dd38c5cf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 176, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s2" - ] - }, - { - "cell_type": "code", - "execution_count": 177, - "id": "f1b61f04", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'baz'" - ] - }, - "execution_count": 177, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s3" - ] - }, - { - "cell_type": "code", - "execution_count": 178, - "id": "89c0d428", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'qux'" - ] - }, - "execution_count": 178, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s4" - ] - }, - { - "cell_type": "markdown", - "id": "b145cde5", - "metadata": {}, - "source": [ - "When unpacking, the number of variables on the left must match the number of values in the tuple:" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "daee90ca", - "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "too many values to unpack (expected 3)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0ms1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms3\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mValueError\u001b[0m: too many values to unpack (expected 3)" - ] - } - ], - "source": [ - "(s1, s2, s3) = t " - ] - }, - { - "cell_type": "code", - "execution_count": 192, - "id": "36b6bcb2", - "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "not enough values to unpack (expected 5, got 4)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0ms1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms5\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mValueError\u001b[0m: not enough values to unpack (expected 5, got 4)" - ] - } - ], - "source": [ - "(s1, s2, s3, s4, s5) = t" - ] - }, - { - "cell_type": "markdown", - "id": "7048d14f", - "metadata": {}, - "source": [ - "Packing and unpacking can be combined into one statement to make a compound assignment:" - ] - }, - { - "cell_type": "code", - "execution_count": 197, - "id": "ada847c3", - "metadata": {}, - "outputs": [], - "source": [ - "(s1, s2, s3, s4) = ('foo', 'bar', 'baz', 'qux')" - ] - }, - { - "cell_type": "code", - "execution_count": 198, - "id": "1c204276", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 198, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1" - ] - }, - { - "cell_type": "code", - "execution_count": 199, - "id": "4f181eb8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 199, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s2" - ] - }, - { - "cell_type": "code", - "execution_count": 200, - "id": "bb0bf08c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'baz'" - ] - }, - "execution_count": 200, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s3" - ] - }, - { - "cell_type": "code", - "execution_count": 201, - "id": "b0de32a6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'qux'" - ] - }, - "execution_count": 201, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s4" - ] - }, - { - "cell_type": "markdown", - "id": "bdc934c6", - "metadata": {}, - "source": [ - "Again, the number of elements in the tuple on the left of the assignment must equal the number on the right:" - ] - }, - { - "cell_type": "code", - "execution_count": 202, - "id": "1d1e42ef", - "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "not enough values to unpack (expected 5, got 4)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0ms1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms5\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'qux'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mValueError\u001b[0m: not enough values to unpack (expected 5, got 4)" - ] - } - ], - "source": [ - "(s1, s2, s3, s4, s5) = ('foo', 'bar', 'baz', 'qux')" - ] - }, - { - "cell_type": "markdown", - "id": "13931cbc", - "metadata": {}, - "source": [ - "In assignments like this and a small handful of other situations, Python allows the parentheses that are usually used for denoting a tuple to be left out:" - ] - }, - { - "cell_type": "code", - "execution_count": 203, - "id": "d301d74c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(1, 2, 3)" - ] - }, - "execution_count": 203, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = 1, 2, 3\n", - "t" - ] - }, - { - "cell_type": "code", - "execution_count": 204, - "id": "4eaf55b5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(1, 2, 3)" - ] - }, - "execution_count": 204, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x1, x2, x3 = t\n", - "x1, x2, x3" - ] - }, - { - "cell_type": "code", - "execution_count": 205, - "id": "4a2c32c5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(4, 5, 6)" - ] - }, - "execution_count": 205, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x1, x2, x3 = 4, 5, 6\n", - "x1, x2, x3" - ] - }, - { - "cell_type": "code", - "execution_count": 206, - "id": "ecdd33ca", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2,)" - ] - }, - "execution_count": 206, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "t = 2,\n", - "t" - ] - }, - { - "cell_type": "markdown", - "id": "0b5e39bb", - "metadata": {}, - "source": [ - "It works the same whether the parentheses are included or not, so if you have any doubt as to whether they’re needed, go ahead and include them." - ] - }, - { - "cell_type": "markdown", - "id": "27814877", - "metadata": {}, - "source": [ - "Tuple assignment allows for a curious bit of idiomatic Python. Frequently when programming, you have two variables whose values you need to swap. In most programming languages, it is necessary to store one of the values in a temporary variable while the swap occurs like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 207, - "id": "840beb6d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 'bar')" - ] - }, - "execution_count": 207, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = 'foo'\n", - "b = 'bar'\n", - "a, b" - ] - }, - { - "cell_type": "code", - "execution_count": 210, - "id": "94eda2d2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 'bar')" - ] - }, - "execution_count": 210, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "temp = a\n", - "a = b\n", - "b = temp\n", - "a, b" - ] - }, - { - "cell_type": "markdown", - "id": "717db98e", - "metadata": {}, - "source": [ - "In Python, the swap can be done with a single tuple assignment:" - ] - }, - { - "cell_type": "code", - "execution_count": 212, - "id": "46350be1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 'bar')" - ] - }, - "execution_count": 212, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = 'foo'\n", - "b = 'bar'\n", - "a, b" - ] - }, - { - "cell_type": "code", - "execution_count": 213, - "id": "d934380b", - "metadata": {}, - "outputs": [], - "source": [ - "a, b = b, a" - ] - }, - { - "cell_type": "code", - "execution_count": 214, - "id": "6f2c968e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('bar', 'foo')" - ] - }, - "execution_count": 214, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a, b" - ] - }, - { - "cell_type": "markdown", - "id": "ad4cb308", - "metadata": {}, - "source": [ - "As anyone who has ever had to swap values using a temporary variable knows, being able to do it this way in Python is the pinnacle of modern technological achievement. It will never get better than this." - ] - }, - { - "cell_type": "code", - "execution_count": 383, - "id": "16b352b7", - "metadata": {}, - "outputs": [], - "source": [ - "x = (1, 2, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": 384, - "id": "41ad8b4d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 384, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x[0]" - ] - }, - { - "cell_type": "markdown", - "id": "8756eecb", - "metadata": {}, - "source": [ - "## Conclusion\n", - "This tutorial covered the basic properties of Python **lists** and **tuples**, and how to manipulate them. You will use these extensively in your Python programming." - ] - }, - { - "cell_type": "markdown", - "id": "dcc73545", - "metadata": {}, - "source": [ - "One of the chief characteristics of a list is that it is ordered. The order of the elements in a list is an intrinsic property of that list and does not change, unless the list itself is modified. (The same is true of tuples, except of course they can’t be modified.)" - ] - }, - { - "cell_type": "markdown", - "id": "d19954dc", - "metadata": {}, - "source": [ - "The next tutorial will introduce you to the Python **dictionary**: a composite data type that is unordered. Read on!" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "5731f133", "metadata": {}, "source": ["# Lists and Tuples in Python"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Python Lists](#python_lists)\n * [1. Lists Are Ordered](#1._lists_are_ordered)\n * [2. Lists Can Contain Arbitrary Objects](#2._lists_can_contain_arbitrary_objects)\n * [3. List Elements Can Be Accessed by Index](#3._list_elements_can_be_accessed_by_index)\n * [4. Lists Can Be Nested](#4._lists_can_be_nested)\n * [5. Lists Are Mutable](#5._lists_are_mutable)\n * [6. Lists Are Dynamic](#6._lists_are_dynamic)\n* [Python Tuples](#python_tuples)\n * [Defining and Using Tuples](#defining_and_using_tuples)\n * [Tuple Assignment, Packing, and Unpacking](#tuple_assignment,_packing,_and_unpacking)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "id": "07aef569-cd5a-46a5-8a01-aa0bb9fa13fd", "metadata": {}, "source": ["Lists and tuples are arguably Python\u2019s most versatile, useful data types. You will find them in virtually every nontrivial Python program.\n", "\n", "* [Python Lists](#lists)\n", "* [Python Tuples](#tuples)"]}, {"cell_type": "markdown", "id": "f28d785b", "metadata": {}, "source": ["", "\n", "## Python Lists\n", "In short, a list is a collection of arbitrary objects, somewhat akin to an array in many other programming languages but more flexible. Lists are defined in Python by enclosing a comma-separated sequence of objects in square brackets (`[]`), as shown below:"]}, {"cell_type": "code", "execution_count": 3, "id": "224fa3d1", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux']"]}, {"cell_type": "code", "execution_count": 9, "id": "944b8e8e", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux']"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "9a664dba", "metadata": {}, "source": ["The important characteristics of Python lists are as follows:\n", "\n", "- Lists are ordered.\n", "- Lists can contain any arbitrary objects.\n", "- List elements can be accessed by index.\n", "- Lists can be nested to arbitrary depth.\n", "- Lists are mutable.\n", "- Lists are dynamic.\n", "\n", "Each of these features is examined in more detail below."]}, {"cell_type": "markdown", "id": "8fcc63ff", "metadata": {}, "source": ["", "\n", "### 1. Lists Are Ordered\n", "\n", "A list is not merely a collection of objects. It is an ordered collection of objects. The order in which you specify the elements when you define a list is an innate characteristic of that list and is maintained for that list\u2019s lifetime. (You will see a Python data type that is not ordered in the next tutorial on dictionaries.)"]}, {"cell_type": "code", "execution_count": 22, "id": "53905c3b", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["False\n", "False\n"]}], "source": ["x = [1, 2, 3]\n", "y = [3, 2, 1]\n", "\n", "print(x == y)\n", "print(x is y)"]}, {"cell_type": "code", "execution_count": 23, "id": "f39383c3", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["True\n", "False\n"]}], "source": ["x = [1, 2, 3]\n", "y = [1, 2, 3]\n", "\n", "print(x == y)\n", "print(x is y)"]}, {"cell_type": "code", "execution_count": 24, "id": "781d0d7f", "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["True\n", "True\n"]}], "source": ["x = [1, 2, 3]\n", "y = x\n", "\n", "print(x == y)\n", "print(x is y)"]}, {"cell_type": "markdown", "id": "edef844e", "metadata": {}, "source": ["Lists that have the same elements in a different order are not the same:"]}, {"cell_type": "code", "execution_count": 4, "id": "72304bd7", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["a = ['foo', 'bar', 'baz', 'qux']\n", "b = ['baz', 'qux', 'bar', 'foo']\n", "a == b"]}, {"cell_type": "code", "execution_count": 5, "id": "3260c4af", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["a is b"]}, {"cell_type": "code", "execution_count": 6, "id": "e15600e5", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["[1, 2, 3, 4] == [4, 1, 3, 2]"]}, {"cell_type": "markdown", "id": "0730d1ba", "metadata": {}, "source": ["", "\n", "### 2. Lists Can Contain Arbitrary Objects\n", "\n", "A list can contain any assortment of objects. The elements of a list can all be the same type:"]}, {"cell_type": "code", "execution_count": 7, "id": "ecb1aea3", "metadata": {}, "outputs": [], "source": ["a = [2, 4, 6, 8]"]}, {"cell_type": "markdown", "id": "b649d22a", "metadata": {}, "source": ["Or the elements can be of varying types:"]}, {"cell_type": "code", "execution_count": 9, "id": "bc2d44ac", "metadata": {}, "outputs": [], "source": ["a = [21.42, 'foobar', 3, 4, 'bark', False, 3.14159]"]}, {"cell_type": "markdown", "id": "c3dea005", "metadata": {}, "source": ["Lists can even contain complex objects, like functions, classes, and modules, which you will learn about in upcoming sections:"]}, {"cell_type": "code", "execution_count": 10, "id": "163b0ecc", "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["int"]}, {"cell_type": "code", "execution_count": 11, "id": "e60eef24", "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["len"]}, {"cell_type": "code", "execution_count": 12, "id": "0aff05d4", "metadata": {}, "outputs": [], "source": ["def foo():\n", " pass"]}, {"cell_type": "code", "execution_count": 13, "id": "3cea8915", "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["foo"]}, {"cell_type": "code", "execution_count": 14, "id": "4eb83630", "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["import math\n", "math"]}, {"cell_type": "code", "execution_count": 16, "id": "3e5e59ca", "metadata": {}, "outputs": [], "source": ["a = [int, len, foo, math]"]}, {"cell_type": "code", "execution_count": 17, "id": "128d97e1", "metadata": {}, "outputs": [{"data": {"text/plain": ["[int,\n", " ,\n", " ,\n", " ]"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "778f7f8e", "metadata": {}, "source": ["A list can contain any number of objects, from zero to as many as your computer\u2019s memory will allow:"]}, {"cell_type": "code", "execution_count": 18, "id": "084b9669", "metadata": {}, "outputs": [{"data": {"text/plain": ["[]"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["a = []\n", "a"]}, {"cell_type": "code", "execution_count": 19, "id": "8f6f663e", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo']"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["a = [ 'foo' ]\n", "a"]}, {"cell_type": "code", "execution_count": 21, "id": "afd84114", "metadata": {}, "outputs": [], "source": ["a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n", "21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n", "41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n", "61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n", "81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]"]}, {"cell_type": "markdown", "id": "fbd823f5", "metadata": {}, "source": ["> A list with a single object is sometimes referred to as a singleton list."]}, {"cell_type": "markdown", "id": "83ed1c59", "metadata": {}, "source": ["List objects needn\u2019t be unique. A given object can appear in a list multiple times:\n", "\n"]}, {"cell_type": "code", "execution_count": 42, "id": "1e372e7d", "metadata": {}, "outputs": [], "source": ["a = ['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']"]}, {"cell_type": "markdown", "id": "f363f673", "metadata": {}, "source": ["", "\n", "### 3. List Elements Can Be Accessed by Index\n", "\n", "Individual elements in a list can be accessed using an index in square brackets. This is exactly analogous to accessing individual characters in a string. List indexing is zero-based as it is with strings."]}, {"cell_type": "markdown", "id": "75516647", "metadata": {}, "source": ["Consider the following list:"]}, {"cell_type": "code", "execution_count": 43, "id": "1238b74b", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "markdown", "id": "68b1c05e", "metadata": {}, "source": ["The indices for the elements in a are shown below:"]}, {"cell_type": "markdown", "id": "76be95f6", "metadata": {}, "source": ["\"string"]}, {"cell_type": "markdown", "id": "daa07526", "metadata": {}, "source": ["Here is Python code to access some elements of a:"]}, {"cell_type": "code", "execution_count": 44, "id": "448bffb0", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 44, "metadata": {}, "output_type": "execute_result"}], "source": ["a[0]"]}, {"cell_type": "code", "execution_count": 45, "id": "ca66f33a", "metadata": {}, "outputs": [{"data": {"text/plain": ["'baz'"]}, "execution_count": 45, "metadata": {}, "output_type": "execute_result"}], "source": ["a[2]"]}, {"cell_type": "code", "execution_count": 46, "id": "ce6610ee", "metadata": {}, "outputs": [{"data": {"text/plain": ["'corge'"]}, "execution_count": 46, "metadata": {}, "output_type": "execute_result"}], "source": ["a[5]"]}, {"cell_type": "markdown", "id": "5806ee80", "metadata": {}, "source": ["Virtually everything about string indexing works similarly for lists. For example, a negative list index counts from the end of the list:"]}, {"cell_type": "markdown", "id": "f4e80df9", "metadata": {}, "source": ["\"string"]}, {"cell_type": "code", "execution_count": 47, "id": "f471f429", "metadata": {}, "outputs": [{"data": {"text/plain": ["'corge'"]}, "execution_count": 47, "metadata": {}, "output_type": "execute_result"}], "source": ["a[-1]"]}, {"cell_type": "code", "execution_count": 48, "id": "d71d5047", "metadata": {}, "outputs": [{"data": {"text/plain": ["'quux'"]}, "execution_count": 48, "metadata": {}, "output_type": "execute_result"}], "source": ["a[-2]"]}, {"cell_type": "code", "execution_count": 49, "id": "9a9c8dc6", "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 49, "metadata": {}, "output_type": "execute_result"}], "source": ["a[-5]"]}, {"cell_type": "markdown", "id": "24e25038", "metadata": {}, "source": ["Slicing also works. If a is a list, the expression `a[m:n]` returns the portion of a from index `m` to, but not including, index `n`:"]}, {"cell_type": "code", "execution_count": 50, "id": "2470be05", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 51, "id": "ec76a7a8", "metadata": {}, "outputs": [{"data": {"text/plain": ["['baz', 'qux', 'quux']"]}, "execution_count": 51, "metadata": {}, "output_type": "execute_result"}], "source": ["a[2:5]"]}, {"cell_type": "markdown", "id": "92e8b2b7", "metadata": {}, "source": ["Other features of string slicing work analogously for list slicing as well:\n", "\n", "- Both positive and negative indices can be specified:"]}, {"cell_type": "code", "execution_count": 52, "id": "186bff88", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bar', 'baz', 'qux']"]}, "execution_count": 52, "metadata": {}, "output_type": "execute_result"}], "source": ["a[-5:-2]"]}, {"cell_type": "code", "execution_count": 53, "id": "2be72101", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bar', 'baz', 'qux']"]}, "execution_count": 53, "metadata": {}, "output_type": "execute_result"}], "source": ["a[1:4]"]}, {"cell_type": "code", "execution_count": 26, "id": "3271375e", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 26, "metadata": {}, "output_type": "execute_result"}], "source": ["a[-5:-2] == a[1:4]"]}, {"cell_type": "markdown", "id": "e4ec255c", "metadata": {}, "source": ["- Omitting the first index starts the slice at the beginning of the list, and omitting the second index extends the slice to the end of the list:"]}, {"cell_type": "code", "execution_count": 29, "id": "f0245a1e", "metadata": {}, "outputs": [{"data": {"text/plain": ["([], [])"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["a[:4], a[0:4]"]}, {"cell_type": "code", "execution_count": 17, "id": "be388ba4", "metadata": {}, "outputs": [{"data": {"text/plain": ["(['baz', 'qux', 'quux', 'corge'], ['baz', 'qux', 'quux', 'corge'])"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["a[2:], a[2:len(a)]"]}, {"cell_type": "code", "execution_count": 18, "id": "ca046fc9", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["a[:4] + a[4:]"]}, {"cell_type": "code", "execution_count": 19, "id": "49b8dc08", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["a[:4] + a[4:] == a"]}, {"cell_type": "markdown", "id": "6e2815b6", "metadata": {}, "source": ["- You can specify a stride\u2014either positive or negative:"]}, {"cell_type": "code", "execution_count": 20, "id": "29c7bfe1", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'baz', 'quux']"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["a[0:6:2]"]}, {"cell_type": "code", "execution_count": 21, "id": "079d8938", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bar', 'qux', 'corge']"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["a[1:6:2]"]}, {"cell_type": "code", "execution_count": 22, "id": "b9dbfed7", "metadata": {}, "outputs": [{"data": {"text/plain": ["['corge', 'qux', 'bar']"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["a[6:0:-2]"]}, {"cell_type": "markdown", "id": "bb2d086b", "metadata": {}, "source": ["- The syntax for reversing a list works the same way it does for strings:"]}, {"cell_type": "code", "execution_count": 23, "id": "ea5539a8", "metadata": {}, "outputs": [{"data": {"text/plain": ["['corge', 'quux', 'qux', 'baz', 'bar', 'foo']"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["a[::-1]"]}, {"cell_type": "markdown", "id": "2a2024a9", "metadata": {}, "source": ["The `[:]` syntax works for lists. However, there is an important difference between how this operation works with a list and how it works with a string."]}, {"cell_type": "code", "execution_count": 61, "id": "67e73393", "metadata": {}, "outputs": [], "source": ["s = 'foobar'"]}, {"cell_type": "code", "execution_count": 36, "id": "730ff483", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foobar'"]}, "execution_count": 36, "metadata": {}, "output_type": "execute_result"}], "source": ["s[:]"]}, {"cell_type": "code", "execution_count": 37, "id": "5e2ab6a8", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 37, "metadata": {}, "output_type": "execute_result"}], "source": ["s[:] is s"]}, {"cell_type": "markdown", "id": "f00040e0", "metadata": {}, "source": ["Conversely, if a is a list, `a[:]` returns a new object that is a copy of `a`:"]}, {"cell_type": "code", "execution_count": 38, "id": "f80028f3", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 39, "id": "cb40d715", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 39, "metadata": {}, "output_type": "execute_result"}], "source": ["a[:]"]}, {"cell_type": "code", "execution_count": 40, "id": "e3bf2d76", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 40, "metadata": {}, "output_type": "execute_result"}], "source": ["a[:] is a"]}, {"cell_type": "markdown", "id": "fcf87db3", "metadata": {}, "source": ["Several Python operators and built-in functions can also be used with lists in ways that are analogous to strings:"]}, {"cell_type": "markdown", "id": "bfbe8474", "metadata": {}, "source": ["- The `in` and `not in` operators:"]}, {"cell_type": "code", "execution_count": 50, "id": "5d0cc53f", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 50, "metadata": {}, "output_type": "execute_result"}], "source": ["'qux' in a"]}, {"cell_type": "code", "execution_count": 51, "id": "5175dcf1", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 51, "metadata": {}, "output_type": "execute_result"}], "source": ["'thud' not in a"]}, {"cell_type": "markdown", "id": "baa92b09", "metadata": {}, "source": ["- The concatenation (`+`) and replication (`*`) operators:"]}, {"cell_type": "code", "execution_count": 61, "id": "da5445ce", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 61, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 62, "id": "8f052203", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']"]}, "execution_count": 62, "metadata": {}, "output_type": "execute_result"}], "source": ["a + ['grault', 'garply']"]}, {"cell_type": "code", "execution_count": 63, "id": "e975dda3", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo',\n", " 'bar',\n", " 'baz',\n", " 'qux',\n", " 'quux',\n", " 'corge',\n", " 'foo',\n", " 'bar',\n", " 'baz',\n", " 'qux',\n", " 'quux',\n", " 'corge']"]}, "execution_count": 63, "metadata": {}, "output_type": "execute_result"}], "source": ["a * 2"]}, {"cell_type": "markdown", "id": "477f6546", "metadata": {}, "source": ["- The `len()`, `min()`, and `max(`) functions:"]}, {"cell_type": "code", "execution_count": 64, "id": "8f61ce86", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 64, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 65, "id": "19230651", "metadata": {}, "outputs": [{"data": {"text/plain": ["6"]}, "execution_count": 65, "metadata": {}, "output_type": "execute_result"}], "source": ["len(a)"]}, {"cell_type": "code", "execution_count": 38, "id": "a1465ad4", "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 38, "metadata": {}, "output_type": "execute_result"}], "source": ["min(a)"]}, {"cell_type": "code", "execution_count": 70, "id": "73689bec", "metadata": {}, "outputs": [{"data": {"text/plain": ["'qux'"]}, "execution_count": 70, "metadata": {}, "output_type": "execute_result"}], "source": ["max(a)"]}, {"cell_type": "markdown", "id": "5bd17e5b", "metadata": {}, "source": ["It\u2019s not an accident that strings and lists behave so similarly. They are both special cases of a more general object type called an iterable, which you will encounter in more detail in the upcoming tutorial on definite iteration."]}, {"cell_type": "markdown", "id": "5024671e", "metadata": {}, "source": ["By the way, in each example above, the list is always assigned to a variable before an operation is performed on it. But you can operate on a list literal as well:"]}, {"cell_type": "code", "execution_count": 40, "id": "2e58770c", "metadata": {}, "outputs": [{"data": {"text/plain": ["'baz'"]}, "execution_count": 40, "metadata": {}, "output_type": "execute_result"}], "source": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][2]"]}, {"cell_type": "code", "execution_count": 41, "id": "349a8106", "metadata": {}, "outputs": [{"data": {"text/plain": ["['corge', 'quux', 'qux', 'baz', 'bar', 'foo']"]}, "execution_count": 41, "metadata": {}, "output_type": "execute_result"}], "source": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1]"]}, {"cell_type": "code", "execution_count": 42, "id": "6f28b0fd", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 42, "metadata": {}, "output_type": "execute_result"}], "source": ["'quux' in ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 43, "id": "2224aa12", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 43, "metadata": {}, "output_type": "execute_result"}], "source": ["['foo', 'bar', 'baz'] + ['qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 44, "id": "097e60a7", "metadata": {}, "outputs": [{"data": {"text/plain": ["6"]}, "execution_count": 44, "metadata": {}, "output_type": "execute_result"}], "source": ["len(['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1])"]}, {"cell_type": "markdown", "id": "0661e9b1", "metadata": {}, "source": ["For that matter, you can do likewise with a string literal:"]}, {"cell_type": "code", "execution_count": 124, "id": "bf6c14f6", "metadata": {}, "outputs": [{"data": {"text/plain": ["'.thgir eb tsum ti ,ti syas noelopaN edarmoC fI'"]}, "execution_count": 124, "metadata": {}, "output_type": "execute_result"}], "source": ["'If Comrade Napoleon says it, it must be right.'[::-1]"]}, {"cell_type": "markdown", "id": "825e5a91", "metadata": {}, "source": ["", "\n", "### 4. Lists Can Be Nested\n", "\n", "You have seen that an element in a list can be any sort of object. That includes another list. A list can contain sublists, which in turn can contain sublists themselves, and so on to arbitrary depth."]}, {"cell_type": "markdown", "id": "f2c80983", "metadata": {}, "source": ["Consider this (admittedly contrived) example:"]}, {"cell_type": "code", "execution_count": 72, "id": "509d8e21", "metadata": {}, "outputs": [], "source": ["x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']"]}, {"cell_type": "markdown", "id": "ff778fc9", "metadata": {}, "source": ["The object structure that x references is diagrammed below:"]}, {"cell_type": "markdown", "id": "7b681953", "metadata": {}, "source": ["\"nested"]}, {"cell_type": "markdown", "id": "cf3b3523", "metadata": {}, "source": ["`x[0]`, `x[2]`, and `x[4]` are strings, each one character long:"]}, {"cell_type": "code", "execution_count": 49, "id": "f7d30716", "metadata": {}, "outputs": [{"data": {"text/plain": ["('a', 'g', 'j')"]}, "execution_count": 49, "metadata": {}, "output_type": "execute_result"}], "source": ["x[0], x[2], x[4]"]}, {"cell_type": "markdown", "id": "faa8b1de", "metadata": {}, "source": ["But `x[1]` and `x[3]` are sublists:"]}, {"cell_type": "code", "execution_count": 50, "id": "bd2afbad", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bb', ['ccc', 'ddd'], 'ee', 'ff']"]}, "execution_count": 50, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1]"]}, {"cell_type": "code", "execution_count": 51, "id": "9b0bbf8d", "metadata": {}, "outputs": [{"data": {"text/plain": ["['hh', 'ii']"]}, "execution_count": 51, "metadata": {}, "output_type": "execute_result"}], "source": ["x[3]"]}, {"cell_type": "markdown", "id": "14b8a84b", "metadata": {}, "source": ["To access the items in a sublist, simply append an additional index:"]}, {"cell_type": "code", "execution_count": 53, "id": "e539e131", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bb', ['ccc', 'ddd'], 'ee', 'ff']"]}, "execution_count": 53, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1]"]}, {"cell_type": "code", "execution_count": 54, "id": "7ffdb3b7", "metadata": {}, "outputs": [{"data": {"text/plain": ["'bb'"]}, "execution_count": 54, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][0]"]}, {"cell_type": "code", "execution_count": 55, "id": "3189540d", "metadata": {}, "outputs": [{"data": {"text/plain": ["['ccc', 'ddd']"]}, "execution_count": 55, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][1]"]}, {"cell_type": "code", "execution_count": 56, "id": "a22d1a11", "metadata": {}, "outputs": [{"data": {"text/plain": ["'ee'"]}, "execution_count": 56, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][2]"]}, {"cell_type": "code", "execution_count": 57, "id": "61b051cf", "metadata": {}, "outputs": [{"data": {"text/plain": ["'ff'"]}, "execution_count": 57, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][3]"]}, {"cell_type": "code", "execution_count": 58, "id": "008ef48d", "metadata": {}, "outputs": [{"data": {"text/plain": ["['hh', 'ii']"]}, "execution_count": 58, "metadata": {}, "output_type": "execute_result"}], "source": ["x[3]"]}, {"cell_type": "markdown", "id": "2e8c0f2d", "metadata": {}, "source": ["`x[1][1]` is yet another sublist, so adding one more index accesses its elements:"]}, {"cell_type": "code", "execution_count": 59, "id": "e21d0bfa", "metadata": {}, "outputs": [{"data": {"text/plain": ["['ccc', 'ddd']"]}, "execution_count": 59, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][1]"]}, {"cell_type": "code", "execution_count": 60, "id": "1089635f", "metadata": {}, "outputs": [{"data": {"text/plain": ["'ccc'"]}, "execution_count": 60, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][1][0]"]}, {"cell_type": "code", "execution_count": 61, "id": "c4f7356c", "metadata": {}, "outputs": [{"data": {"text/plain": ["'ddd'"]}, "execution_count": 61, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][1][1]"]}, {"cell_type": "markdown", "id": "ba86c2fe", "metadata": {}, "source": ["There is no limit, short of the extent of your computer\u2019s memory, to the depth or complexity with which lists can be nested in this way."]}, {"cell_type": "markdown", "id": "8eb1e152", "metadata": {}, "source": ["All the usual syntax regarding indices and slicing applies to sublists as well:"]}, {"cell_type": "code", "execution_count": 62, "id": "67b5631b", "metadata": {}, "outputs": [{"data": {"text/plain": ["'ddd'"]}, "execution_count": 62, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][1][-1]"]}, {"cell_type": "code", "execution_count": 63, "id": "4f9714c4", "metadata": {}, "outputs": [{"data": {"text/plain": ["[['ccc', 'ddd'], 'ee']"]}, "execution_count": 63, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1][1:3]"]}, {"cell_type": "code", "execution_count": 64, "id": "81a1dd51", "metadata": {}, "outputs": [{"data": {"text/plain": ["['ii', 'hh']"]}, "execution_count": 64, "metadata": {}, "output_type": "execute_result"}], "source": ["x[3][::-1]"]}, {"cell_type": "markdown", "id": "54539219", "metadata": {}, "source": ["However, be aware that operators and functions apply to only the list at the level you specify and are not recursive. Consider what happens when you query the length of `x` using `len()`:"]}, {"cell_type": "code", "execution_count": 65, "id": "3e78a3f3", "metadata": {}, "outputs": [{"data": {"text/plain": ["['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']"]}, "execution_count": 65, "metadata": {}, "output_type": "execute_result"}], "source": ["x"]}, {"cell_type": "code", "execution_count": 66, "id": "9b4e8070", "metadata": {}, "outputs": [{"data": {"text/plain": ["5"]}, "execution_count": 66, "metadata": {}, "output_type": "execute_result"}], "source": ["len(x)"]}, {"cell_type": "code", "execution_count": 67, "id": "0d39cd2b", "metadata": {}, "outputs": [{"data": {"text/plain": ["'a'"]}, "execution_count": 67, "metadata": {}, "output_type": "execute_result"}], "source": ["x[0]"]}, {"cell_type": "code", "execution_count": 68, "id": "46a1e57f", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bb', ['ccc', 'ddd'], 'ee', 'ff']"]}, "execution_count": 68, "metadata": {}, "output_type": "execute_result"}], "source": ["x[1]"]}, {"cell_type": "code", "execution_count": 69, "id": "2bc7ba3b", "metadata": {}, "outputs": [{"data": {"text/plain": ["'g'"]}, "execution_count": 69, "metadata": {}, "output_type": "execute_result"}], "source": ["x[2]"]}, {"cell_type": "code", "execution_count": 70, "id": "e35f116f", "metadata": {}, "outputs": [{"data": {"text/plain": ["['hh', 'ii']"]}, "execution_count": 70, "metadata": {}, "output_type": "execute_result"}], "source": ["x[3]"]}, {"cell_type": "code", "execution_count": 71, "id": "32578a6b", "metadata": {}, "outputs": [{"data": {"text/plain": ["'j'"]}, "execution_count": 71, "metadata": {}, "output_type": "execute_result"}], "source": ["x[4]"]}, {"cell_type": "markdown", "id": "c1afc28b", "metadata": {}, "source": ["`x` has only five elements\u2014three strings and two sublists. The individual elements in the sublists don\u2019t count toward `x`\u2019s length."]}, {"cell_type": "markdown", "id": "73e857bf", "metadata": {}, "source": ["You\u2019d encounter a similar situation when using the in operator:"]}, {"cell_type": "code", "execution_count": 72, "id": "70d8feb6", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 72, "metadata": {}, "output_type": "execute_result"}], "source": ["'ddd' in x"]}, {"cell_type": "code", "execution_count": 73, "id": "4b79b4a8", "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 73, "metadata": {}, "output_type": "execute_result"}], "source": ["'ddd' in x[1]"]}, {"cell_type": "code", "execution_count": 74, "id": "0d691d61", "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 74, "metadata": {}, "output_type": "execute_result"}], "source": ["'ddd' in x[1][1]"]}, {"cell_type": "markdown", "id": "0f83d93c", "metadata": {}, "source": ["`'ddd'` is not one of the elements in `x` or `x[1]`. It is only directly an element in the sublist `x[1][1]`. An individual element in a sublist does not count as an element of the parent `list(s)`."]}, {"cell_type": "markdown", "id": "ea5e4006", "metadata": {}, "source": ["", "\n", "### 5. Lists Are Mutable\n", "Most of the data types you have encountered so far have been atomic types. Integer or float objects, for example, are primitive units that can\u2019t be further broken down. These types are immutable, meaning that they can\u2019t be changed once they have been assigned. It doesn\u2019t make much sense to think of changing the value of an integer. If you want a different integer, you just assign a different one."]}, {"cell_type": "markdown", "id": "2034dc7c", "metadata": {}, "source": ["By contrast, the string type is a composite type. Strings are reducible to smaller parts\u2014the component characters. It might make sense to think of changing the characters in a string. But you can\u2019t. In Python, strings are also immutable."]}, {"cell_type": "markdown", "id": "01e81a5a", "metadata": {}, "source": ["The list is the first mutable data type you have encountered. Once a list has been created, elements can be added, deleted, shifted, and moved around at will. Python provides a wide range of ways to modify lists."]}, {"cell_type": "markdown", "id": "4d6f90a7", "metadata": {}, "source": ["#### Modifying a Single List Value\n", "A single value in a list can be replaced by indexing and simple assignment:"]}, {"cell_type": "code", "execution_count": 83, "id": "cc6bb5c6", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 84, "id": "2e5c019a", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 84, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 85, "id": "82256a14", "metadata": {}, "outputs": [], "source": ["a[2] = 10"]}, {"cell_type": "code", "execution_count": 86, "id": "3375ed03", "metadata": {}, "outputs": [], "source": ["a[-1] = 20"]}, {"cell_type": "code", "execution_count": 87, "id": "67f42e68", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 10, 'qux', 'quux', 20]"]}, "execution_count": 87, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "72ccef34", "metadata": {}, "source": ["You may recall from the section on Strings and Character Data in Python that you can\u2019t do this with a string:"]}, {"cell_type": "code", "execution_count": 89, "id": "5e0d7fcb", "metadata": {}, "outputs": [], "source": ["s = 'foobarbaz'"]}, {"cell_type": "code", "execution_count": 90, "id": "7b2952e4", "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'str' object does not support item assignment", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'x'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment"]}], "source": ["s[2] = 'x'"]}, {"cell_type": "markdown", "id": "2b911673", "metadata": {}, "source": ["A list item can be deleted with the `del` command:"]}, {"cell_type": "code", "execution_count": 92, "id": "18d15d1f", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 93, "id": "d8caa2b0", "metadata": {}, "outputs": [], "source": ["del a[3]"]}, {"cell_type": "code", "execution_count": 94, "id": "de0c5d08", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'quux', 'corge']"]}, "execution_count": 94, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "cbe55162", "metadata": {}, "source": ["#### Modifying Multiple List Values\n", "\n", "What if you want to change several contiguous elements in a list at one time? Python allows this with slice assignment, which has the following syntax:\n", "\n", "```python\n", "a[m:n] = \n", "```"]}, {"cell_type": "markdown", "id": "4a99e7fc", "metadata": {}, "source": ["Again, for the moment, think of an iterable as a list. This assignment replaces the specified slice of a with ``:"]}, {"cell_type": "code", "execution_count": 242, "id": "74da295b", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 243, "id": "5aae64b9", "metadata": {}, "outputs": [{"data": {"text/plain": ["['bar', 'baz', 'qux']"]}, "execution_count": 243, "metadata": {}, "output_type": "execute_result"}], "source": ["a[1:4]"]}, {"cell_type": "code", "execution_count": 244, "id": "7ea4c9c2", "metadata": {}, "outputs": [], "source": ["a[1:4] = [1.1, 2.2, 3.3, 4.4, 5.5]"]}, {"cell_type": "code", "execution_count": 245, "id": "76994c62", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']"]}, "execution_count": 245, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 99, "id": "b56fecb6", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1.1, 2.2, 3.3, 4.4, 5.5]"]}, "execution_count": 99, "metadata": {}, "output_type": "execute_result"}], "source": ["a[1:6]"]}, {"cell_type": "code", "execution_count": 100, "id": "aaf1a477", "metadata": {}, "outputs": [], "source": ["a[1:6] = ['Bark!']"]}, {"cell_type": "code", "execution_count": 101, "id": "b23cf51b", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'Bark!', 'quux', 'corge']"]}, "execution_count": 101, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "1cbe3508", "metadata": {}, "source": ["The number of elements inserted need not be equal to the number replaced. Python just grows or shrinks the list as needed."]}, {"cell_type": "markdown", "id": "0f9fd23a", "metadata": {}, "source": ["You can insert multiple elements in place of a single element\u2014just use a slice that denotes only one element:"]}, {"cell_type": "code", "execution_count": 102, "id": "246ce51d", "metadata": {}, "outputs": [], "source": ["a = [1, 2, 3]"]}, {"cell_type": "code", "execution_count": 103, "id": "6b83bcc5", "metadata": {}, "outputs": [], "source": ["a[1:2] = [2.1, 2.2, 2.3]"]}, {"cell_type": "code", "execution_count": 104, "id": "f55f6bdd", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1, 2.1, 2.2, 2.3, 3]"]}, "execution_count": 104, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "f49b0899", "metadata": {}, "source": ["Note that this is not the same as replacing the single element with a list:"]}, {"cell_type": "code", "execution_count": 106, "id": "949ce113", "metadata": {}, "outputs": [], "source": ["a = [1, 2, 3]"]}, {"cell_type": "code", "execution_count": 107, "id": "11c7f9f6", "metadata": {}, "outputs": [], "source": ["a[1] = [2.1, 2.2, 2.3]"]}, {"cell_type": "code", "execution_count": 108, "id": "8d58652b", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1, [2.1, 2.2, 2.3], 3]"]}, "execution_count": 108, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "5d73ed33", "metadata": {}, "source": ["You can also insert elements into a list without removing anything. Simply specify a slice of the form `[n:n]` (a zero-length slice) at the desired index:"]}, {"cell_type": "code", "execution_count": 109, "id": "1a9c2a32", "metadata": {}, "outputs": [], "source": ["a = [1, 2, 7, 8]"]}, {"cell_type": "code", "execution_count": 110, "id": "d0626b56", "metadata": {}, "outputs": [], "source": ["a[2:2] = [3, 4, 5, 6]"]}, {"cell_type": "code", "execution_count": 111, "id": "4e7c3244", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1, 2, 3, 4, 5, 6, 7, 8]"]}, "execution_count": 111, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "8bba76d8", "metadata": {}, "source": ["You can delete multiple elements out of the middle of a list by assigning the appropriate slice to an empty list. You can also use the del statement with the same slice:"]}, {"cell_type": "code", "execution_count": 115, "id": "7bcf5f1f", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 116, "id": "99f2580f", "metadata": {}, "outputs": [], "source": ["a[1:5] = []"]}, {"cell_type": "code", "execution_count": 117, "id": "d047bbff", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'corge']"]}, "execution_count": 117, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 118, "id": "6c54c55b", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 119, "id": "9dfeb0e2", "metadata": {}, "outputs": [], "source": ["del a[1:5]"]}, {"cell_type": "code", "execution_count": 246, "id": "38b8462e", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']"]}, "execution_count": 246, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "b7219cc5", "metadata": {}, "source": ["#### Prepending or Appending Items to a List\n", "\n", "Additional items can be added to the start or end of a list using the + concatenation operator or the `+=` augmented assignment operator:"]}, {"cell_type": "code", "execution_count": 121, "id": "0d66853f", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 122, "id": "43e20929", "metadata": {}, "outputs": [], "source": ["a += ['grault', 'garply']"]}, {"cell_type": "code", "execution_count": 123, "id": "15bde346", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux', 'quux', 'corge', 'grault', 'garply']"]}, "execution_count": 123, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 124, "id": "3a607bd9", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 125, "id": "797c39bb", "metadata": {}, "outputs": [], "source": ["a = [10, 20] + a"]}, {"cell_type": "code", "execution_count": 126, "id": "11c45a8b", "metadata": {}, "outputs": [{"data": {"text/plain": ["[10, 20, 'foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, "execution_count": 126, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "12bbfca7", "metadata": {}, "source": ["Note that a list must be concatenated with another list, so if you want to add only one element, you need to specify it as a singleton list:"]}, {"cell_type": "code", "execution_count": 127, "id": "6169fab4", "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'int' object is not iterable", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'qux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'quux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'corge'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable"]}], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']\n", "a += 20 "]}, {"cell_type": "code", "execution_count": 128, "id": "8168bcf0", "metadata": {}, "outputs": [], "source": ["a += [20]"]}, {"cell_type": "code", "execution_count": 119, "id": "53ec6cc3", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']"]}, "execution_count": 119, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "c432ab55", "metadata": {}, "source": ["> **Note:** Technically, it isn\u2019t quite correct to say a list must be concatenated with another list. More precisely, a list must be concatenated with an object that is iterable. Of course, lists are iterable, so it works to concatenate a list with another list.\n", ">\n", ">Strings are iterable also. But watch what happens when you concatenate a string onto a list:\n", ">```python\n", "a = ['foo', 'bar', 'baz', 'qux', 'quux']\n", "a += 'corge'\n", "a\n", ">```\n", ">This result is perhaps not quite what you expected. When a string is iterated through, the result is a list of its component characters. In the above example, what gets concatenated onto list a is a list of the characters in the string `'corge'`.\n", ">\n", ">If you really want to add just the single string 'corge' to the end of the list, you need to specify it as a singleton list:\n", ">```python\n", "a = ['foo', 'bar', 'baz', 'qux', 'quux']\n", "a += ['corge']\n", "a\n", ">```\n", "> If this seems mysterious, don\u2019t fret too much. You\u2019ll learn about the ins and outs of iterables in the tutorial on definite iteration."]}, {"cell_type": "markdown", "id": "3c679f5f", "metadata": {}, "source": ["", "\n", "### 6. Lists Are Dynamic\n", "This tutorial began with a list of six defining characteristics of Python lists. The last one is that lists are dynamic. You have seen many examples of this in the sections above. When items are added to a list, it grows as needed:"]}, {"cell_type": "code", "execution_count": 135, "id": "07222c9a", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 136, "id": "90e7fd91", "metadata": {}, "outputs": [], "source": ["a[2:2] = [1, 2, 3]"]}, {"cell_type": "code", "execution_count": 137, "id": "c860669c", "metadata": {}, "outputs": [], "source": ["a += [3.14159]"]}, {"cell_type": "code", "execution_count": 138, "id": "59f45737", "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 1, 2, 3, 'baz', 'qux', 'quux', 'corge', 3.14159]"]}, "execution_count": 138, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "efebeb5e", "metadata": {}, "source": ["Similarly, a list shrinks to accommodate the removal of items:"]}, {"cell_type": "code", "execution_count": 139, "id": "9e8025f4", "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']"]}, {"cell_type": "code", "execution_count": 140, "id": "1bfa206c", "metadata": {}, "outputs": [], "source": ["a[2:3] = []"]}, {"cell_type": "code", "execution_count": 141, "id": "bcb842d3", "metadata": {}, "outputs": [], "source": ["del a[0]"]}, {"cell_type": "code", "execution_count": 279, "id": "c7f29cd7", "metadata": {"scrolled": true}, "outputs": [{"data": {"text/plain": ["['foo', 1.1, 2.2, 3.3, 4.4, 5.5, 'quux', 'corge']"]}, "execution_count": 279, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "id": "779ebac7", "metadata": {}, "source": ["", "\n", "## Python Tuples\n", "\n", "Python provides another type that is an ordered collection of objects, called a tuple."]}, {"cell_type": "markdown", "id": "9d19ee98", "metadata": {}, "source": ["", "\n", "### Defining and Using Tuples\n", "Tuples are identical to lists in all respects, except for the following properties:\n", "\n", "- Tuples are defined by enclosing the elements in parentheses (`()`) instead of square brackets `[]`).\n", "- Tuples are immutable."]}, {"cell_type": "markdown", "id": "58fc91ae", "metadata": {}, "source": ["Here is a short example showing a tuple definition, indexing, and slicing:"]}, {"cell_type": "code", "execution_count": 299, "id": "8a21fd5f", "metadata": {}, "outputs": [], "source": ["t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')"]}, {"cell_type": "code", "execution_count": 300, "id": "4b5c124e", "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 'bar', 'baz', 'qux', 'quux', 'corge')"]}, "execution_count": 300, "metadata": {}, "output_type": "execute_result"}], "source": ["t"]}, {"cell_type": "code", "execution_count": 301, "id": "e7cd310e", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 301, "metadata": {}, "output_type": "execute_result"}], "source": ["t[0]"]}, {"cell_type": "code", "execution_count": 302, "id": "b447fd42", "metadata": {}, "outputs": [{"data": {"text/plain": ["'corge'"]}, "execution_count": 302, "metadata": {}, "output_type": "execute_result"}], "source": ["t[-1]"]}, {"cell_type": "code", "execution_count": 303, "id": "4a97577a", "metadata": {}, "outputs": [{"data": {"text/plain": ["('bar', 'qux', 'corge')"]}, "execution_count": 303, "metadata": {}, "output_type": "execute_result"}], "source": ["t[1::2]"]}, {"cell_type": "markdown", "id": "aa9a0f3b", "metadata": {}, "source": ["Never fear! Our favorite string and list reversal mechanism works for tuples as well:"]}, {"cell_type": "code", "execution_count": 304, "id": "c0e9af40", "metadata": {}, "outputs": [{"data": {"text/plain": ["('corge', 'quux', 'qux', 'baz', 'bar', 'foo')"]}, "execution_count": 304, "metadata": {}, "output_type": "execute_result"}], "source": ["t[::-1]"]}, {"cell_type": "markdown", "id": "fdb1c32a", "metadata": {}, "source": ["> Note: Even though tuples are defined using parentheses, you still index and slice tuples using square brackets, just as for strings and lists."]}, {"cell_type": "markdown", "id": "ca8d5e75", "metadata": {}, "source": ["Everything you\u2019ve learned about lists\u2014they are ordered, they can contain arbitrary objects, they can be indexed and sliced, they can be nested\u2014is true of tuples as well. But they can\u2019t be modified:"]}, {"cell_type": "code", "execution_count": 305, "id": "29c14a99", "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'qux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'quux'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'corge'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'Bark!'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"]}], "source": ["t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')\n", "t[2] = 'Bark!'"]}, {"cell_type": "markdown", "id": "d3c309c0", "metadata": {}, "source": ["Why use a tuple instead of a list?\n", "\n", "- Program execution is faster when manipulating a tuple than it is for the equivalent list. (This is probably not going to be noticeable when the list or tuple is small.)\n", "\n", "- Sometimes you don\u2019t want data to be modified. If the values in the collection are meant to remain constant for the life of the program, using a tuple instead of a list guards against accidental modification.\n", "\n", "- There is another Python data type that you will encounter shortly called a dictionary, which requires as one of its components a value that is of an immutable type. A tuple can be used for this purpose, whereas a list can\u2019t be."]}, {"cell_type": "markdown", "id": "77c610d9", "metadata": {}, "source": ["In a Python REPL session, you can display the values of several objects simultaneously by entering them directly at the `>>>` prompt, separated by commas:"]}, {"cell_type": "code", "execution_count": 150, "id": "ab20cb42", "metadata": {}, "outputs": [], "source": ["a = 'foo'"]}, {"cell_type": "code", "execution_count": 151, "id": "33a267f4", "metadata": {}, "outputs": [], "source": ["b = 42"]}, {"cell_type": "code", "execution_count": 152, "id": "0ca51e51", "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 3.14159, 42)"]}, "execution_count": 152, "metadata": {}, "output_type": "execute_result"}], "source": ["a, 3.14159, b"]}, {"cell_type": "markdown", "id": "dca838bf", "metadata": {}, "source": ["Python displays the response in parentheses because it is implicitly interpreting the input as a tuple."]}, {"cell_type": "markdown", "id": "1a4ca1ce", "metadata": {}, "source": ["There is one peculiarity regarding tuple definition that you should be aware of. There is no ambiguity when defining an empty tuple, nor one with two or more elements. Python knows you are defining a tuple:"]}, {"cell_type": "code", "execution_count": 346, "id": "71c13a4e", "metadata": {}, "outputs": [{"data": {"text/plain": ["tuple"]}, "execution_count": 346, "metadata": {}, "output_type": "execute_result"}], "source": ["t = ()\n", "type(t)"]}, {"cell_type": "code", "execution_count": 347, "id": "9182eb81", "metadata": {}, "outputs": [{"data": {"text/plain": ["tuple"]}, "execution_count": 347, "metadata": {}, "output_type": "execute_result"}], "source": ["t = (1, 2)\n", "type(t)"]}, {"cell_type": "code", "execution_count": 348, "id": "0f792121", "metadata": {}, "outputs": [{"data": {"text/plain": ["tuple"]}, "execution_count": 348, "metadata": {}, "output_type": "execute_result"}], "source": ["t = (1, 2, 3, 4, 5)\n", "type(t)"]}, {"cell_type": "markdown", "id": "94149463", "metadata": {}, "source": ["But what happens when you try to define a tuple with one item:"]}, {"cell_type": "code", "execution_count": 349, "id": "482ddc41", "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 349, "metadata": {}, "output_type": "execute_result"}], "source": ["t = (2)\n", "type(t)"]}, {"cell_type": "markdown", "id": "278c54f2", "metadata": {}, "source": ["Doh! Since parentheses are also used to define operator precedence in expressions, Python evaluates the expression `(2)` as simply the integer `2` and creates an int object. To tell Python that you really want to define a singleton tuple, include a trailing comma `(,)` just before the closing parenthesis:"]}, {"cell_type": "code", "execution_count": 350, "id": "978af638", "metadata": {}, "outputs": [{"data": {"text/plain": ["tuple"]}, "execution_count": 350, "metadata": {}, "output_type": "execute_result"}], "source": ["t = (2,)\n", "type(t)"]}, {"cell_type": "code", "execution_count": 351, "id": "dc15be8f", "metadata": {}, "outputs": [{"data": {"text/plain": ["2"]}, "execution_count": 351, "metadata": {}, "output_type": "execute_result"}], "source": ["t[0]"]}, {"cell_type": "code", "execution_count": 352, "id": "221ed952", "metadata": {}, "outputs": [{"data": {"text/plain": ["2"]}, "execution_count": 352, "metadata": {}, "output_type": "execute_result"}], "source": ["t[-1]"]}, {"cell_type": "markdown", "id": "e67604f3", "metadata": {}, "source": ["You probably won\u2019t need to define a singleton tuple often, but there has to be a way."]}, {"cell_type": "markdown", "id": "f1c8e7d6", "metadata": {}, "source": ["When you display a singleton tuple, Python includes the comma, to remind you that it\u2019s a tuple:"]}, {"cell_type": "code", "execution_count": 166, "id": "fc8bc0fc", "metadata": {}, "outputs": [{"data": {"text/plain": ["(2,)"]}, "execution_count": 166, "metadata": {}, "output_type": "execute_result"}], "source": ["t"]}, {"cell_type": "markdown", "id": "89dd7789", "metadata": {}, "source": ["", "\n", "### Tuple Assignment, Packing, and Unpacking\n", "\n", "As you have already seen above, a literal tuple containing several items can be assigned to a single object:"]}, {"cell_type": "code", "execution_count": 69, "id": "b4bdef2f", "metadata": {}, "outputs": [], "source": ["t = ('foo', 'bar', 'baz', 'qux')"]}, {"cell_type": "markdown", "id": "303f6805", "metadata": {}, "source": ["\"tuple-packing\""]}, {"cell_type": "code", "execution_count": 70, "id": "9db2d631", "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 'bar', 'baz', 'qux')"]}, "execution_count": 70, "metadata": {}, "output_type": "execute_result"}], "source": ["t"]}, {"cell_type": "code", "execution_count": 71, "id": "7a298e62", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 71, "metadata": {}, "output_type": "execute_result"}], "source": ["t[0]"]}, {"cell_type": "code", "execution_count": 72, "id": "8e9180a0", "metadata": {}, "outputs": [{"data": {"text/plain": ["'qux'"]}, "execution_count": 72, "metadata": {}, "output_type": "execute_result"}], "source": ["t[-1]"]}, {"cell_type": "markdown", "id": "7d2ce889", "metadata": {}, "source": ["If that \u201cpacked\u201d object is subsequently assigned to a new tuple, the individual items are \u201cunpacked\u201d into the objects in the tuple:"]}, {"cell_type": "markdown", "id": "2cf73f03", "metadata": {}, "source": ["\"tuple-unpacking\""]}, {"cell_type": "code", "execution_count": 174, "id": "022d4f57", "metadata": {}, "outputs": [], "source": ["(s1, s2, s3, s4) = t"]}, {"cell_type": "code", "execution_count": 175, "id": "bf059422", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 175, "metadata": {}, "output_type": "execute_result"}], "source": ["s1"]}, {"cell_type": "code", "execution_count": 176, "id": "dd38c5cf", "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 176, "metadata": {}, "output_type": "execute_result"}], "source": ["s2"]}, {"cell_type": "code", "execution_count": 177, "id": "f1b61f04", "metadata": {}, "outputs": [{"data": {"text/plain": ["'baz'"]}, "execution_count": 177, "metadata": {}, "output_type": "execute_result"}], "source": ["s3"]}, {"cell_type": "code", "execution_count": 178, "id": "89c0d428", "metadata": {}, "outputs": [{"data": {"text/plain": ["'qux'"]}, "execution_count": 178, "metadata": {}, "output_type": "execute_result"}], "source": ["s4"]}, {"cell_type": "markdown", "id": "b145cde5", "metadata": {}, "source": ["When unpacking, the number of variables on the left must match the number of values in the tuple:"]}, {"cell_type": "code", "execution_count": 191, "id": "daee90ca", "metadata": {}, "outputs": [{"ename": "ValueError", "evalue": "too many values to unpack (expected 3)", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0ms1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms3\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: too many values to unpack (expected 3)"]}], "source": ["(s1, s2, s3) = t "]}, {"cell_type": "code", "execution_count": 192, "id": "36b6bcb2", "metadata": {}, "outputs": [{"ename": "ValueError", "evalue": "not enough values to unpack (expected 5, got 4)", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0ms1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms5\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: not enough values to unpack (expected 5, got 4)"]}], "source": ["(s1, s2, s3, s4, s5) = t"]}, {"cell_type": "markdown", "id": "7048d14f", "metadata": {}, "source": ["Packing and unpacking can be combined into one statement to make a compound assignment:"]}, {"cell_type": "code", "execution_count": 197, "id": "ada847c3", "metadata": {}, "outputs": [], "source": ["(s1, s2, s3, s4) = ('foo', 'bar', 'baz', 'qux')"]}, {"cell_type": "code", "execution_count": 198, "id": "1c204276", "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 198, "metadata": {}, "output_type": "execute_result"}], "source": ["s1"]}, {"cell_type": "code", "execution_count": 199, "id": "4f181eb8", "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 199, "metadata": {}, "output_type": "execute_result"}], "source": ["s2"]}, {"cell_type": "code", "execution_count": 200, "id": "bb0bf08c", "metadata": {}, "outputs": [{"data": {"text/plain": ["'baz'"]}, "execution_count": 200, "metadata": {}, "output_type": "execute_result"}], "source": ["s3"]}, {"cell_type": "code", "execution_count": 201, "id": "b0de32a6", "metadata": {}, "outputs": [{"data": {"text/plain": ["'qux'"]}, "execution_count": 201, "metadata": {}, "output_type": "execute_result"}], "source": ["s4"]}, {"cell_type": "markdown", "id": "bdc934c6", "metadata": {}, "source": ["Again, the number of elements in the tuple on the left of the assignment must equal the number on the right:"]}, {"cell_type": "code", "execution_count": 202, "id": "1d1e42ef", "metadata": {}, "outputs": [{"ename": "ValueError", "evalue": "not enough values to unpack (expected 5, got 4)", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0ms1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms5\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'qux'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: not enough values to unpack (expected 5, got 4)"]}], "source": ["(s1, s2, s3, s4, s5) = ('foo', 'bar', 'baz', 'qux')"]}, {"cell_type": "markdown", "id": "13931cbc", "metadata": {}, "source": ["In assignments like this and a small handful of other situations, Python allows the parentheses that are usually used for denoting a tuple to be left out:"]}, {"cell_type": "code", "execution_count": 203, "id": "d301d74c", "metadata": {}, "outputs": [{"data": {"text/plain": ["(1, 2, 3)"]}, "execution_count": 203, "metadata": {}, "output_type": "execute_result"}], "source": ["t = 1, 2, 3\n", "t"]}, {"cell_type": "code", "execution_count": 204, "id": "4eaf55b5", "metadata": {}, "outputs": [{"data": {"text/plain": ["(1, 2, 3)"]}, "execution_count": 204, "metadata": {}, "output_type": "execute_result"}], "source": ["x1, x2, x3 = t\n", "x1, x2, x3"]}, {"cell_type": "code", "execution_count": 205, "id": "4a2c32c5", "metadata": {}, "outputs": [{"data": {"text/plain": ["(4, 5, 6)"]}, "execution_count": 205, "metadata": {}, "output_type": "execute_result"}], "source": ["x1, x2, x3 = 4, 5, 6\n", "x1, x2, x3"]}, {"cell_type": "code", "execution_count": 206, "id": "ecdd33ca", "metadata": {}, "outputs": [{"data": {"text/plain": ["(2,)"]}, "execution_count": 206, "metadata": {}, "output_type": "execute_result"}], "source": ["t = 2,\n", "t"]}, {"cell_type": "markdown", "id": "0b5e39bb", "metadata": {}, "source": ["It works the same whether the parentheses are included or not, so if you have any doubt as to whether they\u2019re needed, go ahead and include them."]}, {"cell_type": "markdown", "id": "27814877", "metadata": {}, "source": ["Tuple assignment allows for a curious bit of idiomatic Python. Frequently when programming, you have two variables whose values you need to swap. In most programming languages, it is necessary to store one of the values in a temporary variable while the swap occurs like this:"]}, {"cell_type": "code", "execution_count": 207, "id": "840beb6d", "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 'bar')"]}, "execution_count": 207, "metadata": {}, "output_type": "execute_result"}], "source": ["a = 'foo'\n", "b = 'bar'\n", "a, b"]}, {"cell_type": "code", "execution_count": 210, "id": "94eda2d2", "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 'bar')"]}, "execution_count": 210, "metadata": {}, "output_type": "execute_result"}], "source": ["temp = a\n", "a = b\n", "b = temp\n", "a, b"]}, {"cell_type": "markdown", "id": "717db98e", "metadata": {}, "source": ["In Python, the swap can be done with a single tuple assignment:"]}, {"cell_type": "code", "execution_count": 212, "id": "46350be1", "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 'bar')"]}, "execution_count": 212, "metadata": {}, "output_type": "execute_result"}], "source": ["a = 'foo'\n", "b = 'bar'\n", "a, b"]}, {"cell_type": "code", "execution_count": 213, "id": "d934380b", "metadata": {}, "outputs": [], "source": ["a, b = b, a"]}, {"cell_type": "code", "execution_count": 214, "id": "6f2c968e", "metadata": {}, "outputs": [{"data": {"text/plain": ["('bar', 'foo')"]}, "execution_count": 214, "metadata": {}, "output_type": "execute_result"}], "source": ["a, b"]}, {"cell_type": "markdown", "id": "ad4cb308", "metadata": {}, "source": ["As anyone who has ever had to swap values using a temporary variable knows, being able to do it this way in Python is the pinnacle of modern technological achievement. It will never get better than this."]}, {"cell_type": "code", "execution_count": 383, "id": "16b352b7", "metadata": {}, "outputs": [], "source": ["x = (1, 2, 3)"]}, {"cell_type": "code", "execution_count": 384, "id": "41ad8b4d", "metadata": {}, "outputs": [{"data": {"text/plain": ["1"]}, "execution_count": 384, "metadata": {}, "output_type": "execute_result"}], "source": ["x[0]"]}, {"cell_type": "markdown", "id": "8756eecb", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "This tutorial covered the basic properties of Python **lists** and **tuples**, and how to manipulate them. You will use these extensively in your Python programming."]}, {"cell_type": "markdown", "id": "dcc73545", "metadata": {}, "source": ["One of the chief characteristics of a list is that it is ordered. The order of the elements in a list is an intrinsic property of that list and does not change, unless the list itself is modified. (The same is true of tuples, except of course they can\u2019t be modified.)"]}, {"cell_type": "markdown", "id": "d19954dc", "metadata": {}, "source": ["The next tutorial will introduce you to the Python **dictionary**: a composite data type that is unordered. Read on!"]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/python/01. Basics/09 Composite Data Types: Dictionary.ipynb b/python/01. Basics/09 Composite Data Types: Dictionary.ipynb index 66d64a9..0ec5413 100755 --- a/python/01. Basics/09 Composite Data Types: Dictionary.ipynb +++ b/python/01. Basics/09 Composite Data Types: Dictionary.ipynb @@ -1,1414 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Dictionary\n", - "\n", - "Python provides another composite data type called a dictionary, which is similar to a list in that it is a collection of objects." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Dictionaries and lists share the following characteristics:\n", - "\n", - "- Both are mutable.\n", - "- Both are dynamic. They can grow and shrink as needed.\n", - "- Both can be nested. A list can contain another list. A dictionary can contain another dictionary. A dictionary can also contain a list, and vice versa." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Dictionaries differ from lists primarily in how elements are accessed:\n", - "\n", - "- List elements are accessed by their position in the list, via indexing.\n", - "- Dictionary elements are accessed via keys." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Defining a Dictionary\n", - "Dictionaries are Python’s implementation of a data structure that is more generally known as an associative array. A dictionary consists of a collection of key-value pairs. Each key-value pair maps the key to its associated value." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can define a dictionary by enclosing a comma-separated list of key-value pairs in curly braces (`{}`). A colon (`:`) separates each key from its associated value:\n", - "\n", - "```python\n", - "d = {\n", - " : ,\n", - " : ,\n", - " .\n", - " .\n", - " .\n", - " : \n", - "}\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The following defines a dictionary that maps a location to the name of its corresponding Major League Baseball team:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "MLB_team = {\n", - " 'Colorado' : 'Rockies',\n", - " 'Boston' : 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle' : 'Mariners'\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"dictionary\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also construct a dictionary with the built-in `dict()` function. The argument to `dict()` should be a sequence of key-value pairs. A list of tuples works well for this:\n", - "\n", - "```python\n", - "d = dict([\n", - " (, ),\n", - " (, , )\n", - "])\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`MLB_team` can then also be defined this way:" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [], - "source": [ - "MLB_team = dict([\n", - " ('Colorado', 'Rockies'),\n", - " ('Boston', 'Red Sox'),\n", - " ('Minnesota', 'Twins'),\n", - " ('Milwaukee', 'Brewers'),\n", - " ('Seattle', 'Mariners')\n", - "])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If the key values are simple strings, they can be specified as keyword arguments. So here is yet another way to define `MLB_team`:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "MLB_team = dict(\n", - " Colorado='Rockies',\n", - " Boston='Red Sox',\n", - " Minnesota='Twins',\n", - " Milwaukee='Brewers',\n", - " Seattle='Mariners'\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once you’ve defined a dictionary, you can display its contents, the same as you can do for a list. All three of the definitions shown above appear as follows when displayed:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(MLB_team)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle': 'Mariners'}" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The entries in the dictionary display in the order they were defined. But that is irrelevant when it comes to retrieving them. Dictionary elements are not accessed by numerical index:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'MLB_team' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/1469821463.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined" - ] - } - ], - "source": [ - "MLB_team[1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing Dictionary Values\n", - "\n", - "Of course, dictionary elements must be accessible somehow. If you don’t get them by index, then how do you get them?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A value is retrieved from a dictionary by specifying its corresponding key in square brackets (`[]`):" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Twins'" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team['Minnesota']" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Rockies'" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team['Colorado']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you refer to a key that is not in the dictionary, Python raises an exception:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "'Toronto'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Toronto'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: 'Toronto'" - ] - } - ], - "source": [ - "MLB_team['Toronto']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Adding an entry to an existing dictionary is simply a matter of assigning a new key and value:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle': 'Mariners',\n", - " 'Kansas City': 'Royals'}" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team['Kansas City'] = 'Royals'\n", - "MLB_team" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you want to update an entry, you can just assign a new value to an existing key:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle': 'Seahawks',\n", - " 'Kansas City': 'Royals'}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team['Seattle'] = 'Seahawks'\n", - "MLB_team" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To delete an entry, use the `del` statement, specifying the key to delete:" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'MLB_team' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3737734966.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mdel\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Seattle'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined" - ] - } - ], - "source": [ - "del MLB_team['Seattle']\n", - "MLB_team" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Dictionary Keys vs. List Indices\n", - "You may have noticed that the interpreter raises the same exception, KeyError, when a dictionary is accessed with either an undefined key or by a numeric index:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "'Toronto'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Toronto'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: 'Toronto'" - ] - } - ], - "source": [ - "MLB_team['Toronto']" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "1", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: 1" - ] - } - ], - "source": [ - "MLB_team[1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In fact, it’s the same error. In the latter case, `[1]` looks like a numerical index, but it isn’t." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You will see later in this tutorial that an object of any immutable type can be used as a dictionary key. Accordingly, there is no reason you can’t use integers:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{0: 'a', 1: 'b', 2: 'c', 3: 'd'}" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a'" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'c'" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[2]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the expressions `MLB_team[1]`, `d[0]`, and `d[2]`, the numbers in square brackets appear as though they might be indices. But they have nothing to do with the order of the items in the dictionary. Python is interpreting them as dictionary keys. If you define this same dictionary in reverse order, you still get the same values using the same keys:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{3: 'd', 2: 'c', 1: 'b', 0: 'a'}" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = {3: 'd', 2: 'c', 1: 'b', 0: 'a'}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a'" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'c'" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[2]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The syntax may look similar, but you can’t treat a dictionary like a list:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(d)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "-1", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: -1" - ] - } - ], - "source": [ - "d[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'd' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3015485889.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'd' is not defined" - ] - } - ], - "source": [ - "d[0:2]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Although access to items in a dictionary does not depend on order, Python does guarantee that the order of items in a dictionary is preserved. When displayed, items will appear in the order they were defined, and iteration through the keys will occur in that order as well. Items added to a dictionary are added at the end. If items are deleted, the order of the remaining items is retained.\n", - ">\n", - ">You can only count on this preservation of order very recently. It was [added as a part of the Python language specification in version 3.7](https://realpython.com/python37-new-features/#the-order-of-dictionaries-is-guaranteed). However, it was true as of version 3.6 as well—by happenstance as a result of the implementation but not guaranteed by the language specification." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Building a Dictionary Incrementally\n", - "\n", - "Defining a dictionary using curly braces and a list of key-value pairs, as shown above, is fine if you know all the keys and values in advance. But what if you want to build a dictionary on the fly?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can start by creating an empty dictionary, which is specified by empty curly braces. Then you can add new keys and values one at a time:" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict" - ] - }, - "execution_count": 118, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person = {}\n", - "type(person)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "person['fname'] = 'Joe'\n", - "person['lname'] = 'Fonebone'\n", - "person['age'] = 51\n", - "person['spouse'] = 'Edna'\n", - "person['children'] = ['Ralph', 'Betty', 'Joey']\n", - "person['pets'] = {'dog': 'Fido', 'cat': 'Sox'}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once the dictionary is created in this way, its values are accessed the same way as any other dictionary:" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'fname': 'Joe',\n", - " 'lname': 'Fonebone',\n", - " 'age': 51,\n", - " 'spouse': 'Edna',\n", - " 'children': ['Ralph', 'Betty', 'Joey'],\n", - " 'pets': {'dog': 'Fido', 'cat': 'Sox'}}" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Joe'" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person['fname']" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "51" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person['age']" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['Ralph', 'Betty', 'Joey']" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person['children']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Retrieving the values in the sublist or subdictionary requires an additional index or key:" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Joey'" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person['children'][-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Sox'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "person['pets']['cat']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This example exhibits another feature of dictionaries: the values contained in the dictionary don’t need to be the same type. In person, some of the values are strings, one is an integer, one is a list, and one is another dictionary." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Just as the values in a dictionary don’t need to be of the same type, the keys don’t either:" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{42: 'aaa', 2.78: 'bbb', True: 'ccc'}" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "foo = {42: 'aaa', 2.78: 'bbb', True: 'ccc'}\n", - "foo" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'aaa'" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "foo[42]" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bbb'" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "foo[2.78]" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ccc'" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "foo[True]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, one of the keys is an integer, one is a float, and one is a Boolean. It’s not obvious how this would be useful, but you never know." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice how versatile Python dictionaries are. In MLB_team, the same piece of information (the baseball team name) is kept for each of several different geographical locations. person, on the other hand, stores varying types of data for a single person." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can use dictionaries for a wide range of purposes because there are so few limitations on the keys and values that are allowed. But there are some. Read on!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Restrictions on Dictionary Keys\n", - "\n", - "Almost any type of value can be used as a dictionary key in Python. You just saw this example, where integer, float, and Boolean objects are used as keys:" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{42: 'aaa', 2.78: 'bbb', True: 'ccc'}" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "foo = {42: 'aaa', 2.78: 'bbb', True: 'ccc'}\n", - "foo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can even use built-in objects like types and functions:" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{int: 1, float: 2, bool: 3}" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = {int: 1, float: 2, bool: 3}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[float]" - ] - }, - { - "cell_type": "code", - "execution_count": 139, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 139, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = {bin: 1, hex: 2, oct: 3}\n", - "d[oct]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "However, there are a couple restrictions that dictionary keys must abide by." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, a given key can appear in a dictionary only once. Duplicate keys are not allowed. A dictionary maps each key to a corresponding value, so it doesn’t make sense to map a particular key more than once." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You saw above that when you assign a value to an already existing dictionary key, it does not add the key a second time, but replaces the existing value:" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [], - "source": [ - "MLB_team = {\n", - " 'Colorado' : 'Rockies',\n", - " 'Boston' : 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle' : 'Mariners'\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Timberwolves',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle': 'Mariners'}" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team['Minnesota'] = 'Timberwolves'\n", - "MLB_team" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly, if you specify a key a second time during the initial creation of a dictionary, the second occurrence will override the first:" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle': 'Mariners'}" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MLB_team = {\n", - " 'Colorado' : 'Rockies',\n", - " 'Boston' : 'Red Sox',\n", - " 'Minnesota': 'Timberwolves',\n", - " 'Milwaukee': 'Brewers',\n", - " 'Seattle' : 'Mariners',\n", - " 'Minnesota': 'Twins'\n", - "}\n", - "MLB_team" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Secondly, a dictionary key must be of a type that is immutable. You have already seen examples where several of the immutable types you are familiar with—integer, float, string, and Boolean—have served as dictionary keys." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A tuple can also be a dictionary key, because tuples are immutable:" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [], - "source": [ - "d = {(1, 1): 'a', (1, 2): 'b', (2, 1): 'c', (2, 2): 'd'}" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'a'" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[(1,1)]" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'c'" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[(2,1)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> Recall from the discussion on tuples that one rationale for using a tuple instead of a list is that there are circumstances where an immutable type is required. This is one of them." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "However, neither a list nor another dictionary can serve as a dictionary key, because lists and dictionaries are mutable:" - ] - }, - { - "cell_type": "code", - "execution_count": 102, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "unhashable type: 'list'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'a'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'b'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'c'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'd'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'" - ] - } - ], - "source": [ - "d = {[1, 1]: 'a', [1, 2]: 'b', [2, 1]: 'c', [2, 2]: 'd'}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Technical Note:** Why does the error message say “unhashable”?\n", - ">\n", - "> Technically, it is not quite correct to say an object must be immutable to be used as a dictionary key. More precisely, an object must be hashable, which means it can be passed to a hash function. A hash function takes data of arbitrary size and maps it to a relatively simpler fixed-size value called a hash value (or simply hash), which is used for table lookup and comparison.\n", - "> \n", - "> Python’s built-in hash() function returns the hash value for an object which is hashable, and raises an exception for an object which isn’t:\n", - ">\n", - "```python\n", - ">>> hash('foo')\n", - "11132615637596761\n", - "\n", - ">>> hash([1, 2, 3])\n", - "Traceback (most recent call last):\n", - " File \"\", line 1, in \n", - "TypeError: unhashable type: 'list'\n", - "```\n", - ">\n", - "> All of the built-in immutable types you have learned about so far are hashable, and the mutable container types (lists and dictionaries) are not. So for present purposes, you can think of hashable and immutable as more or less synonymous.\n", - "> \n", - "> In future tutorials, you will encounter mutable objects which are also hashable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Restrictions on Dictionary Values\n", - "By contrast, there are no restrictions on dictionary values. Literally none at all. A dictionary value can be any type of object Python supports, including mutable types like lists and dictionaries, and user-defined objects, which you will learn about in upcoming tutorials." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There is also no restriction against a particular value appearing in a dictionary multiple times:" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{0: 'a', 1: 'a', 2: 'a', 3: 'a'}" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = {0: 'a', 1: 'a', 2: 'a', 3: 'a'}\n", - "d" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[0] == d[1] == d[2]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "In this tutorial, you covered the basic properties of the Python **dictionary** and learned how to access and manipulate dictionary data." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Lists** and **dictionaries** are two of the most frequently used Python types. As you have seen, they have several similarities, but differ in how their elements are accessed. Lists elements are accessed by numerical index based on order, and dictionary elements are accessed by key" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Because of this difference, lists and dictionaries tend to be appropriate for different circumstances. You should now have a good feel for which, if either, would be best for a given situation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next you will learn about Python **sets**. The set is another composite data type, but it is quite different from either a list or dictionary." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Dictionary\n", "\n", "Python provides another composite data type called a dictionary, which is similar to a list in that it is a collection of objects."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Defining a Dictionary](#defining_a_dictionary)\n* [Accessing Dictionary Values](#accessing_dictionary_values)\n* [Dictionary Keys vs. List Indices](#dictionary_keys_vs._list_indices)\n* [Building a Dictionary Incrementally](#building_a_dictionary_incrementally)\n* [Restrictions on Dictionary Keys](#restrictions_on_dictionary_keys)\n* [Restrictions on Dictionary Values](#restrictions_on_dictionary_values)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Dictionaries and lists share the following characteristics:\n", "\n", "- Both are mutable.\n", "- Both are dynamic. They can grow and shrink as needed.\n", "- Both can be nested. A list can contain another list. A dictionary can contain another dictionary. A dictionary can also contain a list, and vice versa."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Dictionaries differ from lists primarily in how elements are accessed:\n", "\n", "- List elements are accessed by their position in the list, via indexing.\n", "- Dictionary elements are accessed via keys."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Defining a Dictionary\n", "Dictionaries are Python\u2019s implementation of a data structure that is more generally known as an associative array. A dictionary consists of a collection of key-value pairs. Each key-value pair maps the key to its associated value."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can define a dictionary by enclosing a comma-separated list of key-value pairs in curly braces (`{}`). A colon (`:`) separates each key from its associated value:\n", "\n", "```python\n", "d = {\n", " : ,\n", " : ,\n", " .\n", " .\n", " .\n", " : \n", "}\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The following defines a dictionary that maps a location to the name of its corresponding Major League Baseball team:"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["MLB_team = {\n", " 'Colorado' : 'Rockies',\n", " 'Boston' : 'Red Sox',\n", " 'Minnesota': 'Twins',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle' : 'Mariners'\n", "}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\"dictionary\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can also construct a dictionary with the built-in `dict()` function. The argument to `dict()` should be a sequence of key-value pairs. A list of tuples works well for this:\n", "\n", "```python\n", "d = dict([\n", " (, ),\n", " (, , )\n", "])\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`MLB_team` can then also be defined this way:"]}, {"cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": ["MLB_team = dict([\n", " ('Colorado', 'Rockies'),\n", " ('Boston', 'Red Sox'),\n", " ('Minnesota', 'Twins'),\n", " ('Milwaukee', 'Brewers'),\n", " ('Seattle', 'Mariners')\n", "])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If the key values are simple strings, they can be specified as keyword arguments. So here is yet another way to define `MLB_team`:"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["MLB_team = dict(\n", " Colorado='Rockies',\n", " Boston='Red Sox',\n", " Minnesota='Twins',\n", " Milwaukee='Brewers',\n", " Seattle='Mariners'\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Once you\u2019ve defined a dictionary, you can display its contents, the same as you can do for a list. All three of the definitions shown above appear as follows when displayed:"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": ["dict"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["type(MLB_team)"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'Colorado': 'Rockies',\n", " 'Boston': 'Red Sox',\n", " 'Minnesota': 'Twins',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle': 'Mariners'}"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The entries in the dictionary display in the order they were defined. But that is irrelevant when it comes to retrieving them. Dictionary elements are not accessed by numerical index:"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"ename": "NameError", "evalue": "name 'MLB_team' is not defined", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/1469821463.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined"]}], "source": ["MLB_team[1]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Accessing Dictionary Values\n", "\n", "Of course, dictionary elements must be accessible somehow. If you don\u2019t get them by index, then how do you get them?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A value is retrieved from a dictionary by specifying its corresponding key in square brackets (`[]`):"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"text/plain": ["'Twins'"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team['Minnesota']"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/plain": ["'Rockies'"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team['Colorado']"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you refer to a key that is not in the dictionary, Python raises an exception:"]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"ename": "KeyError", "evalue": "'Toronto'", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Toronto'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 'Toronto'"]}], "source": ["MLB_team['Toronto']"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Adding an entry to an existing dictionary is simply a matter of assigning a new key and value:"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'Colorado': 'Rockies',\n", " 'Boston': 'Red Sox',\n", " 'Minnesota': 'Twins',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle': 'Mariners',\n", " 'Kansas City': 'Royals'}"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team['Kansas City'] = 'Royals'\n", "MLB_team"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you want to update an entry, you can just assign a new value to an existing key:"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'Colorado': 'Rockies',\n", " 'Boston': 'Red Sox',\n", " 'Minnesota': 'Twins',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle': 'Seahawks',\n", " 'Kansas City': 'Royals'}"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team['Seattle'] = 'Seahawks'\n", "MLB_team"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To delete an entry, use the `del` statement, specifying the key to delete:"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"ename": "NameError", "evalue": "name 'MLB_team' is not defined", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3737734966.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mdel\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Seattle'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined"]}], "source": ["del MLB_team['Seattle']\n", "MLB_team"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Dictionary Keys vs. List Indices\n", "You may have noticed that the interpreter raises the same exception, KeyError, when a dictionary is accessed with either an undefined key or by a numeric index:"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"ename": "KeyError", "evalue": "'Toronto'", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Toronto'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 'Toronto'"]}], "source": ["MLB_team['Toronto']"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"ename": "KeyError", "evalue": "1", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 1"]}], "source": ["MLB_team[1]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In fact, it\u2019s the same error. In the latter case, `[1]` looks like a numerical index, but it isn\u2019t."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You will see later in this tutorial that an object of any immutable type can be used as a dictionary key. Accordingly, there is no reason you can\u2019t use integers:"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["{0: 'a', 1: 'b', 2: 'c', 3: 'd'}"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["d = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}\n", "d"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"data": {"text/plain": ["'a'"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["d[0]"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/plain": ["'c'"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["d[2]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the expressions `MLB_team[1]`, `d[0]`, and `d[2]`, the numbers in square brackets appear as though they might be indices. But they have nothing to do with the order of the items in the dictionary. Python is interpreting them as dictionary keys. If you define this same dictionary in reverse order, you still get the same values using the same keys:"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"data": {"text/plain": ["{3: 'd', 2: 'c', 1: 'b', 0: 'a'}"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["d = {3: 'd', 2: 'c', 1: 'b', 0: 'a'}\n", "d"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/plain": ["'a'"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["d[0]"]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [{"data": {"text/plain": ["'c'"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["d[2]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The syntax may look similar, but you can\u2019t treat a dictionary like a list:"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/plain": ["dict"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["type(d)"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"ename": "KeyError", "evalue": "-1", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: -1"]}], "source": ["d[-1]"]}, {"cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [{"ename": "NameError", "evalue": "name 'd' is not defined", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3015485889.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'd' is not defined"]}], "source": ["d[0:2]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Although access to items in a dictionary does not depend on order, Python does guarantee that the order of items in a dictionary is preserved. When displayed, items will appear in the order they were defined, and iteration through the keys will occur in that order as well. Items added to a dictionary are added at the end. If items are deleted, the order of the remaining items is retained.\n", ">\n", ">You can only count on this preservation of order very recently. It was [added as a part of the Python language specification in version 3.7](https://realpython.com/python37-new-features/#the-order-of-dictionaries-is-guaranteed). However, it was true as of version 3.6 as well\u2014by happenstance as a result of the implementation but not guaranteed by the language specification."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Building a Dictionary Incrementally\n", "\n", "Defining a dictionary using curly braces and a list of key-value pairs, as shown above, is fine if you know all the keys and values in advance. But what if you want to build a dictionary on the fly?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can start by creating an empty dictionary, which is specified by empty curly braces. Then you can add new keys and values one at a time:"]}, {"cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [{"data": {"text/plain": ["dict"]}, "execution_count": 118, "metadata": {}, "output_type": "execute_result"}], "source": ["person = {}\n", "type(person)"]}, {"cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": ["person['fname'] = 'Joe'\n", "person['lname'] = 'Fonebone'\n", "person['age'] = 51\n", "person['spouse'] = 'Edna'\n", "person['children'] = ['Ralph', 'Betty', 'Joey']\n", "person['pets'] = {'dog': 'Fido', 'cat': 'Sox'}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Once the dictionary is created in this way, its values are accessed the same way as any other dictionary:"]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'fname': 'Joe',\n", " 'lname': 'Fonebone',\n", " 'age': 51,\n", " 'spouse': 'Edna',\n", " 'children': ['Ralph', 'Betty', 'Joey'],\n", " 'pets': {'dog': 'Fido', 'cat': 'Sox'}}"]}, "execution_count": 28, "metadata": {}, "output_type": "execute_result"}], "source": ["person"]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"data": {"text/plain": ["'Joe'"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["person['fname']"]}, {"cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [{"data": {"text/plain": ["51"]}, "execution_count": 30, "metadata": {}, "output_type": "execute_result"}], "source": ["person['age']"]}, {"cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [{"data": {"text/plain": ["['Ralph', 'Betty', 'Joey']"]}, "execution_count": 31, "metadata": {}, "output_type": "execute_result"}], "source": ["person['children']"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Retrieving the values in the sublist or subdictionary requires an additional index or key:"]}, {"cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [{"data": {"text/plain": ["'Joey'"]}, "execution_count": 32, "metadata": {}, "output_type": "execute_result"}], "source": ["person['children'][-1]"]}, {"cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [{"data": {"text/plain": ["'Sox'"]}, "execution_count": 33, "metadata": {}, "output_type": "execute_result"}], "source": ["person['pets']['cat']"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This example exhibits another feature of dictionaries: the values contained in the dictionary don\u2019t need to be the same type. In person, some of the values are strings, one is an integer, one is a list, and one is another dictionary."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Just as the values in a dictionary don\u2019t need to be of the same type, the keys don\u2019t either:"]}, {"cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [{"data": {"text/plain": ["{42: 'aaa', 2.78: 'bbb', True: 'ccc'}"]}, "execution_count": 34, "metadata": {}, "output_type": "execute_result"}], "source": ["foo = {42: 'aaa', 2.78: 'bbb', True: 'ccc'}\n", "foo"]}, {"cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [{"data": {"text/plain": ["'aaa'"]}, "execution_count": 35, "metadata": {}, "output_type": "execute_result"}], "source": ["foo[42]"]}, {"cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [{"data": {"text/plain": ["'bbb'"]}, "execution_count": 36, "metadata": {}, "output_type": "execute_result"}], "source": ["foo[2.78]"]}, {"cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [{"data": {"text/plain": ["'ccc'"]}, "execution_count": 37, "metadata": {}, "output_type": "execute_result"}], "source": ["foo[True]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, one of the keys is an integer, one is a float, and one is a Boolean. It\u2019s not obvious how this would be useful, but you never know."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Notice how versatile Python dictionaries are. In MLB_team, the same piece of information (the baseball team name) is kept for each of several different geographical locations. person, on the other hand, stores varying types of data for a single person."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can use dictionaries for a wide range of purposes because there are so few limitations on the keys and values that are allowed. But there are some. Read on!"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Restrictions on Dictionary Keys\n", "\n", "Almost any type of value can be used as a dictionary key in Python. You just saw this example, where integer, float, and Boolean objects are used as keys:"]}, {"cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [{"data": {"text/plain": ["{42: 'aaa', 2.78: 'bbb', True: 'ccc'}"]}, "execution_count": 38, "metadata": {}, "output_type": "execute_result"}], "source": ["foo = {42: 'aaa', 2.78: 'bbb', True: 'ccc'}\n", "foo"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can even use built-in objects like types and functions:"]}, {"cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [{"data": {"text/plain": ["{int: 1, float: 2, bool: 3}"]}, "execution_count": 39, "metadata": {}, "output_type": "execute_result"}], "source": ["d = {int: 1, float: 2, bool: 3}\n", "d"]}, {"cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [{"data": {"text/plain": ["2"]}, "execution_count": 40, "metadata": {}, "output_type": "execute_result"}], "source": ["d[float]"]}, {"cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [{"data": {"text/plain": ["3"]}, "execution_count": 139, "metadata": {}, "output_type": "execute_result"}], "source": ["d = {bin: 1, hex: 2, oct: 3}\n", "d[oct]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["However, there are a couple restrictions that dictionary keys must abide by."]}, {"cell_type": "markdown", "metadata": {}, "source": ["First, a given key can appear in a dictionary only once. Duplicate keys are not allowed. A dictionary maps each key to a corresponding value, so it doesn\u2019t make sense to map a particular key more than once."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You saw above that when you assign a value to an already existing dictionary key, it does not add the key a second time, but replaces the existing value:"]}, {"cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": ["MLB_team = {\n", " 'Colorado' : 'Rockies',\n", " 'Boston' : 'Red Sox',\n", " 'Minnesota': 'Twins',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle' : 'Mariners'\n", "}"]}, {"cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'Colorado': 'Rockies',\n", " 'Boston': 'Red Sox',\n", " 'Minnesota': 'Timberwolves',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle': 'Mariners'}"]}, "execution_count": 43, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team['Minnesota'] = 'Timberwolves'\n", "MLB_team"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Similarly, if you specify a key a second time during the initial creation of a dictionary, the second occurrence will override the first:"]}, {"cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'Colorado': 'Rockies',\n", " 'Boston': 'Red Sox',\n", " 'Minnesota': 'Twins',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle': 'Mariners'}"]}, "execution_count": 44, "metadata": {}, "output_type": "execute_result"}], "source": ["MLB_team = {\n", " 'Colorado' : 'Rockies',\n", " 'Boston' : 'Red Sox',\n", " 'Minnesota': 'Timberwolves',\n", " 'Milwaukee': 'Brewers',\n", " 'Seattle' : 'Mariners',\n", " 'Minnesota': 'Twins'\n", "}\n", "MLB_team"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Secondly, a dictionary key must be of a type that is immutable. You have already seen examples where several of the immutable types you are familiar with\u2014integer, float, string, and Boolean\u2014have served as dictionary keys."]}, {"cell_type": "markdown", "metadata": {}, "source": ["A tuple can also be a dictionary key, because tuples are immutable:"]}, {"cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": ["d = {(1, 1): 'a', (1, 2): 'b', (2, 1): 'c', (2, 2): 'd'}"]}, {"cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [{"data": {"text/plain": ["'a'"]}, "execution_count": 46, "metadata": {}, "output_type": "execute_result"}], "source": ["d[(1,1)]"]}, {"cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [{"data": {"text/plain": ["'c'"]}, "execution_count": 47, "metadata": {}, "output_type": "execute_result"}], "source": ["d[(2,1)]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> Recall from the discussion on tuples that one rationale for using a tuple instead of a list is that there are circumstances where an immutable type is required. This is one of them."]}, {"cell_type": "markdown", "metadata": {}, "source": ["However, neither a list nor another dictionary can serve as a dictionary key, because lists and dictionaries are mutable:"]}, {"cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "unhashable type: 'list'", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'a'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'b'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'c'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'd'\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'"]}], "source": ["d = {[1, 1]: 'a', [1, 2]: 'b', [2, 1]: 'c', [2, 2]: 'd'}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Technical Note:** Why does the error message say \u201cunhashable\u201d?\n", ">\n", "> Technically, it is not quite correct to say an object must be immutable to be used as a dictionary key. More precisely, an object must be hashable, which means it can be passed to a hash function. A hash function takes data of arbitrary size and maps it to a relatively simpler fixed-size value called a hash value (or simply hash), which is used for table lookup and comparison.\n", "> \n", "> Python\u2019s built-in hash() function returns the hash value for an object which is hashable, and raises an exception for an object which isn\u2019t:\n", ">\n", "```python\n", ">>> hash('foo')\n", "11132615637596761\n", "\n", ">>> hash([1, 2, 3])\n", "Traceback (most recent call last):\n", " File \"\", line 1, in \n", "TypeError: unhashable type: 'list'\n", "```\n", ">\n", "> All of the built-in immutable types you have learned about so far are hashable, and the mutable container types (lists and dictionaries) are not. So for present purposes, you can think of hashable and immutable as more or less synonymous.\n", "> \n", "> In future tutorials, you will encounter mutable objects which are also hashable."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Restrictions on Dictionary Values\n", "By contrast, there are no restrictions on dictionary values. Literally none at all. A dictionary value can be any type of object Python supports, including mutable types like lists and dictionaries, and user-defined objects, which you will learn about in upcoming tutorials."]}, {"cell_type": "markdown", "metadata": {}, "source": ["There is also no restriction against a particular value appearing in a dictionary multiple times:"]}, {"cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [{"data": {"text/plain": ["{0: 'a', 1: 'a', 2: 'a', 3: 'a'}"]}, "execution_count": 49, "metadata": {}, "output_type": "execute_result"}], "source": ["d = {0: 'a', 1: 'a', 2: 'a', 3: 'a'}\n", "d"]}, {"cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 50, "metadata": {}, "output_type": "execute_result"}], "source": ["d[0] == d[1] == d[2]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "In this tutorial, you covered the basic properties of the Python **dictionary** and learned how to access and manipulate dictionary data."]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Lists** and **dictionaries** are two of the most frequently used Python types. As you have seen, they have several similarities, but differ in how their elements are accessed. Lists elements are accessed by numerical index based on order, and dictionary elements are accessed by key"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Because of this difference, lists and dictionaries tend to be appropriate for different circumstances. You should now have a good feel for which, if either, would be best for a given situation."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Next you will learn about Python **sets**. The set is another composite data type, but it is quite different from either a list or dictionary."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/10 Composite Data Types: Sets.ipynb b/python/01. Basics/10 Composite Data Types: Sets.ipynb index 95d2b14..72f80d5 100755 --- a/python/01. Basics/10 Composite Data Types: Sets.ipynb +++ b/python/01. Basics/10 Composite Data Types: Sets.ipynb @@ -1,665 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Set\n", - "\n", - "In mathematics, a rigorous definition of a set can be abstract and difficult to grasp. Practically though, a set can be thought of simply as a well-defined collection of distinct objects, typically called **elements** or **members**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Grouping objects into a set can be useful in programming as well, and Python provides a built-in set type to do so. Sets are distinguished from other object types by the unique operations that can be performed on them." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Defining a Set\n", - "\n", - "Python’s built-in set type has the following characteristics:\n", - "\n", - "- Sets are unordered.\n", - "- Set elements are unique. Duplicate elements are not allowed.\n", - "- A set itself may be modified, but the elements contained in the set must be of an immutable type." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let’s see what all that means, and how you can work with sets in Python.\n", - "\n", - "A set can be created in two ways. First, you can define a set with the built-in `set()` function:\n", - "\n", - "```python\n", - "x = set()\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this case, the argument `` is an iterable—again, for the moment, think list or tuple—that generates the list of objects to be included in the set. This is analogous to the `` argument given to the `.extend()` list method:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bar', 'baz', 'foo', 'qux'}" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = set(['foo', 'bar', 'baz', 'foo', 'qux'])\n", - "x" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bar', 'baz', 'foo', 'qux'}" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = set(('foo', 'bar', 'baz', 'foo', 'qux'))\n", - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Strings are also iterable, so a string can be passed to `set()` as well. You have already seen that `list(s)` generates a list of the characters in the string `s`. Similarly, `set(s)` generates a set of the characters in `s`:" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [], - "source": [ - "s = 'quux'" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['q', 'u', 'u', 'x']" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(s)" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'q', 'u', 'x'}" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "set(s)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can see that the resulting sets are unordered: the original order, as specified in the definition, is not necessarily preserved. Additionally, duplicate values are only represented in the set once, as with the string `'foo'` in the first two examples and the letter `'u'` in the third." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Alternately, a set can be defined with curly braces (`{}`):\n", - "\n", - "```python\n", - "x = {, , ..., }\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When a set is defined this way, each `` becomes a distinct element of the set, even if it is an iterable. This behavior is similar to that of the `.append()` list method." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Thus, the sets shown above can also be defined like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bar', 'baz', 'foo', 'qux'}" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = {'foo', 'bar', 'baz', 'foo', 'qux'}\n", - "x" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'q', 'u', 'x'}" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = {'q', 'u', 'u', 'x'}\n", - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To recap:\n", - "\n", - "- The argument to `set()` is an iterable. It generates a list of elements to be placed into the set.\n", - "- The objects in curly braces are placed into the set intact, even if they are iterable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Observe the difference between these two set definitions:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'foo'}" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "{'foo'}" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'f', 'o'}" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "set('foo')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A set can be empty. However, recall that Python interprets empty curly braces (`{}`) as an empty dictionary, so the only way to define an empty set is with the `set()` function:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "set" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = set()\n", - "type(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "set()" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = {}\n", - "type(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "An empty set is falsy in a Boolean context:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = set()\n", - "bool(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x or 1" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "set()" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x and 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You might think the most intuitive sets would contain similar objects—for example, even numbers or surnames:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "s1 = {2, 4, 6, 8, 10}\n", - "s2 = {'Smith', 'McArthur', 'Wilson', 'Johansson'}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python does not require this, though. The elements in a set can be objects of different types:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{3.14159, 42, None, 'foo'}" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = {42, 'foo', 3.14159, None}\n", - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Don’t forget that set elements must be immutable (you will later learn that the objects must actually be hashable). For example, a tuple may be included in a set:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{(1, 2, 3), 3.14159, 42, 'foo'}" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = {42, 'foo', (1, 2, 3), 3.14159}\n", - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But lists and dictionaries are mutable, so they can’t be set elements:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "unhashable type: 'list'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m{\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'" - ] - } - ], - "source": [ - "a = [1, 2, 3]\n", - "{a}" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "unhashable type: 'dict'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m'a'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'b'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m{\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'dict'" - ] - } - ], - "source": [ - "d = {'a': 1, 'b': 2}\n", - "{d}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Set Size and Membership\n", - "\n", - "The `len()` function returns the number of elements in a set, and the `in` and `not in` operators can be used to test for membership:" - ] - }, - { - "cell_type": "code", - "execution_count": 107, - "metadata": {}, - "outputs": [], - "source": [ - "x = {'foo', 'bar', 'baz'}" - ] - }, - { - "cell_type": "code", - "execution_count": 108, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'bar' in x" - ] - }, - { - "cell_type": "code", - "execution_count": 243, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 243, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'qux' in x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "\n", - "In this tutorial, you learned how to define set objects in Python, and you became familiar with the functions, operators, and methods that can be used to work with sets." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You should now be comfortable with the basic built-in data types that Python provides." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, you will begin to explore how the code that operates on those objects is organized and structured in a Python program." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Set\n", "\n", "In mathematics, a rigorous definition of a set can be abstract and difficult to grasp. Practically though, a set can be thought of simply as a well-defined collection of distinct objects, typically called **elements** or **members**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Defining a Set](#defining_a_set)\n* [Set Size and Membership](#set_size_and_membership)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Grouping objects into a set can be useful in programming as well, and Python provides a built-in set type to do so. Sets are distinguished from other object types by the unique operations that can be performed on them."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Defining a Set\n", "\n", "Python\u2019s built-in set type has the following characteristics:\n", "\n", "- Sets are unordered.\n", "- Set elements are unique. Duplicate elements are not allowed.\n", "- A set itself may be modified, but the elements contained in the set must be of an immutable type."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Let\u2019s see what all that means, and how you can work with sets in Python.\n", "\n", "A set can be created in two ways. First, you can define a set with the built-in `set()` function:\n", "\n", "```python\n", "x = set()\n", "```"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": ["x = {3, 8, 1}"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["8\n", "1\n", "3\n"]}], "source": ["for item in x:\n", " print(item)"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": ["x = {}"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["a\n", "e\n", "h\n", "l\n", "s\n"]}], "source": ["for char in 'abcdefghijklmnopqrstuvwxyz':\n", " hash_value = hash(char)\n", " hash_hash_value = hash(hash_value)\n", " \n", " if hash_value == hash_hash_value:\n", " print(char)"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/plain": ["1753726360175525413"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["hash('a')"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": ["x = {\n", " 'a': 1,\n", " 1753726360175525413: 2,\n", "}"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'a': 1, 1753726360175525413: 2}"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["x"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [{"data": {"text/plain": ["5603912153990001835"]}, "execution_count": 25, "metadata": {}, "output_type": "execute_result"}], "source": ["hash('a str')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this case, the argument `` is an iterable\u2014again, for the moment, think list or tuple\u2014that generates the list of objects to be included in the set. This is analogous to the `` argument given to the `.extend()` list method:"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'bar', 'baz', 'foo', 'qux'}"]}, "execution_count": 1, "metadata": {}, "output_type": "execute_result"}], "source": ["x = set(['foo', 'bar', 'baz', 'foo', 'qux'])\n", "x"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'bar', 'baz', 'foo', 'qux'}"]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["x = set(('foo', 'bar', 'baz', 'foo', 'qux'))\n", "x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Strings are also iterable, so a string can be passed to `set()` as well. You have already seen that `list(s)` generates a list of the characters in the string `s`. Similarly, `set(s)` generates a set of the characters in `s`:"]}, {"cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": ["s = 'quux'"]}, {"cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [{"data": {"text/plain": ["['q', 'u', 'u', 'x']"]}, "execution_count": 46, "metadata": {}, "output_type": "execute_result"}], "source": ["list(s)"]}, {"cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'q', 'u', 'x'}"]}, "execution_count": 64, "metadata": {}, "output_type": "execute_result"}], "source": ["set(s)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can see that the resulting sets are unordered: the original order, as specified in the definition, is not necessarily preserved. Additionally, duplicate values are only represented in the set once, as with the string `'foo'` in the first two examples and the letter `'u'` in the third."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Alternately, a set can be defined with curly braces (`{}`):\n", "\n", "```python\n", "x = {, , ..., }\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["When a set is defined this way, each `` becomes a distinct element of the set, even if it is an iterable. This behavior is similar to that of the `.append()` list method."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Thus, the sets shown above can also be defined like this:"]}, {"cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'bar', 'baz', 'foo', 'qux'}"]}, "execution_count": 67, "metadata": {}, "output_type": "execute_result"}], "source": ["x = {'foo', 'bar', 'baz', 'foo', 'qux'}\n", "x"]}, {"cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'q', 'u', 'x'}"]}, "execution_count": 68, "metadata": {}, "output_type": "execute_result"}], "source": ["x = {'q', 'u', 'u', 'x'}\n", "x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To recap:\n", "\n", "- The argument to `set()` is an iterable. It generates a list of elements to be placed into the set.\n", "- The objects in curly braces are placed into the set intact, even if they are iterable."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Observe the difference between these two set definitions:"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'foo'}"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["{'foo'}"]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'f', 'o'}"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["set('foo')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A set can be empty. However, recall that Python interprets empty curly braces (`{}`) as an empty dictionary, so the only way to define an empty set is with the `set()` function:"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/plain": ["set"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["x = set()\n", "type(x)"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/plain": ["set()"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["x"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["dict"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["x = {}\n", "type(x)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["An empty set is falsy in a Boolean context:"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["x = set()\n", "bool(x)"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"data": {"text/plain": ["1"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["x or 1"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["set()"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["x and 1"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You might think the most intuitive sets would contain similar objects\u2014for example, even numbers or surnames:"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": ["s1 = {2, 4, 6, 8, 10}\n", "s2 = {'Smith', 'McArthur', 'Wilson', 'Johansson'}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python does not require this, though. The elements in a set can be objects of different types:"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"data": {"text/plain": ["{3.14159, 42, None, 'foo'}"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["x = {42, 'foo', 3.14159, None}\n", "x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Don\u2019t forget that set elements must be immutable (you will later learn that the objects must actually be hashable). For example, a tuple may be included in a set:"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/plain": ["{(1, 2, 3), 3.14159, 42, 'foo'}"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["x = {42, 'foo', (1, 2, 3), 3.14159}\n", "x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["But lists and dictionaries are mutable, so they can\u2019t be set elements:"]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "unhashable type: 'list'", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m{\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'"]}], "source": ["a = [1, 2, 3]\n", "{a}"]}, {"cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "unhashable type: 'dict'", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m'a'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'b'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m{\u001b[0m\u001b[0md\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'dict'"]}], "source": ["d = {'a': 1, 'b': 2}\n", "{d}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Set Size and Membership\n", "\n", "The `len()` function returns the number of elements in a set, and the `in` and `not in` operators can be used to test for membership:"]}, {"cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [], "source": ["x = {'foo', 'bar', 'baz'}"]}, {"cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [{"data": {"text/plain": ["3"]}, "execution_count": 108, "metadata": {}, "output_type": "execute_result"}], "source": ["len(x)"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 26, "metadata": {}, "output_type": "execute_result"}], "source": ["'bar' in x"]}, {"cell_type": "code", "execution_count": 243, "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 243, "metadata": {}, "output_type": "execute_result"}], "source": ["'qux' in x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "\n", "In this tutorial, you learned how to define set objects in Python, and you became familiar with the functions, operators, and methods that can be used to work with sets."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You should now be comfortable with the basic built-in data types that Python provides."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Next, you will begin to explore how the code that operates on those objects is organized and structured in a Python program."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/11 Python Program Lexical Structure.ipynb b/python/01. Basics/11 Python Program Lexical Structure.ipynb index 66b89c9..120b565 100755 --- a/python/01. Basics/11 Python Program Lexical Structure.ipynb +++ b/python/01. Basics/11 Python Program Lexical Structure.ipynb @@ -1,1858 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Python Program Lexical Structure\n", - "\n", - "You have now covered Python variables, operators, and data types in depth, and you’ve seen quite a bit of example code. Up to now, the code has consisted of short individual statements, simply assigning objects to variables or displaying values.\n", - "\n", - "But you want to do more than just define data and display it! Let’s start arranging code into more complex groupings." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Python Statements\n", - "\n", - "Statements are the basic units of instruction that the Python interpreter parses and processes. In general, the interpreter executes statements sequentially, one after the next as it encounters them. (You will see in the next tutorial on conditional statements that it is possible to alter this behavior.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In a REPL session, statements are executed as they are typed in, until the interpreter is terminated. When you execute a script file, the interpreter reads statements from the file and executes them until end-of-file is encountered." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python programs are typically organized with one statement per line. In other words, each statement occupies a single line, with the end of the statement delimited by the newline character that marks the end of the line. The majority of the examples so far in this tutorial series have followed this pattern:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello, World!\n" - ] - } - ], - "source": [ - "print('Hello, World!')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[2]\n" - ] - } - ], - "source": [ - "x = [1, 2, 3]\n", - "print(x[1:2])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Line Continuation\n", - "\n", - "Suppose a single statement in your Python code is especially long. For example, you may have an assignment statement with many terms:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "person1_age = 42\n", - "person2_age = 16\n", - "person3_age = 71" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "someone_is_of_working_age = (person1_age >= 18 and person1_age <= 65) or (person2_age >= 18 and person2_age <= 65) or (person3_age >= 18 and person3_age <= 65)\n", - "someone_is_of_working_age" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or perhaps you are defining a lengthy nested list:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[[1, 2, 3, 4, 5],\n", - " [6, 7, 8, 9, 10],\n", - " [11, 12, 13, 14, 15],\n", - " [16, 17, 18, 19, 20],\n", - " [21, 22, 23, 24, 25]]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]\n", - "a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You’ll notice that these statements are too long to fit in your browser window, and the browser is forced to render the code blocks with horizontal scroll bars. You may find that irritating. (You have our apologies—these examples are presented that way to make the point. It won’t happen again.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is equally frustrating when lengthy statements like these are contained in a script file. Most editors can be configured to wrap text, so that the ends of long lines are at least visible and don’t disappear out the right edge of the editor window. But the wrapping doesn’t necessarily occur in logical locations that enhance readability:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"line-wrap\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Excessively long lines of code are generally considered poor practice. In fact, there is an official [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008) put forth by the Python Software Foundation, and one of its stipulations is that the [maximum line length](https://www.python.org/dev/peps/pep-0008/#maximum-line-length) in Python code should be 79 characters." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** The **Style Guide for Python Code** is also referred to as **PEP 8**. PEP stands for Python Enhancement Proposal. PEPs are documents that contain details about features, standards, design issues, general guidelines, and information relating to Python. For more information, see the Python Software Foundation [Index of PEPs](https://www.python.org/dev/peps)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As code becomes more complex, statements will on occasion unavoidably grow long. To maintain readability, you should break them up into parts across several lines. But you can’t just split a statement whenever and wherever you like. Unless told otherwise, the interpreter assumes that a newline character terminates a statement. If the statement isn’t syntactically correct at that point, an exception is raised:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (1911760183.py, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_50053/1911760183.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python code, a statement can be continued from one line to the next in two different ways: implicit and explicit line continuation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Implicit Line Continuation\n", - "\n", - "This is the more straightforward technique for line continuation, and the one that is preferred according to PEP 8." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Any statement containing opening parentheses (`'('`), brackets (`'['`), or curly braces (`'{'`) is presumed to be incomplete until all matching parentheses, brackets, and braces have been encountered. Until then, the statement can be implicitly continued across lines without raising an error." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, the nested list definition from above can be made much more readable using implicit line continuation because of the open brackets:" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "a = [\n", - " [1, 2, 3, 4, 5],\n", - " [6, 7, 8, 9, 10],\n", - " [11, 12, 13, 14, 15],\n", - " [16, 17, 18, 19, 20],\n", - " [21, 22, 23, 24, 25]\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[[1, 2, 3, 4, 5],\n", - " [6, 7, 8, 9, 10],\n", - " [11, 12, 13, 14, 15],\n", - " [16, 17, 18, 19, 20],\n", - " [21, 22, 23, 24, 25]]" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A long expression can also be continued across multiple lines by wrapping it in grouping parentheses. PEP 8 explicitly advocates using parentheses in this manner when appropriate:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "someone_is_of_working_age = (\n", - " (person1_age >= 18 and person1_age <= 65)\n", - " or (person2_age >= 18 and person2_age <= 65)\n", - " or (person3_age >= 18 and person3_age <= 65)\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "someone_is_of_working_age" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you need to continue a statement across multiple lines, it is usually possible to use implicit line continuation to do so. This is because parentheses, brackets, and curly braces appear so frequently in Python syntax:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Parentheses\n", - "\n", - "- Expression grouping" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "x = (\n", - " 1 + 2\n", - " + 3 + 4\n", - " + 5 + 6\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "21" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Function call (functions will be covered later)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo bar baz\n" - ] - } - ], - "source": [ - "print(\n", - " 'foo',\n", - " 'bar',\n", - " 'baz'\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Method call (methods will be covered later)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'---abc---'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'abc'.center(\n", - " 9,\n", - " '-'\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Tuple definition" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "t = (\n", - " 'a', 'b',\n", - " 'c', 'd'\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Curly Braces" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Dictionary definition" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "d = {\n", - " 'a': 1,\n", - " 'b': 2\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Set definition" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "x1 = {\n", - " 'foo',\n", - " 'bar',\n", - " 'baz'\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Square Brackets" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- List definition" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "a = [\n", - " 'foo', 'bar',\n", - " 'baz', 'qux'\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Indexing" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[6, 7, 8, 9, 10]" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[\n", - " 1\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Slicing" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['bar']" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[\n", - " 1:2\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "- Dictionary key reference" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d[\n", - " 'b'\n", - "]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Just because something is syntactically allowed, it doesn’t mean you should do it. Some of the examples above would not typically be recommended. Splitting indexing, slicing, or dictionary key reference across lines, in particular, would be unusual. But you can consider it if you can make a good argument that it enhances readability." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Remember that if there are multiple parentheses, brackets, or curly braces, then implicit line continuation is in effect until they are all closed:" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [], - "source": [ - "a = [\n", - " [\n", - " ['foo', 'bar'],\n", - " [1, 2, 3]\n", - " ],\n", - " {1, 3, 5},\n", - " {\n", - " 'a': 1,\n", - " 'b': 2\n", - " }\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[[['foo', 'bar'], [1, 2, 3]], {1, 3, 5}, {'a': 1, 'b': 2}]" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note how line continuation and judicious use of indentation can be used to clarify the nested structure of the list." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Explicit Line Continuation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In cases where implicit line continuation is not readily available or practicable, there is another option. This is referred to as explicit line continuation or explicit line joining." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Ordinarily, a newline character (which you get when you press _Enter_ on your keyboard) indicates the end of a line. If the statement is not complete by that point, Python will raise a SyntaxError exception:" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m s =\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "s =" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m x = 1 + 2 +\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "x = 1 + 2 +" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To indicate explicit line continuation, you can specify a backslash (`\\`) character as the final character on the line. In that case, Python ignores the following newline, and the statement is effectively continued on next line:" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [], - "source": [ - "s = \\\n", - "'Hello, World!'" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Hello, World!'" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [], - "source": [ - "x = 1 + 2 \\\n", - " + 3 + 4 \\\n", - " + 5 + 6" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "21" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Note that the backslash character must be the last character on the line. Not even whitespace is allowed after it:**" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "unexpected character after line continuation character (, line 2)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m s = \\\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected character after line continuation character\n" - ] - } - ], - "source": [ - "# You can't see it, but there is a space character following the \\ here:\n", - "s = \\ " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Again, PEP 8 recommends using explicit line continuation only when implicit line continuation is not feasible." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Multiple Statements Per Line\n", - "\n", - "Multiple statements may occur on one line, if they are separated by a semicolon (`;`) character:" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [], - "source": [ - "x = 1; y = 2; z = 3" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "2\n", - "3\n" - ] - } - ], - "source": [ - "print(x); print(y); print(z)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Stylistically, this is generally frowned upon, and [PEP 8 expressly discourages it](https://www.python.org/dev/peps/pep-0008/?#other-recommendations). There might be situations where it improves readability, but it usually doesn’t. In fact, it often isn’t necessary. The following statements are functionally equivalent to the example above, but would be considered more typical Python code:" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [], - "source": [ - "x, y, z = 1, 2, 3" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "2\n", - "3\n" - ] - } - ], - "source": [ - "print(x, y, z, sep='\\n')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> The term **Pythonic** refers to code that adheres to generally accepted common guidelines for readability and “best” use of idiomatic Python. When someone says code is not Pythonic, they are implying that it does not express the programmer’s intent as well as might otherwise be done in Python. Thus, the code is probably not as readable as it could be to someone who is fluent in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you find your code has multiple statements on a line, there is probably a more Pythonic way to write it. But again, if you think it’s appropriate or enhances readability, you should feel free to do it." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Comments\n", - "\n", - "In Python, the hash character (`#`) signifies a comment. The interpreter will ignore everything from the hash character through the end of that line:" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz'] # I am a comment." - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz']" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If the first non-whitespace character on the line is a hash, the entire line is effectively ignored:" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [], - "source": [ - "# I am a comment.\n", - " # I am too." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Naturally, a hash character inside a string literal is protected, and does not indicate a comment:" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foobar # I am *not* a comment.'" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = 'foobar # I am *not* a comment.'\n", - "a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A comment is just ignored, so what purpose does it serve? Comments give you a way to attach explanatory detail to your code:" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate and display the area of a circle.\n", - "\n", - "pi = 3.1415926536\n", - "r = 12.35" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [], - "source": [ - "area = pi * (r ** 2)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The area of a circle with radius 12.35 is 479.163565508706\n" - ] - } - ], - "source": [ - "print('The area of a circle with radius', r, 'is', area)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Up to now, your Python coding has consisted mostly of short, isolated REPL sessions. In that setting, the need for comments is pretty minimal. Eventually, you will develop larger applications contained across multiple script files, and comments will become increasingly important." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Good commenting makes the intent of your code clear at a glance when someone else reads it, or even when you yourself read it. Ideally, you should strive to write code that is as clear, concise, and self-explanatory as possible. But there will be times that you will make design or implementation decisions that are not readily obvious from the code itself. That is where commenting comes in. Good code explains how; good comments explain why." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Comments can be included within implicit line continuation:" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [], - "source": [ - "x = (1 + 2 # I am a comment.\n", - " + 3 + 4 # Me too.\n", - " + 5 + 6)" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "21" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [], - "source": [ - "a = [\n", - " 'foo', 'bar', # Me three.\n", - " 'baz', 'qux'\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz', 'qux']" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But recall that explicit line continuation requires the backslash character to be the last character on the line. Thus, a comment can’t follow afterward:" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "unexpected character after line continuation character (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m x = 1 + 2 + \\ # I wish to be comment, but I'm not.\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected character after line continuation character\n" - ] - } - ], - "source": [ - "x = 1 + 2 + \\ # I wish to be comment, but I'm not." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What if you want to add a comment that is several lines long? Many programming languages provide a syntax for multiline comments (also called block comments). For example, in C and Java, comments are delimited by the tokens `/*` and `*/`. The text contained within those delimiters can span multiple lines:\n", - "\n", - "```c\n", - "/*\n", - "[This is not Python!]\n", - "\n", - "Initialize the value for radius of circle.\n", - "\n", - "Then calculate the area of the circle\n", - "and display the result to the console.\n", - "*/\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python doesn’t explicitly provide anything analogous to this for creating multiline block comments. To create a block comment, you would usually just begin each line with a hash character:" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The area of a circle with radius 12.35 is 479.163565508706\n" - ] - } - ], - "source": [ - "# Initialize value for radius of circle.\n", - "#\n", - "# Then calculate the area of the circle\n", - "# and display the result to the console.\n", - "\n", - "pi = 3.1415926536\n", - "r = 12.35\n", - "\n", - "area = pi * (r ** 2)\n", - "\n", - "print('The area of a circle with radius', r, 'is', area)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "However, for code in a script file, there is technically an alternative." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You saw above that when the interpreter parses code in a script file, it ignores a string literal (or any literal, for that matter) if it appears as statement by itself. More precisely, a literal isn’t ignored entirely: the interpreter sees it and parses it, but doesn’t do anything with it. Thus, a string literal on a line by itself can serve as a comment. Since a triple-quoted string can span multiple lines, it can effectively function as a multiline comment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider this script file (name it `foo.py` for example):" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The area of a circle with radius 12.35 is 479.163565508706\n" - ] - } - ], - "source": [ - "\"\"\"Initialize value for radius of circle.\n", - "\n", - "Then calculate the area of the circle\n", - "and display the result to the console.\n", - "\"\"\"\n", - "\n", - "pi = 3.1415926536\n", - "r = 12.35\n", - "\n", - "area = pi * (r ** 2)\n", - "\n", - "print('The area of a circle with radius', r, 'is', area)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When this script is run, the output appears as follows:\n", - "\n", - "```bash\n", - "python foo.py\n", - "The area of a circle with radius 12.35 is 479.163565508706\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The triple-quoted string is not displayed and doesn’t change the way the script executes in any way. It effectively constitutes a multiline block comment." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Although this works (and was once put forth as a Python programming tip by Guido himself), PEP 8 actually recommends against it. The reason for this appears to be because of a special Python construct called the **docstring**. A docstring is a special comment at the beginning of a user-defined function that documents the function’s behavior. Docstrings are typically specified as triple-quoted string comments, so PEP 8 recommends that other [block comments](https://www.python.org/dev/peps/pep-0008/?#block-comments) in Python code be designated the usual way, with a hash character at the start of each line." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "However, as you are developing code, if you want a quick and dirty way to comment out as section of code temporarily for experimentation, you may find it convenient to wrap the code in triple quotes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> You will learn more about docstrings in the upcoming tutorial on functions in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Whitespace\n", - "\n", - "When parsing code, the Python interpreter breaks the input up into tokens. Informally, tokens are just the language elements that you have seen so far: identifiers, keywords, literals, and operators." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Typically, what separates tokens from one another is whitespace: blank characters that provide empty space to improve readability. The most common whitespace characters are the following:\n", - "\n", - "|Character| ASCII Code |Literal Expression|\n", - "|:--|:--|:--|\n", - "|space| `32` `(0x20)` |`' '`|\n", - "|tab| `9` `(0x9)` |`'\\t'`|\n", - "|newline| `10` `(0xa)` |`'\\n'`|" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are other somewhat outdated ASCII whitespace characters such as line feed and form feed, as well as some very esoteric Unicode characters that provide whitespace. But for present purposes, whitespace usually means a space, tab, or newline." - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [], - "source": [ - "x = 3\n", - "x=2" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Whitespace is mostly ignored, and mostly not required, by the Python interpreter. When it is clear where one token ends and the next one starts, whitespace can be omitted. This is usually the case when special non-alphanumeric characters are involved:" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "15" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x=3;y=12\n", - "x+y" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "(x==3)and(x=0)and(value1= 0) and (value1 < value2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Most people would likely find that the added whitespace in the second example makes it easier to read. On the other hand, you could probably find a few who would prefer the first example. To some extent, it is a matter of personal preference. But there are standards for [whitespace in expressions and statements](https://www.python.org/dev/peps/pep-0008/?#whitespace-in-expressions-and-statements) put forth in PEP 8, and you should strongly consider adhering to them as much as possible." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = (1,)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> Note: You can juxtapose string literals, with or without whitespace:\n", - ">\n", - "```python\n", - ">>> s = \"foo\"'bar''''baz'''\n", - ">>> s\n", - "'foobarbaz'\n", - "\n", - ">>> s = 'foo' \"bar\" '''baz'''\n", - ">>> s\n", - "'foobarbaz'\n", - "```\n", - "> The effect is concatenation, exactly as though you had used the + operator." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python, whitespace is generally only required when it is necessary to distinguish one token from the next. This is most common when one or both tokens are an identifier or keyword." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, in the following case, whitespace is needed to separate the identifier `s` from the keyword `in`:" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [], - "source": [ - "s = 'bar'" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 76, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s in ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'sin' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msin\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'sin' is not defined" - ] - } - ], - "source": [ - "sin ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is an example where whitespace is required to distinguish between the identifier `y` and the numeric constant `20`: " - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 78, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "y is 20" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m y is20\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "y is20" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, whitespace is needed between two keywords:" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'qux' not in ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 'qux' notin ['foo', 'bar', 'baz']\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "'qux' notin ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Running identifiers or keywords together fools the interpreter into thinking you are referring to a different token than you intended: `sin`, `is20`, and `notin`, in the examples above." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Running identifiers or keywords together fools the interpreter into thinking you are referring to a different token than you intended: sin, is20, and notin, in the examples above." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All this tends to be rather academic because it isn’t something you’ll likely need to think about much. Instances where whitespace is necessary tend to be intuitive, and you’ll probably just do it by second nature." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You should use whitespace where it isn’t strictly necessary as well to enhance readability. Ideally, you should follow the guidelines in PEP 8." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Deep Dive: Fortran and Whitespace**\n", - ">\n", - ">The earliest versions of Fortran, one of the first programming languages created, were designed so that all whitespace was completely ignored. Whitespace characters could be optionally included or omitted virtually anywhere—between identifiers and reserved words, and even in the middle of identifiers and reserved words.\n", - ">\n", - ">For example, if your Fortran code contained a variable named total, any of the following would be a valid statement to assign it the value 50:\n", - ">\n", - "```fortran\n", - "total = 50\n", - "to tal = 50\n", - "t o t a l=5 0\n", - "```\n", - ">This was meant as a convenience, but in retrospect it is widely regarded as overkill. It often resulted in code that was difficult to read. Worse yet, it potentially led to code that did not execute correctly.\n", - ">\n", - ">Consider this tale from NASA in the 1960s. A Mission Control Center orbit computation program written in Fortran was supposed to contain the following line of code:\n", - ">\n", - "```fortran\n", - "DO 10 I = 1,100\n", - "```\n", - ">In the Fortran dialect used by NASA at that time, the code shown introduces a loop, a construct that executes a body of code repeatedly. (You will learn about loops in Python in two future tutorials on definite and indefinite iteration).\n", - ">\n", - ">Unfortunately, this line of code ended up in the program instead:\n", - ">\n", - "```fortran\n", - "DO 10 I = 1.100\n", - "```\n", - "> If you have a difficult time seeing the difference, don’t feel too bad. It took the NASA programmer a couple weeks to notice that there is a period between `1` and `100` instead of a comma. Because the Fortran compiler ignored whitespace, `DO 10 I` was taken to be a variable name, and the statement `DO 10 I = 1.100` resulted in assigning `1.100` to a variable called `DO10I` instead of introducing a loop.\n", - ">\n", - "> Some versions of the story claim that a Mercury rocket was lost because of this error, but that is evidently a myth. It did apparently cause inaccurate data for some time, though, before the programmer spotted the error.\n", - ">\n", - ">Virtually all modern programming languages have chosen not to go this far with ignoring whitespace." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Whitespace as Indentation\n", - "\n", - "There is one more important situation in which whitespace is significant in Python code. Indentation—whitespace that appears to the left of the first token on a line—has very special meaning." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In most interpreted languages, leading whitespace before statements is ignored. For example, consider this Windows Command Prompt session:\n", - "\n", - "```bash\n", - "$ echo foo\n", - "foo\n", - "$ echo foo\n", - "foo\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** In a Command Prompt window, the echo command displays its arguments to the console, like the `print()` function in Python. Similar behavior can be observed from a terminal window in macOS or Linux." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the second statement, four space characters are inserted to the left of the echo command. But the result is the same. The interpreter ignores the leading whitespace and executes the same command, echo foo, just as it does when the leading whitespace is absent." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now try more or less the same thing with the Python interpreter:\n", - "\n", - "```python\n", - ">>> print('foo')\n", - "foo\n", - ">>> print('foo')\n", - "\n", - "SyntaxError: unexpected indent\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Running the above code in jupyter notebook does not raise an error as jupyter notebook ignores the whitespaces at the start of a single line command." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Say what? Unexpected indent? The leading whitespace before the second `print()` statement causes a `SyntaxError` exception!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python, indentation is not ignored. Leading whitespace is used to compute a line’s indentation level, which in turn is used to determine grouping of statements. As yet, you have not needed to group statements, but that will change in the next tutorial with the introduction of control structures." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Until then, be aware that leading whitespace matters." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "\n", - "This tutorial introduced you to Python program lexical structure. You learned what constitutes a valid Python **statement** and how to use **implicit** and **explicit line continuation** to write a statement that spans multiple lines. You also learned about commenting Python code, and about use of whitespace to enhance readability." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, you will learn how to group statements into more complex decision-making constructs using **conditional statements**." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Python Program Lexical Structure\n", "\n", "You have now covered Python variables, operators, and data types in depth, and you\u2019ve seen quite a bit of example code. Up to now, the code has consisted of short individual statements, simply assigning objects to variables or displaying values.\n", "\n", "But you want to do more than just define data and display it! Let\u2019s start arranging code into more complex groupings."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Python Statements](#python_statements)\n* [Line Continuation](#line_continuation)\n * [Implicit Line Continuation](#implicit_line_continuation)\n * [Explicit Line Continuation](#explicit_line_continuation)\n* [Multiple Statements Per Line](#multiple_statements_per_line)\n* [Comments](#comments)\n* [Whitespace](#whitespace)\n* [Whitespace as Indentation](#whitespace_as_indentation)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Python Statements\n", "\n", "Statements are the basic units of instruction that the Python interpreter parses and processes. In general, the interpreter executes statements sequentially, one after the next as it encounters them. (You will see in the next tutorial on conditional statements that it is possible to alter this behavior.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In a REPL session, statements are executed as they are typed in, until the interpreter is terminated. When you execute a script file, the interpreter reads statements from the file and executes them until end-of-file is encountered."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python programs are typically organized with one statement per line. In other words, each statement occupies a single line, with the end of the statement delimited by the newline character that marks the end of the line. The majority of the examples so far in this tutorial series have followed this pattern:"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Hello, World!\n"]}], "source": ["print('Hello, World!')"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["[2]\n"]}], "source": ["x = [1, 2, 3]\n", "print(x[1:2])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Line Continuation\n", "\n", "Suppose a single statement in your Python code is especially long. For example, you may have an assignment statement with many terms:"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": ["person1_age = 42\n", "person2_age = 16\n", "person3_age = 71"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["someone_is_of_working_age = (person1_age >= 18 and person1_age <= 65) or (person2_age >= 18 and person2_age <= 65) or (person3_age >= 18 and person3_age <= 65)\n", "someone_is_of_working_age"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Or perhaps you are defining a lengthy nested list:"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/plain": ["[[1, 2, 3, 4, 5],\n", " [6, 7, 8, 9, 10],\n", " [11, 12, 13, 14, 15],\n", " [16, 17, 18, 19, 20],\n", " [21, 22, 23, 24, 25]]"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["a = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]\n", "a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You\u2019ll notice that these statements are too long to fit in your browser window, and the browser is forced to render the code blocks with horizontal scroll bars. You may find that irritating. (You have our apologies\u2014these examples are presented that way to make the point. It won\u2019t happen again.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is equally frustrating when lengthy statements like these are contained in a script file. Most editors can be configured to wrap text, so that the ends of long lines are at least visible and don\u2019t disappear out the right edge of the editor window. But the wrapping doesn\u2019t necessarily occur in logical locations that enhance readability:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["\"line-wrap\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["Excessively long lines of code are generally considered poor practice. In fact, there is an official [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008) put forth by the Python Software Foundation, and one of its stipulations is that the [maximum line length](https://www.python.org/dev/peps/pep-0008/#maximum-line-length) in Python code should be 79 characters."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** The **Style Guide for Python Code** is also referred to as **PEP 8**. PEP stands for Python Enhancement Proposal. PEPs are documents that contain details about features, standards, design issues, general guidelines, and information relating to Python. For more information, see the Python Software Foundation [Index of PEPs](https://www.python.org/dev/peps)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["As code becomes more complex, statements will on occasion unavoidably grow long. To maintain readability, you should break them up into parts across several lines. But you can\u2019t just split a statement whenever and wherever you like. Unless told otherwise, the interpreter assumes that a newline character terminates a statement. If the statement isn\u2019t syntactically correct at that point, an exception is raised:"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (1911760183.py, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_50053/1911760183.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In Python code, a statement can be continued from one line to the next in two different ways: implicit and explicit line continuation."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Implicit Line Continuation\n", "\n", "This is the more straightforward technique for line continuation, and the one that is preferred according to PEP 8."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Any statement containing opening parentheses (`'('`), brackets (`'['`), or curly braces (`'{'`) is presumed to be incomplete until all matching parentheses, brackets, and braces have been encountered. Until then, the statement can be implicitly continued across lines without raising an error."]}, {"cell_type": "markdown", "metadata": {}, "source": ["For example, the nested list definition from above can be made much more readable using implicit line continuation because of the open brackets:"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": ["a = [\n", " [1, 2, 3, 4, 5],\n", " [6, 7, 8, 9, 10],\n", " [11, 12, 13, 14, 15],\n", " [16, 17, 18, 19, 20],\n", " [21, 22, 23, 24, 25]\n", "]"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"data": {"text/plain": ["[[1, 2, 3, 4, 5],\n", " [6, 7, 8, 9, 10],\n", " [11, 12, 13, 14, 15],\n", " [16, 17, 18, 19, 20],\n", " [21, 22, 23, 24, 25]]"]}, "execution_count": 26, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A long expression can also be continued across multiple lines by wrapping it in grouping parentheses. PEP 8 explicitly advocates using parentheses in this manner when appropriate:"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": ["someone_is_of_working_age = (\n", " (person1_age >= 18 and person1_age <= 65)\n", " or (person2_age >= 18 and person2_age <= 65)\n", " or (person3_age >= 18 and person3_age <= 65)\n", ")"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["someone_is_of_working_age"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you need to continue a statement across multiple lines, it is usually possible to use implicit line continuation to do so. This is because parentheses, brackets, and curly braces appear so frequently in Python syntax:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Parentheses\n", "\n", "- Expression grouping"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": ["x = (\n", " 1 + 2\n", " + 3 + 4\n", " + 5 + 6\n", ")"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["21"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Function call (functions will be covered later)"]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo bar baz\n"]}], "source": ["print(\n", " 'foo',\n", " 'bar',\n", " 'baz'\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Method call (methods will be covered later)"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["'---abc---'"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["'abc'.center(\n", " 9,\n", " '-'\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Tuple definition"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": ["t = (\n", " 'a', 'b',\n", " 'c', 'd'\n", ")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Curly Braces"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Dictionary definition"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": ["d = {\n", " 'a': 1,\n", " 'b': 2\n", "}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Set definition"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": ["x1 = {\n", " 'foo',\n", " 'bar',\n", " 'baz'\n", "}"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### Square Brackets"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- List definition"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": ["a = [\n", " 'foo', 'bar',\n", " 'baz', 'qux'\n", "]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Indexing"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"data": {"text/plain": ["[6, 7, 8, 9, 10]"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["a[\n", " 1\n", "]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Slicing"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [{"data": {"text/plain": ["['bar']"]}, "execution_count": 25, "metadata": {}, "output_type": "execute_result"}], "source": ["a[\n", " 1:2\n", "]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["- Dictionary key reference"]}, {"cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [{"data": {"text/plain": ["2"]}, "execution_count": 27, "metadata": {}, "output_type": "execute_result"}], "source": ["d[\n", " 'b'\n", "]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Just because something is syntactically allowed, it doesn\u2019t mean you should do it. Some of the examples above would not typically be recommended. Splitting indexing, slicing, or dictionary key reference across lines, in particular, would be unusual. But you can consider it if you can make a good argument that it enhances readability."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Remember that if there are multiple parentheses, brackets, or curly braces, then implicit line continuation is in effect until they are all closed:"]}, {"cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": ["a = [\n", " [\n", " ['foo', 'bar'],\n", " [1, 2, 3]\n", " ],\n", " {1, 3, 5},\n", " {\n", " 'a': 1,\n", " 'b': 2\n", " }\n", "]"]}, {"cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [{"data": {"text/plain": ["[[['foo', 'bar'], [1, 2, 3]], {1, 3, 5}, {'a': 1, 'b': 2}]"]}, "execution_count": 36, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note how line continuation and judicious use of indentation can be used to clarify the nested structure of the list."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Explicit Line Continuation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In cases where implicit line continuation is not readily available or practicable, there is another option. This is referred to as explicit line continuation or explicit line joining."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Ordinarily, a newline character (which you get when you press _Enter_ on your keyboard) indicates the end of a line. If the statement is not complete by that point, Python will raise a SyntaxError exception:"]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m s =\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["s ="]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m x = 1 + 2 +\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["x = 1 + 2 +"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To indicate explicit line continuation, you can specify a backslash (`\\`) character as the final character on the line. In that case, Python ignores the following newline, and the statement is effectively continued on next line:"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["s = \\\n", "'Hello, World!'"]}, {"cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [{"data": {"text/plain": ["'Hello, World!'"]}, "execution_count": 33, "metadata": {}, "output_type": "execute_result"}], "source": ["s"]}, {"cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": ["x = 1 + 2 \\\n", " + 3 + 4 \\\n", " + 5 + 6"]}, {"cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [{"data": {"text/plain": ["21"]}, "execution_count": 45, "metadata": {}, "output_type": "execute_result"}], "source": ["x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Note that the backslash character must be the last character on the line. Not even whitespace is allowed after it:**"]}, {"cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "unexpected character after line continuation character (, line 2)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m s = \\\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected character after line continuation character\n"]}], "source": ["# You can't see it, but there is a space character following the \\ here:\n", "s = \\ "]}, {"cell_type": "markdown", "metadata": {}, "source": ["Again, PEP 8 recommends using explicit line continuation only when implicit line continuation is not feasible."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Multiple Statements Per Line\n", "\n", "Multiple statements may occur on one line, if they are separated by a semicolon (`;`) character:"]}, {"cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], "source": ["x = 1; y = 2; z = 3"]}, {"cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1\n", "2\n", "3\n"]}], "source": ["print(x); print(y); print(z)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Stylistically, this is generally frowned upon, and [PEP 8 expressly discourages it](https://www.python.org/dev/peps/pep-0008/?#other-recommendations). There might be situations where it improves readability, but it usually doesn\u2019t. In fact, it often isn\u2019t necessary. The following statements are functionally equivalent to the example above, but would be considered more typical Python code:"]}, {"cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": ["x, y, z = 1, 2, 3"]}, {"cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1\n", "2\n", "3\n"]}], "source": ["print(x, y, z, sep='\\n')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> The term **Pythonic** refers to code that adheres to generally accepted common guidelines for readability and \u201cbest\u201d use of idiomatic Python. When someone says code is not Pythonic, they are implying that it does not express the programmer\u2019s intent as well as might otherwise be done in Python. Thus, the code is probably not as readable as it could be to someone who is fluent in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you find your code has multiple statements on a line, there is probably a more Pythonic way to write it. But again, if you think it\u2019s appropriate or enhances readability, you should feel free to do it."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Comments\n", "\n", "In Python, the hash character (`#`) signifies a comment. The interpreter will ignore everything from the hash character through the end of that line:"]}, {"cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz'] # I am a comment."]}, {"cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz']"]}, "execution_count": 52, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If the first non-whitespace character on the line is a hash, the entire line is effectively ignored:"]}, {"cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": ["# I am a comment.\n", " # I am too."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Naturally, a hash character inside a string literal is protected, and does not indicate a comment:"]}, {"cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [{"data": {"text/plain": ["'foobar # I am *not* a comment.'"]}, "execution_count": 59, "metadata": {}, "output_type": "execute_result"}], "source": ["a = 'foobar # I am *not* a comment.'\n", "a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A comment is just ignored, so what purpose does it serve? Comments give you a way to attach explanatory detail to your code:"]}, {"cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": ["# Calculate and display the area of a circle.\n", "pi = 3.1415926536\n", "r = 12.35"]}, {"cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [], "source": ["area = pi * (r ** 2)"]}, {"cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["The area of a circle with radius 12.35 is 479.163565508706\n"]}], "source": ["print('The area of a circle with radius', r, 'is', area)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Up to now, your Python coding has consisted mostly of short, isolated REPL sessions. In that setting, the need for comments is pretty minimal. Eventually, you will develop larger applications contained across multiple script files, and comments will become increasingly important."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Good commenting makes the intent of your code clear at a glance when someone else reads it, or even when you yourself read it. Ideally, you should strive to write code that is as clear, concise, and self-explanatory as possible. But there will be times that you will make design or implementation decisions that are not readily obvious from the code itself. That is where commenting comes in. Good code explains how; good comments explain why."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Comments can be included within implicit line continuation:"]}, {"cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": ["x = (1 + 2 # I am a comment.\n", " + 3 + 4 # Me too.\n", " + 5 + 6)"]}, {"cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [{"data": {"text/plain": ["21"]}, "execution_count": 59, "metadata": {}, "output_type": "execute_result"}], "source": ["x"]}, {"cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [], "source": ["a = [\n", " 'foo', 'bar', # Me three.\n", " 'baz', 'qux'\n", "]"]}, {"cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz', 'qux']"]}, "execution_count": 61, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "markdown", "metadata": {}, "source": ["But recall that explicit line continuation requires the backslash character to be the last character on the line. Thus, a comment can\u2019t follow afterward:"]}, {"cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "unexpected character after line continuation character (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m x = 1 + 2 + \\ # I wish to be comment, but I'm not.\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected character after line continuation character\n"]}], "source": ["x = 1 + 2 + \\ # I wish to be comment, but I'm not."]}, {"cell_type": "markdown", "metadata": {}, "source": ["What if you want to add a comment that is several lines long? Many programming languages provide a syntax for multiline comments (also called block comments). For example, in C and Java, comments are delimited by the tokens `/*` and `*/`. The text contained within those delimiters can span multiple lines:\n", "\n", "```c\n", "/*\n", "[This is not Python!]\n", "\n", "Initialize the value for radius of circle.\n", "\n", "Then calculate the area of the circle\n", "and display the result to the console.\n", "*/\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python doesn\u2019t explicitly provide anything analogous to this for creating multiline block comments. To create a block comment, you would usually just begin each line with a hash character:"]}, {"cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["The area of a circle with radius 12.35 is 479.163565508706\n"]}], "source": ["# Initialize value for radius of circle.\n", "#\n", "# Then calculate the area of the circle\n", "# and display the result to the console.\n", "\n", "pi = 3.1415926536\n", "r = 12.35\n", "\n", "area = pi * (r ** 2)\n", "\n", "print('The area of a circle with radius', r, 'is', area)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["However, for code in a script file, there is technically an alternative."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You saw above that when the interpreter parses code in a script file, it ignores a string literal (or any literal, for that matter) if it appears as statement by itself. More precisely, a literal isn\u2019t ignored entirely: the interpreter sees it and parses it, but doesn\u2019t do anything with it. Thus, a string literal on a line by itself can serve as a comment. Since a triple-quoted string can span multiple lines, it can effectively function as a multiline comment."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Consider this script file (name it `foo.py` for example):"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["The area of a circle with radius 12.35 is 479.163565508706\n"]}], "source": ["\"\"\"Initialize value for radius of circle.\n", "\n", "Then calculate the area of the circle\n", "and display the result to the console.\n", "\"\"\"\n", "\n", "pi = 3.1415926536\n", "r = 12.35\n", "\n", "area = pi * (r ** 2)\n", "\n", "print('The area of a circle with radius', r, 'is', area)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["When this script is run, the output appears as follows:\n", "\n", "```bash\n", "python foo.py\n", "The area of a circle with radius 12.35 is 479.163565508706\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The triple-quoted string is not displayed and doesn\u2019t change the way the script executes in any way. It effectively constitutes a multiline block comment."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Although this works (and was once put forth as a Python programming tip by Guido himself), PEP 8 actually recommends against it. The reason for this appears to be because of a special Python construct called the **docstring**. A docstring is a special comment at the beginning of a user-defined function that documents the function\u2019s behavior. Docstrings are typically specified as triple-quoted string comments, so PEP 8 recommends that other [block comments](https://www.python.org/dev/peps/pep-0008/?#block-comments) in Python code be designated the usual way, with a hash character at the start of each line."]}, {"cell_type": "markdown", "metadata": {}, "source": ["However, as you are developing code, if you want a quick and dirty way to comment out as section of code temporarily for experimentation, you may find it convenient to wrap the code in triple quotes."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> You will learn more about docstrings in the upcoming tutorial on functions in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Whitespace\n", "\n", "When parsing code, the Python interpreter breaks the input up into tokens. Informally, tokens are just the language elements that you have seen so far: identifiers, keywords, literals, and operators."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Typically, what separates tokens from one another is whitespace: blank characters that provide empty space to improve readability. The most common whitespace characters are the following:\n", "\n", "|Character| ASCII Code |Literal Expression|\n", "|:--|:--|:--|\n", "|space| `32` `(0x20)` |`' '`|\n", "|tab| `9` `(0x9)` |`'\\t'`|\n", "|newline| `10` `(0xa)` |`'\\n'`|"]}, {"cell_type": "markdown", "metadata": {}, "source": ["There are other somewhat outdated ASCII whitespace characters such as line feed and form feed, as well as some very esoteric Unicode characters that provide whitespace. But for present purposes, whitespace usually means a space, tab, or newline."]}, {"cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [], "source": ["x = 3\n", "x=2"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Whitespace is mostly ignored, and mostly not required, by the Python interpreter. When it is clear where one token ends and the next one starts, whitespace can be omitted. This is usually the case when special non-alphanumeric characters are involved:"]}, {"cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [{"data": {"text/plain": ["15"]}, "execution_count": 65, "metadata": {}, "output_type": "execute_result"}], "source": ["x=3;y=12\n", "x+y"]}, {"cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 66, "metadata": {}, "output_type": "execute_result"}], "source": ["(x==3)and(x=0)and(value1= 0) and (value1 < value2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Most people would likely find that the added whitespace in the second example makes it easier to read. On the other hand, you could probably find a few who would prefer the first example. To some extent, it is a matter of personal preference. But there are standards for [whitespace in expressions and statements](https://www.python.org/dev/peps/pep-0008/?#whitespace-in-expressions-and-statements) put forth in PEP 8, and you should strongly consider adhering to them as much as possible."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["x = (1, )"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> Note: You can juxtapose string literals, with or without whitespace:\n", ">\n", "```python\n", ">>> s = \"foo\"'bar''''baz'''\n", ">>> s\n", "'foobarbaz'\n", "\n", ">>> s = 'foo' \"bar\" '''baz'''\n", ">>> s\n", "'foobarbaz'\n", "```\n", "> The effect is concatenation, exactly as though you had used the + operator."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In Python, whitespace is generally only required when it is necessary to distinguish one token from the next. This is most common when one or both tokens are an identifier or keyword."]}, {"cell_type": "markdown", "metadata": {}, "source": ["For example, in the following case, whitespace is needed to separate the identifier `s` from the keyword `in`:"]}, {"cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [], "source": ["s = 'bar'"]}, {"cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 76, "metadata": {}, "output_type": "execute_result"}], "source": ["s in ['foo', 'bar', 'baz']"]}, {"cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [{"ename": "NameError", "evalue": "name 'sin' is not defined", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msin\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'foo'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'bar'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'baz'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'sin' is not defined"]}], "source": ["sin ['foo', 'bar', 'baz']"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here is an example where whitespace is required to distinguish between the identifier `y` and the numeric constant `20`: "]}, {"cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [{"data": {"text/plain": ["False"]}, "execution_count": 78, "metadata": {}, "output_type": "execute_result"}], "source": ["y is 20"]}, {"cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m y is20\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["y is20"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this example, whitespace is needed between two keywords:"]}, {"cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [{"data": {"text/plain": ["True"]}, "execution_count": 80, "metadata": {}, "output_type": "execute_result"}], "source": ["'qux' not in ['foo', 'bar', 'baz']"]}, {"cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 'qux' notin ['foo', 'bar', 'baz']\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["'qux' notin ['foo', 'bar', 'baz']"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Running identifiers or keywords together fools the interpreter into thinking you are referring to a different token than you intended: `sin`, `is20`, and `notin`, in the examples above."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Running identifiers or keywords together fools the interpreter into thinking you are referring to a different token than you intended: sin, is20, and notin, in the examples above."]}, {"cell_type": "markdown", "metadata": {}, "source": ["All this tends to be rather academic because it isn\u2019t something you\u2019ll likely need to think about much. Instances where whitespace is necessary tend to be intuitive, and you\u2019ll probably just do it by second nature."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You should use whitespace where it isn\u2019t strictly necessary as well to enhance readability. Ideally, you should follow the guidelines in PEP 8."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Deep Dive: Fortran and Whitespace**\n", ">\n", ">The earliest versions of Fortran, one of the first programming languages created, were designed so that all whitespace was completely ignored. Whitespace characters could be optionally included or omitted virtually anywhere\u2014between identifiers and reserved words, and even in the middle of identifiers and reserved words.\n", ">\n", ">For example, if your Fortran code contained a variable named total, any of the following would be a valid statement to assign it the value 50:\n", ">\n", "```fortran\n", "total = 50\n", "to tal = 50\n", "t o t a l=5 0\n", "```\n", ">This was meant as a convenience, but in retrospect it is widely regarded as overkill. It often resulted in code that was difficult to read. Worse yet, it potentially led to code that did not execute correctly.\n", ">\n", ">Consider this tale from NASA in the 1960s. A Mission Control Center orbit computation program written in Fortran was supposed to contain the following line of code:\n", ">\n", "```fortran\n", "DO 10 I = 1,100\n", "```\n", ">In the Fortran dialect used by NASA at that time, the code shown introduces a loop, a construct that executes a body of code repeatedly. (You will learn about loops in Python in two future tutorials on definite and indefinite iteration).\n", ">\n", ">Unfortunately, this line of code ended up in the program instead:\n", ">\n", "```fortran\n", "DO 10 I = 1.100\n", "```\n", "> If you have a difficult time seeing the difference, don\u2019t feel too bad. It took the NASA programmer a couple weeks to notice that there is a period between `1` and `100` instead of a comma. Because the Fortran compiler ignored whitespace, `DO 10 I` was taken to be a variable name, and the statement `DO 10 I = 1.100` resulted in assigning `1.100` to a variable called `DO10I` instead of introducing a loop.\n", ">\n", "> Some versions of the story claim that a Mercury rocket was lost because of this error, but that is evidently a myth. It did apparently cause inaccurate data for some time, though, before the programmer spotted the error.\n", ">\n", ">Virtually all modern programming languages have chosen not to go this far with ignoring whitespace."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Whitespace as Indentation\n", "\n", "There is one more important situation in which whitespace is significant in Python code. Indentation\u2014whitespace that appears to the left of the first token on a line\u2014has very special meaning."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In most interpreted languages, leading whitespace before statements is ignored. For example, consider this Windows Command Prompt session:\n", "\n", "```bash\n", "$ echo foo\n", "foo\n", "$ echo foo\n", "foo\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** In a Command Prompt window, the echo command displays its arguments to the console, like the `print()` function in Python. Similar behavior can be observed from a terminal window in macOS or Linux."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the second statement, four space characters are inserted to the left of the echo command. But the result is the same. The interpreter ignores the leading whitespace and executes the same command, echo foo, just as it does when the leading whitespace is absent."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now try more or less the same thing with the Python interpreter:\n", "\n", "```python\n", ">>> print('foo')\n", "foo\n", ">>> print('foo')\n", "\n", "SyntaxError: unexpected indent\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Running the above code in jupyter notebook does not raise an error as jupyter notebook ignores the whitespaces at the start of a single line command."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Say what? Unexpected indent? The leading whitespace before the second `print()` statement causes a `SyntaxError` exception!"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In Python, indentation is not ignored. Leading whitespace is used to compute a line\u2019s indentation level, which in turn is used to determine grouping of statements. As yet, you have not needed to group statements, but that will change in the next tutorial with the introduction of control structures."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Until then, be aware that leading whitespace matters."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "\n", "This tutorial introduced you to Python program lexical structure. You learned what constitutes a valid Python **statement** and how to use **implicit** and **explicit line continuation** to write a statement that spans multiple lines. You also learned about commenting Python code, and about use of whitespace to enhance readability."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Next, you will learn how to group statements into more complex decision-making constructs using **conditional statements**."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/12 Conditional Statements in Python.ipynb b/python/01. Basics/12 Conditional Statements in Python.ipynb index cd8ae37..f9b2414 100755 --- a/python/01. Basics/12 Conditional Statements in Python.ipynb +++ b/python/01. Basics/12 Conditional Statements in Python.ipynb @@ -1,1555 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Conditional Statements in Python" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "From the previous tutorials in this series, you now have quite a bit of Python code under your belt. Everything you have seen so far has consisted of **sequential execution** , in which statements are always performed one after the next, in exactly the order specified." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But the world is often more complicated than that. Frequently, a program needs to skip over some statements, execute a series of statements repetitively, or choose between alternate sets of statements to execute." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "That is where **control structures** come in. A control structure directs the order of execution of the statements in a program (referred to as the program’s control flow)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the real world, we commonly must evaluate information around us and then choose one course of action or another based on what we observe:\n", - "\n", - "> If the weather is nice, then I’ll mow the lawn. (It’s implied that if the weather isn’t nice, then I won’t mow the lawn.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In a Python program, the if statement is how you perform this sort of decision-making. It allows for **conditional** execution of a statement or group of statements based on the value of an expression." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The outline of this section is as follows:\n", - "\n", - "- First, you’ll get a quick overview of the `if` statement in its simplest form.\n", - "- Next, using the if statement as a model, you’ll see why control structures require some mechanism for grouping statements together into **compound statements** or **blocks**. You’ll learn how this is done in Python.\n", - "- Lastly, you’ll tie it all together and learn how to write complex decision-making code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Introduction to the `if` Statement" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We’ll start by looking at the most basic type of `if` statement. In its simplest form, it looks like this:\n", - "\n", - "```python\n", - "if :\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the form shown above:\n", - "\n", - "- `` is an expression evaluated in a Boolean context, as discussed in the section on Logical Operators in the Operators and Expressions section.\n", - "- `` is a valid Python statement, which must be indented. (You will see why very soon.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If `` is true (evaluates to a value that is “truthy”), then `` is executed. If `` is false, then `` is skipped over and not executed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the colon (`:`) following `` is required. Some programming languages require `` to be enclosed in parentheses, but Python does not." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here are several examples of this type of `if` statement:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "x = 0\n", - "y = 5" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "yes\n" - ] - } - ], - "source": [ - "if x < y: # Truthy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "if y < x: # Falsy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "yes\n" - ] - } - ], - "source": [ - "if x: # Falsy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "yes\n" - ] - } - ], - "source": [ - "if y: # Truthy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "yes\n" - ] - } - ], - "source": [ - "if x or y: # Truthy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "if x and y: # Falsy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "yes\n" - ] - } - ], - "source": [ - "if 'aul' in 'grault': # Truthy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [], - "source": [ - "if 'quux' in ['foo', 'bar', 'baz']: # Falsy\n", - " print('yes')" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "if 10 in [1, 2, 3, 4]:\n", - " print('hi')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Grouping Statements: Indentation and Blocks" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "So far, so good.\n", - "\n", - "But let’s say you want to evaluate a condition and then do more than one thing if it is true:\n", - "\n", - "> If the weather is nice, then I will:\n", - "> \n", - "> - Mow the lawn\n", - "> - Weed the garden\n", - "> - Take the dog for a walk\n", - "> \n", - "> (If the weather isn’t nice, then I won’t do any of these things.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In all the examples shown above, each `if `: has been followed by only a single ``. There needs to be some way to say \"If `` is true, do all of the following things.\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The usual approach taken by most programming languages is to define a syntactic device that groups multiple statements into one **compound statement** or **block**. A block is regarded syntactically as a single entity. When it is the target of an `if` statement, and `` is true, then all the statements in the block are executed. If `` is false, then none of them are." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Virtually all programming languages provide the capability to define blocks, but they don’t all provide it in the same way. Let’s see how Python does it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python: It’s All About the Indentation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python follows a convention known as the [off-side rule](https://en.wikipedia.org/wiki/Off-side_rule), a term coined by British computer scientist Peter J. Landin. (The term is taken from the offside law in association football.) Languages that adhere to the off-side rule define blocks by indentation. Python is one of a relatively small set of [off-side rule languages](https://en.wikipedia.org/wiki/Off-side_rule#Off-side_rule_languages)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Recall from the previous section on Python program structure that indentation has special significance in a Python program. Now you know why: indentation is used to define compound statements or blocks. In a Python program, contiguous statements that are indented to the same level are considered to be part of the same block." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Thus, a compound `if` statement in Python looks like this:\n", - "\n", - "```python\n", - "if :\n", - " \n", - " \n", - " ...\n", - " \n", - "\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, all the statements at the matching indentation level (lines 2 to 5) are considered part of the same block. The entire block is executed if `` is true, or skipped over if `` is false. Either way, execution proceeds with `` (line 6) afterward.\n", - "\n", - "\"if-block\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice that there is no token that denotes the end of the block. Rather, the end of the block is indicated by a line that is indented less than the lines of the block itself." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** In the Python documentation, a group of statements defined by indentation is often referred to as a **suite**. This tutorial series uses the terms block and suite interchangeably." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider the following code:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "After conditional\n" - ] - } - ], - "source": [ - "if 'foo' in ['bar', 'baz', 'qux']:\n", - " print('Expression was true')\n", - " print('Executing statement in suite')\n", - " print('...')\n", - " print('Done.')\n", - " \n", - "print('After conditional')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The four `print()` statements on lines 2 to 5 are indented to the same level as one another. They constitute the block that would be executed if the condition were true. But it is false, so all the statements in the block are skipped. After the end of the compound `if` statement has been reached (whether the statements in the block on lines 2 to 5 are executed or not), execution proceeds to the first statement having a lesser indentation level: the `print()` statement on line 6." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Blocks can be nested to arbitrary depth. Each indent defines a new block, and each outdent ends the preceding block. The resulting structure is straightforward, consistent, and intuitive." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a more complicated `if` block: " - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Outer condition is true\n", - "Between inner conditions\n", - "Inner condition 2\n", - "End of outer condition\n", - "After outer condition\n" - ] - } - ], - "source": [ - "# Does line execute? Yes No\n", - "# --- --\n", - "if 'foo' in ['foo', 'bar', 'baz']: # x\n", - " print('Outer condition is true') # x\n", - "\n", - " if 10 > 20: # x\n", - " print('Inner condition 1') # x\n", - "\n", - " print('Between inner conditions') # x\n", - "\n", - " if 10 < 20: # x\n", - " print('Inner condition 2') # x\n", - "\n", - " print('End of outer condition') # x\n", - "print('After outer condition') # x" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What Do Other Languages Do?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Perhaps you’re curious what the alternatives are. How are blocks defined in languages that don’t adhere to the off-side rule?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The tactic used by most programming languages is to designate special tokens that mark the start and end of a block. For example, in Perl blocks are defined with pairs of curly braces (`{}`) like this:\n", - "\n", - "```perl\n", - "# (This is Perl, not Python)\n", - "if () {\n", - " ;\n", - " ;\n", - " ...\n", - " ;\n", - "}\n", - ";\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "C/C++, Java, and a whole host of other languages use curly braces in this way.\n", - "\n", - "\"if-block-c\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Other languages, such as Algol and Pascal, use keywords `begin` and `end` to enclose blocks." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Which Is Better?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Better is in the eye of the beholder. On the whole, programmers tend to feel rather strongly about how they do things. Debate about the merits of the off-side rule can run pretty hot." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "On the plus side:\n", - "\n", - "- Python’s use of indentation is clean, concise, and consistent.\n", - "- In programming languages that do not use the off-side rule, indentation of code is completely independent of block definition and code function. It’s possible to write code that is indented in a manner that does not actually match how the code executes, thus creating a mistaken impression when a person just glances at it. This sort of mistake is virtually impossible to make in Python.\n", - "- Use of indentation to define blocks forces you to maintain code formatting standards you probably should be using anyway." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "On the negative side:\n", - "\n", - "- Many programmers don’t like to be forced to do things a certain way. They tend to have strong opinions about what looks good and what doesn’t, and they don’t like to be shoehorned into a specific choice.\n", - "- Some editors insert a mix of space and tab characters to the left of indented lines, which makes it difficult for the Python interpreter to determine indentation levels. On the other hand, it is frequently possible to configure editors not to do this. It generally isn’t considered desirable to have a mix of tabs and spaces in source code anyhow, no matter the language." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Like it or not, if you’re programming in Python, you’re stuck with the off-side rule. All control structures in Python use it, as you will see in several future tutorials." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For what it’s worth, many programmers who have been used to languages with more traditional means of block definition have initially recoiled at Python’s way but have gotten comfortable with it and have even grown to prefer it." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The `else` and `elif` Clauses" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now you know how to use an `if` statement to conditionally execute a single statement or a block of several statements. It’s time to find out what else you can do." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Sometimes, you want to evaluate a condition and take one path if it is true but specify an alternative path if it is not. This is accomplished with an `else` clause:\n", - "\n", - "```python\n", - "if :\n", - " \n", - "else:\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If `` is true, the first suite is executed, and the second is skipped. If `` is false, the first suite is skipped and the second is executed. Either way, execution then resumes after the second suite. Both suites are defined by indentation, as described above." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, `x` is less than `50`, so the first suite (lines 4 to 5) are executed, and the second suite (lines 7 to 8) are skipped:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(first suite)\n", - "x is small\n" - ] - } - ], - "source": [ - "x = 20\n", - "\n", - "if x < 50:\n", - " print('(first suite)')\n", - " print('x is small')\n", - "else:\n", - " print('(second suite)')\n", - " print('x is large')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, on the other hand, `x` is greater than `50`, so the first suite is passed over, and the second suite executed:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(second suite)\n", - "x is large\n" - ] - } - ], - "source": [ - "x = 120\n", - "\n", - "if x < 50:\n", - " print('(first suite)')\n", - " print('x is small')\n", - "else:\n", - " print('(second suite)')\n", - " print('x is large')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There is also syntax for branching execution based on several alternatives. For this, use one or more `elif` (short for `else if`) clauses. Python evaluates each `` in turn and executes the suite corresponding to the first that is true. If none of the expressions are true, and an `else` clause is specified, then its suite is executed:\n", - "\n", - "```python\n", - "if :\n", - " \n", - "elif :\n", - " \n", - "elif :\n", - " \n", - " ...\n", - "else:\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "An arbitrary number of `elif` clauses can be specified. The `else` clause is optional. If it is present, there can be only one, and it must be specified last:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello Joe\n" - ] - } - ], - "source": [ - "name = 'Joe'\n", - "if name == 'Fred':\n", - " print('Hello Fred')\n", - "elif name == 'Xander':\n", - " print('Hello Xander')\n", - "elif name == 'Joe':\n", - " print('Hello Joe')\n", - "elif name == 'Arnold':\n", - " print('Hello Arnold')\n", - "else:\n", - " print(\"I don't know who you are!\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "At most, one of the code blocks specified will be executed. If an `else` clause isn’t included, and all the conditions are false, then none of the blocks will be executed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Using a lengthy `if/elif/else` series can be a little inelegant, especially when the actions are simple statements like `print()`. In many cases, there may be a more Pythonic way to accomplish the same thing.\n", - "> \n", - "> Here’s one possible alternative to the example above using f-string:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello Joe\n" - ] - } - ], - "source": [ - "name = 'Joe'\n", - "\n", - "if name in ['Fred', 'Xander', 'Joe', 'Arnold']:\n", - " print(f'Hello {name}')\n", - "else:\n", - " print(\"I don't know who you are!\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "An `if` statement with `elif` clauses uses short-circuit evaluation, analogous to what you saw with the `and` and `or` operators. Once one of the expressions is found to be true and its block is executed, none of the remaining expressions are tested. This is demonstrated below:" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'var' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_10923/504837137.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvar\u001b[0m \u001b[0;31m# Not defined\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'var' is not defined" - ] - } - ], - "source": [ - "var # Not defined" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n" - ] - } - ], - "source": [ - "if 'a' in 'bar':\n", - " print('foo')\n", - "elif 1/0:\n", - " print(\"This won't happen\")\n", - "elif var:\n", - " print(\"This won't either\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The second expression contains a division by zero, and the third references an undefined variable `var`. Either would raise an error, but neither is evaluated because the first condition specified is true." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## One-Line `if` Statements" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is customary to write if `` on one line and `` indented on the following line like this:\n", - "\n", - "```python\n", - "if :\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But it is permissible to write an entire if statement on one line. The following is functionally equivalent to the example above:\n", - "\n", - "```python\n", - "if : \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There can even be more than one `` on the same line, separated by semicolons:\n", - "\n", - "```python\n", - "if : ; ; ...; \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But what does this mean? There are two possible interpretations:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. If `` is true, execute ``.\n", - "\n", - "Then, execute ` ... ` unconditionally, irrespective of whether `` is true or not.\n", - "\n", - "2. If `` is true, execute all of ` ... `. Otherwise, don’t execute any of them." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python takes the latter interpretation. The semicolon separating the `` has higher precedence than the colon following ``—in computer lingo, the semicolon is said to bind more tightly than the colon. Thus, the `` are treated as a suite, and either all of them are executed, or none of them are:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "2\n", - "3\n" - ] - } - ], - "source": [ - "if 'f' in 'foo': print('1'); print('2'); print('3')" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "if 'z' in 'foo': print('1'); print('2'); print('3')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Multiple statements may be specified on the same line as an `elif` or `else` clause as well:" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "qux\n", - "quux\n" - ] - } - ], - "source": [ - "x = 2\n", - "if x == 1: print('foo'); print('bar'); print('baz')\n", - "elif x == 2: print('qux'); print('quux')\n", - "else: print('corge'); print('grault')" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "corge\n", - "grault\n" - ] - } - ], - "source": [ - "x = 3\n", - "if x == 1: print('foo'); print('bar'); print('baz')\n", - "elif x == 2: print('qux'); print('quux')\n", - "else: print('corge'); print('grault')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "While all of this works, and the interpreter allows it, it is generally discouraged on the grounds that it leads to poor readability, particularly for complex `if` statements. [PEP 8](https://www.python.org/dev/peps/pep-0008/#other-recommendations) specifically recommends against it." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As usual, it is somewhat a matter of taste. Most people would find the following more visually appealing and easier to understand at first glance than the example above:" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "corge\n", - "grault\n" - ] - } - ], - "source": [ - "x = 3\n", - "if x == 1:\n", - " print('foo')\n", - " print('bar')\n", - " print('baz')\n", - "elif x == 2:\n", - " print('qux')\n", - " print('quux')\n", - "else:\n", - " print('corge')\n", - " print('grault')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If an `if` statement is simple enough, though, putting it all on one line may be reasonable. Something like this probably wouldn’t raise anyone’s hackles too much:\n", - "\n", - "```python\n", - "debugging = True # Set to True to turn debugging on.\n", - "\n", - " .\n", - " .\n", - " .\n", - "\n", - "if debugging: print('About to call function foo()')\n", - "foo()\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "if x < 5:\n", - " print('True')\n", - "else:\n", - " print('False')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conditional Expressions (Python’s Ternary Operator)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "conditional expression. (It is also referred to as a conditional operator or ternary operator in various places in the Python documentation.) Conditional expressions were proposed for addition to the language in [PEP 308](https://www.python.org/dev/peps/pep-0308) and green-lighted by Guido in 2005." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In its simplest form, the syntax of the conditional expression is as follows:\n", - "\n", - "```python\n", - " if else \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is different from the `if` statement forms listed above because it is not a control structure that directs the flow of program execution. It acts more like an operator that defines an expression. In the above example, `` is evaluated first. If it is true, the expression evaluates to ``. If it is false, the expression evaluates to ``." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice the non-obvious order: the middle expression is evaluated first, and based on that result, one of the expressions on the ends is returned. Here are some examples that will hopefully help clarify:" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Let's go to the beach\n" - ] - } - ], - "source": [ - "raining = False\n", - "print(\"Let's go to the\", 'beach' if not raining else 'library')" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Let's go to the library\n" - ] - } - ], - "source": [ - "raining = True\n", - "print(\"Let's go to the\", 'beach' if not raining else 'library')" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'minor'" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "age = 12\n", - "s = 'minor' if age < 21 else 'adult'\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'no'" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'yes' if ('qux' in ['foo', 'bar', 'baz']) else 'no'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Python’s conditional expression is similar to the ` ? : ` syntax used by many other languages—C, Perl and Java to name a few. In fact, the `?:` operator is commonly called the ternary operator in those languages, which is probably the reason Python’s conditional expression is sometimes referred to as the Python ternary operator.\n", - "> \n", - "> You can see in PEP 308 that the ` ? : ` syntax was considered for Python but ultimately rejected in favor of the syntax shown above." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A common use of the conditional expression is to select variable assignment. For example, suppose you want to find the larger of two numbers. Of course, there is a built-in function `max()` that does just this (and more) that you could use. But suppose you want to write your own code from scratch." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You could use a standard `if` statement with an `else` clause:\n", - "\n", - "```python\n", - "if a > b:\n", - " m = a\n", - "else:\n", - " m = b\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But a conditional expression is shorter and arguably more readable as well:\n", - "\n", - "```python\n", - "m = a if a > b else b\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Remember that the conditional expression behaves like an expression syntactically. It can be used as part of a longer expression. The conditional expression has lower precedence than virtually all the other operators, so parentheses are needed to group it by itself." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the following example, the `+` operator binds more tightly than the conditional expression, so `1 + x` and `y + 2` are evaluated first, followed by the conditional expression. The parentheses in the second case are unnecessary and do not change the result:" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "42" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = y = 40\n", - "z = 1 + x if x > y else y + 2\n", - "z" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "42" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "z = (1 + x) if x > y else (y + 2)\n", - "z" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you want the conditional expression to be evaluated first, you need to surround it with grouping parentheses. In the next example, (`x if x > y else y`) is evaluated first. The result is `y`, which is `40`, so `z` is assigned `1 + 40 + 2 = 43`:" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [], - "source": [ - "x = y = 40" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "43" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "z = 1 + (x if x > y else y) + 2\n", - "z" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you are using a conditional expression as part of a larger expression, it probably is a good idea to use grouping parentheses for clarification even if they are not needed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Conditional expressions also use [short-circuit evaluation](https://realpython.com/python-operators-expressions/#compound-logical-expressions-and-short-circuit-evaluation) like compound logical expressions. Portions of a conditional expression are not evaluated if they don’t need to be.\n", - "\n", - "In the expression ` if else `:\n", - "\n", - "- If `` is true, `` is returned and `` is not evaluated.\n", - "- If `` is false, `` is returned and `` is not evaluated." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As before, you can verify this by using terms that would raise an error:" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "'foo' if True else 1/0" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 81, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "1/0 if False else 'bar'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In both cases, the `1/0` terms are not evaluated, so no exception is raised." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Conditional expressions can also be chained together, as a sort of alternative `if/elif/else` structure, as shown here:" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [], - "source": [ - "s = ('foo' if (x == 1) else\n", - " 'bar' if (x == 2) else\n", - " 'baz' if (x == 3) else\n", - " 'qux' if (x == 4) else\n", - " 'quux'\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'quux'" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It’s not clear that this has any significant advantage over the corresponding `if/elif/else` statement, but it is syntactically correct Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The Python `pass` Statement" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Occasionally, you may find that you want to write what is called a code stub: a placeholder for where you will eventually put a block of code that you haven’t implemented yet." - ] - }, - { - "cell_type": "code", - "execution_count": 91, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n" - ] - } - ], - "source": [ - "name = 'Ali'\n", - "\n", - "if name == 'Ali':\n", - " # TODO: add name to database\n", - " pass\n", - "else:\n", - " # TODO: warn user about registeration\n", - " pass\n", - "\n", - "print('here')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In languages where token delimiters are used to define blocks, like the curly braces in Perl and C, empty delimiters can be used to define a code stub. For example, the following is legitimate Perl or C code:\n", - "\n", - "```c\n", - "# This is not Python\n", - "if (x)\n", - "{\n", - "}\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, the empty curly braces define an empty block. Perl or C will evaluate the expression `x`, and then even if it is true, quietly do nothing." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Because Python uses indentation instead of delimiters, it is not possible to specify an empty block. If you introduce an `if` statement with `if :`, something has to come after it, either on the same line or indented on the following line. Consider the following code (if you try it you will get `IndentationError`:" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "ename": "IndentationError", - "evalue": "expected an indented block (, line 3)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m3\u001b[0m\n\u001b[0;31m print('foo')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n" - ] - } - ], - "source": [ - "if True:\n", - "\n", - "print('foo')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Python `pass` statement solves this problem. It doesn’t change program behavior at all. It is used as a placeholder to keep the interpreter happy in any situation where a statement is syntactically required, but you don’t really want to do anything:" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n" - ] - } - ], - "source": [ - "if True:\n", - " pass\n", - "\n", - "print('foo')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With the completion of this tutorial, you are beginning to write Python code that goes beyond simple sequential execution:\n", - "\n", - "- You were introduced to the concept of **control structures**. These are compound statements that alter program **control flow**—the order of execution of program statements.\n", - "- You learned how to group individual statements together into a **block** or **suite**.\n", - "- You encountered your first control structure, the if statement, which makes it possible to **conditionally** execute a statement or block based on evaluation of program data." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All of these concepts are crucial to developing more complex Python code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next two tutorials will present two new control structures: the while statement and the for statement. These structures facilitate **iteration**, execution of a statement or block of statements repeatedly." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Conditional Statements in Python"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Introduction to the `if` Statement](#introduction_to_the_`if`_statement)\n* [Grouping Statements: Indentation and Blocks](#grouping_statements:_indentation_and_blocks)\n * [Python: It\u2019s All About the Indentation](#python:_it\u2019s_all_about_the_indentation)\n * [What Do Other Languages Do?](#what_do_other_languages_do?)\n * [Which Is Better?](#which_is_better?)\n* [The `else` and `elif` Clauses](#the_`else`_and_`elif`_clauses)\n* [One-Line `if` Statements](#one-line_`if`_statements)\n* [Conditional Expressions (Python\u2019s Ternary Operator)](#conditional_expressions_(python\u2019s_ternary_operator))\n* [The Python `pass` Statement](#the_python_`pass`_statement)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["From the previous tutorials in this series, you now have quite a bit of Python code under your belt. Everything you have seen so far has consisted of **sequential execution** , in which statements are always performed one after the next, in exactly the order specified."]}, {"cell_type": "markdown", "metadata": {}, "source": ["But the world is often more complicated than that. Frequently, a program needs to skip over some statements, execute a series of statements repetitively, or choose between alternate sets of statements to execute."]}, {"cell_type": "markdown", "metadata": {}, "source": ["That is where **control structures** come in. A control structure directs the order of execution of the statements in a program (referred to as the program\u2019s control flow)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the real world, we commonly must evaluate information around us and then choose one course of action or another based on what we observe:\n", "\n", "> If the weather is nice, then I\u2019ll mow the lawn. (It\u2019s implied that if the weather isn\u2019t nice, then I won\u2019t mow the lawn.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In a Python program, the if statement is how you perform this sort of decision-making. It allows for **conditional** execution of a statement or group of statements based on the value of an expression."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The outline of this section is as follows:\n", "\n", "- First, you\u2019ll get a quick overview of the `if` statement in its simplest form.\n", "- Next, using the if statement as a model, you\u2019ll see why control structures require some mechanism for grouping statements together into **compound statements** or **blocks**. You\u2019ll learn how this is done in Python.\n", "- Lastly, you\u2019ll tie it all together and learn how to write complex decision-making code."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Introduction to the `if` Statement"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We\u2019ll start by looking at the most basic type of `if` statement. In its simplest form, it looks like this:\n", "\n", "```python\n", "if :\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the form shown above:\n", "\n", "- `` is an expression evaluated in a Boolean context, as discussed in the section on Logical Operators in the Operators and Expressions section.\n", "- `` is a valid Python statement, which must be indented. (You will see why very soon.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If `` is true (evaluates to a value that is \u201ctruthy\u201d), then `` is executed. If `` is false, then `` is skipped over and not executed."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that the colon (`:`) following `` is required. Some programming languages require `` to be enclosed in parentheses, but Python does not."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here are several examples of this type of `if` statement:"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["x = 0\n", "y = 5"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["yes\n"]}], "source": ["if x < y: # Truthy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["if y < x: # Falsy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["yes\n"]}], "source": ["if x: # Falsy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["yes\n"]}], "source": ["if y: # Truthy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["yes\n"]}], "source": ["if x or y: # Truthy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": ["if x and y: # Falsy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["yes\n"]}], "source": ["if 'aul' in 'grault': # Truthy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": ["if 'quux' in ['foo', 'bar', 'baz']: # Falsy\n", " print('yes')"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": ["if 10 in [1, 2, 3, 4]:\n", " print('hi')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Grouping Statements: Indentation and Blocks"]}, {"cell_type": "markdown", "metadata": {}, "source": ["So far, so good.\n", "\n", "But let\u2019s say you want to evaluate a condition and then do more than one thing if it is true:\n", "\n", "> If the weather is nice, then I will:\n", "> \n", "> - Mow the lawn\n", "> - Weed the garden\n", "> - Take the dog for a walk\n", "> \n", "> (If the weather isn\u2019t nice, then I won\u2019t do any of these things.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In all the examples shown above, each `if `: has been followed by only a single ``. There needs to be some way to say \"If `` is true, do all of the following things.\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["The usual approach taken by most programming languages is to define a syntactic device that groups multiple statements into one **compound statement** or **block**. A block is regarded syntactically as a single entity. When it is the target of an `if` statement, and `` is true, then all the statements in the block are executed. If `` is false, then none of them are."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Virtually all programming languages provide the capability to define blocks, but they don\u2019t all provide it in the same way. Let\u2019s see how Python does it."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Python: It\u2019s All About the Indentation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python follows a convention known as the [off-side rule](https://en.wikipedia.org/wiki/Off-side_rule), a term coined by British computer scientist Peter J. Landin. (The term is taken from the offside law in association football.) Languages that adhere to the off-side rule define blocks by indentation. Python is one of a relatively small set of [off-side rule languages](https://en.wikipedia.org/wiki/Off-side_rule#Off-side_rule_languages)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Recall from the previous section on Python program structure that indentation has special significance in a Python program. Now you know why: indentation is used to define compound statements or blocks. In a Python program, contiguous statements that are indented to the same level are considered to be part of the same block."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Thus, a compound `if` statement in Python looks like this:\n", "\n", "```python\n", "if :\n", " \n", " \n", " ...\n", " \n", "\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, all the statements at the matching indentation level (lines 2 to 5) are considered part of the same block. The entire block is executed if `` is true, or skipped over if `` is false. Either way, execution proceeds with `` (line 6) afterward.\n", "\n", "\"if-block\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["Notice that there is no token that denotes the end of the block. Rather, the end of the block is indicated by a line that is indented less than the lines of the block itself."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** In the Python documentation, a group of statements defined by indentation is often referred to as a **suite**. This tutorial series uses the terms block and suite interchangeably."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Consider the following code:"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["After conditional\n"]}], "source": ["if 'foo' in ['bar', 'baz', 'qux']:\n", " print('Expression was true')\n", " print('Executing statement in suite')\n", " print('...')\n", " print('Done.')\n", " \n", "print('After conditional')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The four `print()` statements on lines 2 to 5 are indented to the same level as one another. They constitute the block that would be executed if the condition were true. But it is false, so all the statements in the block are skipped. After the end of the compound `if` statement has been reached (whether the statements in the block on lines 2 to 5 are executed or not), execution proceeds to the first statement having a lesser indentation level: the `print()` statement on line 6."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Blocks can be nested to arbitrary depth. Each indent defines a new block, and each outdent ends the preceding block. The resulting structure is straightforward, consistent, and intuitive."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here is a more complicated `if` block: "]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Outer condition is true\n", "Between inner conditions\n", "Inner condition 2\n", "End of outer condition\n", "After outer condition\n"]}], "source": ["# Does line execute? Yes No\n", "# --- --\n", "if 'foo' in ['foo', 'bar', 'baz']: # x\n", " print('Outer condition is true') # x\n", "\n", " if 10 > 20: # x\n", " print('Inner condition 1') # x\n", "\n", " print('Between inner conditions') # x\n", "\n", " if 10 < 20: # x\n", " print('Inner condition 2') # x\n", "\n", " print('End of outer condition') # x\n", "print('After outer condition') # x"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### What Do Other Languages Do?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Perhaps you\u2019re curious what the alternatives are. How are blocks defined in languages that don\u2019t adhere to the off-side rule?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The tactic used by most programming languages is to designate special tokens that mark the start and end of a block. For example, in Perl blocks are defined with pairs of curly braces (`{}`) like this:\n", "\n", "```perl\n", "# (This is Perl, not Python)\n", "if () {\n", " ;\n", " ;\n", " ...\n", " ;\n", "}\n", ";\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["C/C++, Java, and a whole host of other languages use curly braces in this way.\n", "\n", "\"if-block-c\""]}, {"cell_type": "markdown", "metadata": {}, "source": ["Other languages, such as Algol and Pascal, use keywords `begin` and `end` to enclose blocks."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Which Is Better?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Better is in the eye of the beholder. On the whole, programmers tend to feel rather strongly about how they do things. Debate about the merits of the off-side rule can run pretty hot."]}, {"cell_type": "markdown", "metadata": {}, "source": ["On the plus side:\n", "\n", "- Python\u2019s use of indentation is clean, concise, and consistent.\n", "- In programming languages that do not use the off-side rule, indentation of code is completely independent of block definition and code function. It\u2019s possible to write code that is indented in a manner that does not actually match how the code executes, thus creating a mistaken impression when a person just glances at it. This sort of mistake is virtually impossible to make in Python.\n", "- Use of indentation to define blocks forces you to maintain code formatting standards you probably should be using anyway."]}, {"cell_type": "markdown", "metadata": {}, "source": ["On the negative side:\n", "\n", "- Many programmers don\u2019t like to be forced to do things a certain way. They tend to have strong opinions about what looks good and what doesn\u2019t, and they don\u2019t like to be shoehorned into a specific choice.\n", "- Some editors insert a mix of space and tab characters to the left of indented lines, which makes it difficult for the Python interpreter to determine indentation levels. On the other hand, it is frequently possible to configure editors not to do this. It generally isn\u2019t considered desirable to have a mix of tabs and spaces in source code anyhow, no matter the language."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Like it or not, if you\u2019re programming in Python, you\u2019re stuck with the off-side rule. All control structures in Python use it, as you will see in several future tutorials."]}, {"cell_type": "markdown", "metadata": {}, "source": ["For what it\u2019s worth, many programmers who have been used to languages with more traditional means of block definition have initially recoiled at Python\u2019s way but have gotten comfortable with it and have even grown to prefer it."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The `else` and `elif` Clauses"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now you know how to use an `if` statement to conditionally execute a single statement or a block of several statements. It\u2019s time to find out what else you can do."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Sometimes, you want to evaluate a condition and take one path if it is true but specify an alternative path if it is not. This is accomplished with an `else` clause:\n", "\n", "```python\n", "if :\n", " \n", "else:\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If `` is true, the first suite is executed, and the second is skipped. If `` is false, the first suite is skipped and the second is executed. Either way, execution then resumes after the second suite. Both suites are defined by indentation, as described above."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this example, `x` is less than `50`, so the first suite (lines 4 to 5) are executed, and the second suite (lines 7 to 8) are skipped:"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["(first suite)\n", "x is small\n"]}], "source": ["x = 20\n", "\n", "if x < 50:\n", " print('(first suite)')\n", " print('x is small')\n", "else:\n", " print('(second suite)')\n", " print('x is large')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, on the other hand, `x` is greater than `50`, so the first suite is passed over, and the second suite executed:"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["(second suite)\n", "x is large\n"]}], "source": ["x = 120\n", "\n", "if x < 50:\n", " print('(first suite)')\n", " print('x is small')\n", "else:\n", " print('(second suite)')\n", " print('x is large')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["There is also syntax for branching execution based on several alternatives. For this, use one or more `elif` (short for `else if`) clauses. Python evaluates each `` in turn and executes the suite corresponding to the first that is true. If none of the expressions are true, and an `else` clause is specified, then its suite is executed:\n", "\n", "```python\n", "if :\n", " \n", "elif :\n", " \n", "elif :\n", " \n", " ...\n", "else:\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["An arbitrary number of `elif` clauses can be specified. The `else` clause is optional. If it is present, there can be only one, and it must be specified last:"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Hello Joe\n"]}], "source": ["name = 'Joe'\n", "if name == 'Fred':\n", " print('Hello Fred')\n", "elif name == 'Xander':\n", " print('Hello Xander')\n", "elif name == 'Joe':\n", " print('Hello Joe')\n", "elif name == 'Arnold':\n", " print('Hello Arnold')\n", "else:\n", " print(\"I don't know who you are!\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["At most, one of the code blocks specified will be executed. If an `else` clause isn\u2019t included, and all the conditions are false, then none of the blocks will be executed."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Using a lengthy `if/elif/else` series can be a little inelegant, especially when the actions are simple statements like `print()`. In many cases, there may be a more Pythonic way to accomplish the same thing.\n", "> \n", "> Here\u2019s one possible alternative to the example above using f-string:"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Hello Joe\n"]}], "source": ["name = 'Joe'\n", "\n", "if name in ['Fred', 'Xander', 'Joe', 'Arnold']:\n", " print(f'Hello {name}')\n", "else:\n", " print(\"I don't know who you are!\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["An `if` statement with `elif` clauses uses short-circuit evaluation, analogous to what you saw with the `and` and `or` operators. Once one of the expressions is found to be true and its block is executed, none of the remaining expressions are tested. This is demonstrated below:"]}, {"cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [{"ename": "NameError", "evalue": "name 'var' is not defined", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_10923/504837137.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvar\u001b[0m \u001b[0;31m# Not defined\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'var' is not defined"]}], "source": ["var # Not defined"]}, {"cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n"]}], "source": ["if 'a' in 'bar':\n", " print('foo')\n", "elif 1/0:\n", " print(\"This won't happen\")\n", "elif var:\n", " print(\"This won't either\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The second expression contains a division by zero, and the third references an undefined variable `var`. Either would raise an error, but neither is evaluated because the first condition specified is true."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## One-Line `if` Statements"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is customary to write if `` on one line and `` indented on the following line like this:\n", "\n", "```python\n", "if :\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["But it is permissible to write an entire if statement on one line. The following is functionally equivalent to the example above:\n", "\n", "```python\n", "if : \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["There can even be more than one `` on the same line, separated by semicolons:\n", "\n", "```python\n", "if : ; ; ...; \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["But what does this mean? There are two possible interpretations:"]}, {"cell_type": "markdown", "metadata": {}, "source": ["1. If `` is true, execute ``.\n", "\n", "Then, execute ` ... ` unconditionally, irrespective of whether `` is true or not.\n", "\n", "2. If `` is true, execute all of ` ... `. Otherwise, don\u2019t execute any of them."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python takes the latter interpretation. The semicolon separating the `` has higher precedence than the colon following ``\u2014in computer lingo, the semicolon is said to bind more tightly than the colon. Thus, the `` are treated as a suite, and either all of them are executed, or none of them are:"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1\n", "2\n", "3\n"]}], "source": ["if 'f' in 'foo': print('1'); print('2'); print('3')"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": ["if 'z' in 'foo': print('1'); print('2'); print('3')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Multiple statements may be specified on the same line as an `elif` or `else` clause as well:"]}, {"cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["qux\n", "quux\n"]}], "source": ["x = 2\n", "if x == 1: print('foo'); print('bar'); print('baz')\n", "elif x == 2: print('qux'); print('quux')\n", "else: print('corge'); print('grault')"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["corge\n", "grault\n"]}], "source": ["x = 3\n", "if x == 1: print('foo'); print('bar'); print('baz')\n", "elif x == 2: print('qux'); print('quux')\n", "else: print('corge'); print('grault')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["While all of this works, and the interpreter allows it, it is generally discouraged on the grounds that it leads to poor readability, particularly for complex `if` statements. [PEP 8](https://www.python.org/dev/peps/pep-0008/#other-recommendations) specifically recommends against it."]}, {"cell_type": "markdown", "metadata": {}, "source": ["As usual, it is somewhat a matter of taste. Most people would find the following more visually appealing and easier to understand at first glance than the example above:"]}, {"cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["corge\n", "grault\n"]}], "source": ["x = 3\n", "if x == 1:\n", " print('foo')\n", " print('bar')\n", " print('baz')\n", "elif x == 2:\n", " print('qux')\n", " print('quux')\n", "else:\n", " print('corge')\n", " print('grault')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If an `if` statement is simple enough, though, putting it all on one line may be reasonable. Something like this probably wouldn\u2019t raise anyone\u2019s hackles too much:\n", "\n", "```python\n", "debugging = True # Set to True to turn debugging on.\n", "\n", " .\n", " .\n", " .\n", "\n", "if debugging: print('About to call function foo()')\n", "foo()\n", "```"]}, {"cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["False\n"]}], "source": ["if x < 5:\n", " print('True')\n", "else:\n", " print('False')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conditional Expressions (Python\u2019s Ternary Operator)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["conditional expression. (It is also referred to as a conditional operator or ternary operator in various places in the Python documentation.) Conditional expressions were proposed for addition to the language in [PEP 308](https://www.python.org/dev/peps/pep-0308) and green-lighted by Guido in 2005."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In its simplest form, the syntax of the conditional expression is as follows:\n", "\n", "```python\n", " if else \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This is different from the `if` statement forms listed above because it is not a control structure that directs the flow of program execution. It acts more like an operator that defines an expression. In the above example, `` is evaluated first. If it is true, the expression evaluates to ``. If it is false, the expression evaluates to ``."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Notice the non-obvious order: the middle expression is evaluated first, and based on that result, one of the expressions on the ends is returned. Here are some examples that will hopefully help clarify:"]}, {"cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Let's go to the beach\n"]}], "source": ["raining = False\n", "print(\"Let's go to the\", 'beach' if not raining else 'library')"]}, {"cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Let's go to the library\n"]}], "source": ["raining = True\n", "print(\"Let's go to the\", 'beach' if not raining else 'library')"]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [{"data": {"text/plain": ["'minor'"]}, "execution_count": 28, "metadata": {}, "output_type": "execute_result"}], "source": ["age = 12\n", "s = 'minor' if age < 21 else 'adult'\n", "s"]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"data": {"text/plain": ["'no'"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["'yes' if ('qux' in ['foo', 'bar', 'baz']) else 'no'"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Python\u2019s conditional expression is similar to the ` ? : ` syntax used by many other languages\u2014C, Perl and Java to name a few. In fact, the `?:` operator is commonly called the ternary operator in those languages, which is probably the reason Python\u2019s conditional expression is sometimes referred to as the Python ternary operator.\n", "> \n", "> You can see in PEP 308 that the ` ? : ` syntax was considered for Python but ultimately rejected in favor of the syntax shown above."]}, {"cell_type": "markdown", "metadata": {}, "source": ["A common use of the conditional expression is to select variable assignment. For example, suppose you want to find the larger of two numbers. Of course, there is a built-in function `max()` that does just this (and more) that you could use. But suppose you want to write your own code from scratch."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You could use a standard `if` statement with an `else` clause:\n", "\n", "```python\n", "if a > b:\n", " m = a\n", "else:\n", " m = b\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["But a conditional expression is shorter and arguably more readable as well:\n", "\n", "```python\n", "m = a if a > b else b\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Remember that the conditional expression behaves like an expression syntactically. It can be used as part of a longer expression. The conditional expression has lower precedence than virtually all the other operators, so parentheses are needed to group it by itself."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the following example, the `+` operator binds more tightly than the conditional expression, so `1 + x` and `y + 2` are evaluated first, followed by the conditional expression. The parentheses in the second case are unnecessary and do not change the result:"]}, {"cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [{"data": {"text/plain": ["42"]}, "execution_count": 31, "metadata": {}, "output_type": "execute_result"}], "source": ["x = y = 40\n", "z = 1 + x if x > y else y + 2\n", "z"]}, {"cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [{"data": {"text/plain": ["42"]}, "execution_count": 32, "metadata": {}, "output_type": "execute_result"}], "source": ["z = (1 + x) if x > y else (y + 2)\n", "z"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you want the conditional expression to be evaluated first, you need to surround it with grouping parentheses. In the next example, (`x if x > y else y`) is evaluated first. The result is `y`, which is `40`, so `z` is assigned `1 + 40 + 2 = 43`:"]}, {"cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": ["x = y = 40"]}, {"cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [{"data": {"text/plain": ["43"]}, "execution_count": 34, "metadata": {}, "output_type": "execute_result"}], "source": ["z = 1 + (x if x > y else y) + 2\n", "z"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you are using a conditional expression as part of a larger expression, it probably is a good idea to use grouping parentheses for clarification even if they are not needed."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Conditional expressions also use [short-circuit evaluation](https://realpython.com/python-operators-expressions/#compound-logical-expressions-and-short-circuit-evaluation) like compound logical expressions. Portions of a conditional expression are not evaluated if they don\u2019t need to be.\n", "\n", "In the expression ` if else `:\n", "\n", "- If `` is true, `` is returned and `` is not evaluated.\n", "- If `` is false, `` is returned and `` is not evaluated."]}, {"cell_type": "markdown", "metadata": {}, "source": ["As before, you can verify this by using terms that would raise an error:"]}, {"cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 80, "metadata": {}, "output_type": "execute_result"}], "source": ["'foo' if True else 1/0"]}, {"cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 81, "metadata": {}, "output_type": "execute_result"}], "source": ["1/0 if False else 'bar'"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In both cases, the `1/0` terms are not evaluated, so no exception is raised."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Conditional expressions can also be chained together, as a sort of alternative `if/elif/else` structure, as shown here:"]}, {"cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": ["s = ('foo' if (x == 1) else\n", " 'bar' if (x == 2) else\n", " 'baz' if (x == 3) else\n", " 'qux' if (x == 4) else\n", " 'quux'\n", ")"]}, {"cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [{"data": {"text/plain": ["'quux'"]}, "execution_count": 38, "metadata": {}, "output_type": "execute_result"}], "source": ["s"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It\u2019s not clear that this has any significant advantage over the corresponding `if/elif/else` statement, but it is syntactically correct Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The Python `pass` Statement"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Occasionally, you may find that you want to write what is called a code stub: a placeholder for where you will eventually put a block of code that you haven\u2019t implemented yet."]}, {"cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["here\n"]}], "source": ["name = 'Ali'\n", "\n", "if name == 'Ali':\n", " # TODO: add name to database\n", " pass\n", "else:\n", " # TODO: warn user about registeration\n", " pass\n", "\n", "print('here')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In languages where token delimiters are used to define blocks, like the curly braces in Perl and C, empty delimiters can be used to define a code stub. For example, the following is legitimate Perl or C code:\n", "\n", "```c\n", "# This is not Python\n", "if (x)\n", "{\n", "}\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, the empty curly braces define an empty block. Perl or C will evaluate the expression `x`, and then even if it is true, quietly do nothing."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Because Python uses indentation instead of delimiters, it is not possible to specify an empty block. If you introduce an `if` statement with `if :`, something has to come after it, either on the same line or indented on the following line. Consider the following code (if you try it you will get `IndentationError`:"]}, {"cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [{"ename": "IndentationError", "evalue": "expected an indented block (, line 3)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m3\u001b[0m\n\u001b[0;31m print('foo')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n"]}], "source": ["if True:\n", "\n", "print('foo')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The Python `pass` statement solves this problem. It doesn\u2019t change program behavior at all. It is used as a placeholder to keep the interpreter happy in any situation where a statement is syntactically required, but you don\u2019t really want to do anything:"]}, {"cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n"]}], "source": ["if True:\n", " pass\n", "\n", "print('foo')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion"]}, {"cell_type": "markdown", "metadata": {}, "source": ["With the completion of this tutorial, you are beginning to write Python code that goes beyond simple sequential execution:\n", "\n", "- You were introduced to the concept of **control structures**. These are compound statements that alter program **control flow**\u2014the order of execution of program statements.\n", "- You learned how to group individual statements together into a **block** or **suite**.\n", "- You encountered your first control structure, the if statement, which makes it possible to **conditionally** execute a statement or block based on evaluation of program data."]}, {"cell_type": "markdown", "metadata": {}, "source": ["All of these concepts are crucial to developing more complex Python code."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The next two tutorials will present two new control structures: the while statement and the for statement. These structures facilitate **iteration**, execution of a statement or block of statements repeatedly."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git "a/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" "b/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" index 73dfd95..6bfd023 100755 --- "a/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" +++ "b/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" @@ -1,13971 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Python \"while\" Loops (Indefinite Iteration)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Iteration** means executing the same block of code over and over, potentially many times. A programming structure that implements iteration is called a **loop**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In programming, there are two types of iteration, indefinite and definite:\n", - "\n", - "- With **indefinite iteration**, the number of times the loop is executed isn’t specified explicitly in advance. Rather, the designated block is executed repeatedly as long as some condition is met.\n", - "\n", - "- With **definite iteration**, the number of times the designated block will be executed is specified explicitly at the time the loop starts." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this section, you’ll:\n", - "\n", - "- Learn about the while loop, the Python control structure used for indefinite iteration\n", - "- See how to break out of a loop or loop iteration prematurely\n", - "- Explore infinite loops" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When you’re finished, you should have a good grasp of how to use indefinite iteration in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The `while` Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let’s see how Python’s `while` statement is used to construct loops. We’ll start simple and embellish as we go." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The format of a rudimentary `while` loop is shown below:\n", - " \n", - "```python\n", - "while :\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`` represents the block to be repeatedly executed, often referred to as the body of the loop. This is denoted with indentation, just as in an if statement." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Remember:** All control structures in Python use indentation to define blocks. See the discussion on grouping statements in the previous section to review." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The controlling expression, ``, typically involves one or more variables that are initialized prior to starting the loop and then modified somewhere in the loop body." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When a while loop is encountered, `` is first evaluated in Boolean context. If it is true, the loop body is executed. Then `` is checked again, and if still true, the body is executed again. This continues until `` becomes false, at which point program execution proceeds to the first statement beyond the loop body." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider this loop:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "3\n", - "2\n", - "1\n", - "0\n" - ] - } - ], - "source": [ - "n = 5\n", - "while n > 0:\n", - " n -= 1\n", - " print(n)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here’s what’s happening in this example:\n", - "\n", - "- n is initially `5`. The expression in the while statement header on line 2 is `n > 0`, which is true, so the loop body executes. Inside the loop body on line 3, `n` is decremented by 1 to 4, and then printed.\n", - "\n", - "- When the body of the loop has finished, program execution returns to the top of the loop at line 2, and the expression is evaluated again. It is still true, so the body executes again, and `3` is printed.\n", - "\n", - "- This continues until `n` becomes `0`. At that point, when the expression is tested, it is false, and the loop terminates. Execution would resume at the first statement following the loop body, but there isn’t one in this case." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the controlling expression of the `while` loop is tested first, before anything else happens. If it’s false to start with, the loop body will never be executed at all:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "n = 0\n", - "while n > 0:\n", - " n -= 1\n", - " print(n)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the example above, when the loop is encountered, `n` is `0`. The controlling expression `n > 0` is already false, so the loop body never executes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here’s another `while` loop involving a list, rather than a numeric comparison:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "baz\n", - "bar\n", - "foo\n" - ] - } - ], - "source": [ - "a = ['foo', 'bar', 'baz']\n", - "while a:\n", - " print(a.pop(-1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When a list is evaluated in Boolean context, it is truthy if it has elements in it and falsy if it is empty. In this example, a is true as long as it has elements in it. Once all the items have been removed with the `.pop()` method and the list is empty, `a` is false, and the loop terminates." - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n" - ] - } - ], - "source": [ - "x = 5\n", - "if x < 5:\n", - " print('here')" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n", - "here\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_65870/2171307792.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'here'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/ipykernel/iostream.py\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, string)\u001b[0m\n\u001b[1;32m 517\u001b[0m \u001b[0mis_child\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_is_master_process\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 518\u001b[0m \u001b[0;31m# only touch the buffer in the IO thread to avoid races\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 519\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpub_thread\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mschedule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_buffer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 520\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_child\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 521\u001b[0m \u001b[0;31m# mp.Pool cannot be trusted to flush promptly (or ever),\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/ipykernel/iostream.py\u001b[0m in \u001b[0;36mschedule\u001b[0;34m(self, f)\u001b[0m\n\u001b[1;32m 212\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_events\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 213\u001b[0m \u001b[0;31m# wake event thread (message content is ignored)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 214\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_event_pipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mb''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 215\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 216\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/zmq/sugar/socket.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, data, flags, copy, track, routing_id, group)\u001b[0m\n\u001b[1;32m 503\u001b[0m )\n\u001b[1;32m 504\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroup\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 505\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSocket\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mflags\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrack\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtrack\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 506\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 507\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0msend_multipart\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmsg_parts\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrack\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket.Socket.send\u001b[0;34m()\u001b[0m\n", - "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket.Socket.send\u001b[0;34m()\u001b[0m\n", - "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket._send_copy\u001b[0;34m()\u001b[0m\n", - "\u001b[0;32m~/opt/anaconda3/envs/py37/lib/python3.7/site-packages/zmq/backend/cython/checkrc.pxd\u001b[0m in \u001b[0;36mzmq.backend.cython.checkrc._check_rc\u001b[0;34m()\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "x = 5\n", - "while x < 5:\n", - " print('here')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The Python `break` and `continue` Statements" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 5\n", - "\n", - "if x == 5:\n", - " print('x is 5')\n", - "elif x > 6:\n", - " print('x is greater than 6')\n", - "else:\n", - " print('else')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In each example you have seen so far, the entire body of the `while` loop is executed on each iteration. Python provides two keywords that terminate a loop iteration prematurely:\n", - "\n", - "- The Python **break** statement immediately terminates a loop entirely. Program execution proceeds to the first statement following the loop body.\n", - "\n", - "- The Python **continue** statement immediately terminates the current loop iteration. Execution jumps to the top of the loop, and the controlling expression is re-evaluated to determine whether the loop will execute again or terminate." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The distinction between `break` and `continue` is demonstrated in the following diagram:\n", - "\n", - "\"break" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "3\n", - "Loop ended.\n" - ] - } - ], - "source": [ - "n = 5\n", - "while n > 0:\n", - " n -= 1\n", - " if n == 2:\n", - " break\n", - " print(n)\n", - "print('Loop ended.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When `n` becomes `2`, the `break` statement is executed. The loop is terminated completely, and program execution jumps to the `print()` statement on line 7." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next block of code below, is identical except for a `continue` statement in place of the `break`:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "3\n", - "1\n", - "0\n", - "Loop ended.\n" - ] - } - ], - "source": [ - "n = 5\n", - "while n > 0:\n", - " n -= 1\n", - " if n == 2:\n", - " continue\n", - " print(n)\n", - "print('Loop ended.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This time, when `n` is `2`, the `continue` statement causes termination of that iteration. Thus, `2` isn’t printed. Execution returns to the top of the loop, the condition is re-evaluated, and it is still true. The loop resumes, terminating when `n` becomes `0`, as previously." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The `else` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python allows an optional `else` clause at the end of a `while` loop. This is a unique feature of Python, not found in most other programming languages. The syntax is shown below:\n", - "\n", - "```python\n", - "while :\n", - " \n", - "else:\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `` specified in the `else` clause will be executed when the while loop terminates." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "About now, you may be thinking, \"How is that useful?\" You could accomplish the same thing by putting those statements immediately after the `while` loop, without the `else`:\n", - "\n", - "```python\n", - "while :\n", - " \n", - "\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What’s the difference?\n", - "\n", - "In the latter case, without the `else` clause, `` will be executed after the `while` loop terminates, no matter what." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When `` are placed in an `else` clause, they will be executed only if the loop terminates \"by exhaustion\"—that is, if the loop iterates until the controlling condition becomes false. If the loop is exited by a `break` statement, the `else` clause won’t be executed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider the following example:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "3\n", - "2\n", - "1\n", - "0\n", - "Loop done.\n" - ] - } - ], - "source": [ - "n = 5\n", - "while n > 0:\n", - " n -= 1\n", - " print(n)\n", - "else:\n", - " print('Loop done.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this case, the loop repeated until the condition was exhausted: `n` became `0`, so `n > 0` became false. Because the loop lived out its natural life, so to speak, the `else` clause was executed. Now observe the difference here:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "3\n", - "2\n" - ] - } - ], - "source": [ - "n = 5\n", - "while n > 0:\n", - " n -= 1\n", - " print(n)\n", - " if n == 2:\n", - " break\n", - "else:\n", - " print('Loop done.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This loop is terminated prematurely with break, so the ‍else clause isn’t executed." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It may seem as if the meaning of the word `else` doesn’t quite fit the `while` loop as well as it does the if statement. Guido van Rossum, the creator of Python, has actually said that, if he had it to do over again, he’d leave the while loop’s `else` clause out of the language." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One of the following interpretations might help to make it more intuitive:\n", - "\n", - "- Think of the header of the loop (`while n > 0`) as an `if` statement (`if n > 0`) that gets executed over and over, with the `else` clause finally being executed when the condition becomes false.\n", - "\n", - "- Think of `else` as though it were `nobreak`, in that the block that follows gets executed if there wasn’t a break." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you don’t find either of these interpretations helpful, then feel free to ignore them." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When might an `else` clause on a while loop be useful? One common situation is if you are searching a list for a specific item. You can use `break` to exit the loop if the item is found, and the `else` clause can contain code that is meant to be executed if the item isn’t found:" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Corge not found in list.\n" - ] - } - ], - "source": [ - "a = ['foo', 'bar', 'baz', 'qux']\n", - "s = 'Corge'\n", - "\n", - "i = 0\n", - "while i < len(a):\n", - " if a[i] == s:\n", - " # Processing for item found\n", - " break\n", - " i += 1\n", - "else:\n", - " # Processing for item not found\n", - " print(s, 'not found in list.')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** The code shown above is useful to illustrate the concept, but you’d actually be very unlikely to search a list that way.\n", - "> \n", - "> First of all, lists are usually processed with definite iteration, not a `while` loop. Definite iteration is covered in the next tutorial in this series.\n", - "> \n", - "> Secondly, Python provides built-in ways to search for an item in a list. You can use the `in` operator:\n", - "> \n", - "> ```python\n", - ">>> if s in a:\n", - "... print(s, 'found in list.')\n", - "... else:\n", - "... print(s, 'not found in list.')\n", - "...\n", - "corge not found in list.\n", - "> ```\n", - "> The `list.index()` method would also work. This method raises a `ValueError` exception if the item isn’t found in the list, so you need to understand exception handling to use it. In Python, you use a `try` statement to handle an exception. An example is given below:\n", - "> \n", - "> ```python\n", - ">>> try:\n", - "... print(a.index('corge'))\n", - "... except ValueError:\n", - "... print(s, 'not found in list.')\n", - "...\n", - "corge not found in list.\n", - "> ```\n", - "> You will learn about exception handling later in this series." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "An `else` clause with a `while` loop is a bit of an oddity, not often seen. But don’t shy away from it if you find a situation in which you feel it adds clarity to your code!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Infinite Loops" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Suppose you write a `while` loop that theoretically never ends. Sounds weird, right?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider this example:\n", - "\n", - "```python\n", - ">>> while True:\n", - "... print('foo')\n", - "...\n", - "foo\n", - "foo\n", - "foo\n", - " .\n", - " .\n", - " .\n", - "foo\n", - "foo\n", - "foo\n", - "KeyboardInterrupt\n", - "Traceback (most recent call last):\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This code was terminated by `Ctrl+C`, which generates an interrupt from the keyboard. Otherwise, it would have gone on unendingly. Many foo output lines have been removed and replaced by the vertical ellipsis in the output shown." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Clearly, `True` will never be false, or we’re all in very big trouble. Thus, `while True`: initiates an infinite loop that will theoretically run forever." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Maybe that doesn’t sound like something you’d want to do, but this pattern is actually quite common. For example, you might write code for a service that starts up and runs forever accepting service requests. “Forever” in this context means until you shut it down, or until the heat death of the universe, whichever comes first." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "More prosaically, remember that loops can be broken out of with the `break` statement. It may be more straightforward to terminate a loop based on conditions recognized within the loop body, rather than on a condition evaluated at the top." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also specify multiple break statements in a loop:\n", - "```python\n", - "while True:\n", - " if : # One condition for loop termination\n", - " break\n", - " ...\n", - " if : # Another termination condition\n", - " break\n", - " ...\n", - " if : # Yet another\n", - " break\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In cases like this, where there are multiple reasons to end the loop, it is often cleaner to `break` out from several different locations, rather than try to specify all the termination conditions in the loop header." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Infinite loops can be very useful. Just remember that you must ensure the loop gets broken out of at some point, so it doesn’t truly become infinite." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Nested `while` Loops" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In general, Python control structures can be nested within one another. For example, `if/elif/else` conditional statements can be nested:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "son\n" - ] - } - ], - "source": [ - "age = 12\n", - "gender = 'M'\n", - "\n", - "if age < 18:\n", - " if gender == 'M':\n", - " print('son')\n", - " else:\n", - " print('daughter')\n", - "elif age >= 18 and age < 65:\n", - " if gender == 'M':\n", - " print('father')\n", - " else:\n", - " print('mother')\n", - "else:\n", - " if gender == 'M':\n", - " print('grandfather')\n", - " else:\n", - " print('grandmother')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly, a `while` loop can be contained within another `while` loop, as shown here:" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "> baz\n", - "> qux\n", - "bar\n", - "> baz\n", - "> qux\n" - ] - } - ], - "source": [ - "a = ['foo', 'bar']\n", - "while len(a):\n", - " print(a[0])\n", - " del a[0]\n", - " \n", - " b = ['baz', 'qux']\n", - " while len(b):\n", - " print('>', b[0])\n", - " del b[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A `break` or `continue` statement found within nested loops applies to the nearest enclosing loop:\n", - "\n", - "```python\n", - "while :\n", - " statement\n", - " statement\n", - "\n", - " while :\n", - " statement\n", - " statement\n", - " break # Applies to while : loop\n", - "\n", - " break # Applies to while : loop\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Additionally, while loops can be nested inside `if/elif/else` statements, and vice versa:\n", - "\n", - "```python\n", - "if :\n", - " statement\n", - " while :\n", - " statement\n", - " statement\n", - "else:\n", - " while :\n", - " statement\n", - " statement\n", - " statement\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```python\n", - "while :\n", - " if :\n", - " statement\n", - " elif :\n", - " statement\n", - " else:\n", - " statement\n", - "\n", - " if :\n", - " statement\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In fact, all the Python control structures can be intermingled with one another to whatever extent you need. That is as it should be. Imagine how frustrating it would be if there were unexpected restrictions like “A `while` loop can’t be contained within an `if` statement” or “`while` loops can only be nested inside one another at most four deep.” You’d have a very difficult time remembering them all." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## One-Line `while` Loops" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As with an `if` statement, a `while` loop can be specified on one line. If there are multiple statements in the block that makes up the loop body, they can be separated by semicolons (`;`):" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "3\n", - "2\n", - "1\n", - "0\n" - ] - } - ], - "source": [ - "n = 5\n", - "while n > 0: n -= 1; print(n)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This only works with simple statements though. You can’t combine two compound statements into one line. Thus, you can specify a `while` loop all on one line as above, and you write an `if` statement on one line:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n" - ] - } - ], - "source": [ - "if True: print('foo')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But you can’t do this:" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m while n > 0: n -= 1; if True: print('foo')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "while n > 0: n -= 1; if True: print('foo')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Remember that [PEP 8](https://www.python.org/dev/peps/pep-0008/#other-recommendations) discourages multiple statements on one line. So you probably shouldn’t be doing any of this very often anyhow." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this tutorial, you learned about **indefinite iteration** using the Python while loop. You’re now able to:\n", - "\n", - "- Construct basic and complex `while` loops\n", - "- Interrupt loop execution with `break` and `continue`\n", - "- Use the `else` clause with a while loop\n", - "- Deal with infinite loops" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You should now have a good grasp of how to execute a piece of code repetitively." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The next section covers **definite iteration** with for loops—recurrent execution where the number of repetitions is specified explicitly." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Python \"while\" Loops (Indefinite Iteration)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [The `while` Loop](#the_`while`_loop)\n* [The Python `break` and `continue` Statements](#the_python_`break`_and_`continue`_statements)\n* [The `else` Clause](#the_`else`_clause)\n* [Infinite Loops](#infinite_loops)\n* [Nested `while` Loops](#nested_`while`_loops)\n* [One-Line `while` Loops](#one-line_`while`_loops)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["**Iteration** means executing the same block of code over and over, potentially many times. A programming structure that implements iteration is called a **loop**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In programming, there are two types of iteration, indefinite and definite:\n", "\n", "- With **indefinite iteration**, the number of times the loop is executed isn\u2019t specified explicitly in advance. Rather, the designated block is executed repeatedly as long as some condition is met.\n", "\n", "- With **definite iteration**, the number of times the designated block will be executed is specified explicitly at the time the loop starts."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this section, you\u2019ll:\n", "\n", "- Learn about the while loop, the Python control structure used for indefinite iteration\n", "- See how to break out of a loop or loop iteration prematurely\n", "- Explore infinite loops"]}, {"cell_type": "markdown", "metadata": {}, "source": ["When you\u2019re finished, you should have a good grasp of how to use indefinite iteration in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The `while` Loop"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Let\u2019s see how Python\u2019s `while` statement is used to construct loops. We\u2019ll start simple and embellish as we go."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The format of a rudimentary `while` loop is shown below:\n", " \n", "```python\n", "while :\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Remember:** All control structures in Python use indentation to define blocks. See the discussion on grouping statements in the previous section to review."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The controlling expression, ``, typically involves one or more variables that are initialized prior to starting the loop and then modified somewhere in the loop body."]}, {"cell_type": "markdown", "metadata": {}, "source": ["When a while loop is encountered, `` is first evaluated in Boolean context. If it is true, the loop body is executed. Then `` is checked again, and if still true, the body is executed again. This continues until `` becomes false, at which point program execution proceeds to the first statement beyond the loop body."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Consider this loop:"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["4\n", "3\n", "2\n", "1\n", "0\n"]}], "source": ["n = 5\n", "while n > 0:\n", " n -= 1\n", " print(n)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here\u2019s what\u2019s happening in this example:\n", "\n", "- n is initially `5`. The expression in the while statement header on line 2 is `n > 0`, which is true, so the loop body executes. Inside the loop body on line 3, `n` is decremented by 1 to 4, and then printed.\n", "\n", "- When the body of the loop has finished, program execution returns to the top of the loop at line 2, and the expression is evaluated again. It is still true, so the body executes again, and `3` is printed.\n", "\n", "- This continues until `n` becomes `0`. At that point, when the expression is tested, it is false, and the loop terminates. Execution would resume at the first statement following the loop body, but there isn\u2019t one in this case."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that the controlling expression of the `while` loop is tested first, before anything else happens. If it\u2019s false to start with, the loop body will never be executed at all:"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": ["n = 0\n", "while n > 0:\n", " n -= 1\n", " print(n)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the example above, when the loop is encountered, `n` is `0`. The controlling expression `n > 0` is already false, so the loop body never executes."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here\u2019s another `while` loop involving a list, rather than a numeric comparison:"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["baz\n", "bar\n", "foo\n"]}], "source": ["a = ['foo', 'bar', 'baz']\n", "while a:\n", " print(a.pop(-1))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["When a list is evaluated in Boolean context, it is truthy if it has elements in it and falsy if it is empty. In this example, a is true as long as it has elements in it. Once all the items have been removed with the `.pop()` method and the list is empty, `a` is false, and the loop terminates."]}, {"cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["here\n"]}], "source": ["x = 5\n", "if x < 5:\n", " print('here')"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["x = 5\n", "while x < 5:\n", " print('here')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The Python `break` and `continue` Statements"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["x = 5\n", "\n", "if x == 5:\n", " print('x is 5')\n", "elif x > 6:\n", " print('x is greater than 6')\n", "else:\n", " print('else')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In each example you have seen so far, the entire body of the `while` loop is executed on each iteration. Python provides two keywords that terminate a loop iteration prematurely:\n", "\n", "- The Python **break** statement immediately terminates a loop entirely. Program execution proceeds to the first statement following the loop body.\n", "\n", "- The Python **continue** statement immediately terminates the current loop iteration. Execution jumps to the top of the loop, and the controlling expression is re-evaluated to determine whether the loop will execute again or terminate."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The distinction between `break` and `continue` is demonstrated in the following diagram:\n", "\n", "\"break"]}, {"cell_type": "markdown", "metadata": {}, "source": ["For example:"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["4\n", "3\n", "Loop ended.\n"]}], "source": ["n = 5\n", "while n > 0:\n", " n -= 1\n", " if n == 2:\n", " break\n", " print(n)\n", "print('Loop ended.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["When `n` becomes `2`, the `break` statement is executed. The loop is terminated completely, and program execution jumps to the `print()` statement on line 7."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The next block of code below, is identical except for a `continue` statement in place of the `break`:"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["4\n", "3\n", "1\n", "0\n", "Loop ended.\n"]}], "source": ["n = 5\n", "while n > 0:\n", " n -= 1\n", " if n == 2:\n", " continue\n", " print(n)\n", "print('Loop ended.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This time, when `n` is `2`, the `continue` statement causes termination of that iteration. Thus, `2` isn\u2019t printed. Execution returns to the top of the loop, the condition is re-evaluated, and it is still true. The loop resumes, terminating when `n` becomes `0`, as previously."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The `else` Clause"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python allows an optional `else` clause at the end of a `while` loop. This is a unique feature of Python, not found in most other programming languages. The syntax is shown below:\n", "\n", "```python\n", "while :\n", " \n", "else:\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `` specified in the `else` clause will be executed when the while loop terminates."]}, {"cell_type": "markdown", "metadata": {}, "source": ["About now, you may be thinking, \"How is that useful?\" You could accomplish the same thing by putting those statements immediately after the `while` loop, without the `else`:\n", "\n", "```python\n", "while :\n", " \n", "\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["What\u2019s the difference?\n", "\n", "In the latter case, without the `else` clause, `` will be executed after the `while` loop terminates, no matter what."]}, {"cell_type": "markdown", "metadata": {}, "source": ["When `` are placed in an `else` clause, they will be executed only if the loop terminates \"by exhaustion\"\u2014that is, if the loop iterates until the controlling condition becomes false. If the loop is exited by a `break` statement, the `else` clause won\u2019t be executed."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Consider the following example:"]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["4\n", "3\n", "2\n", "1\n", "0\n", "Loop done.\n"]}], "source": ["n = 5\n", "while n > 0:\n", " n -= 1\n", " print(n)\n", "else:\n", " print('Loop done.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this case, the loop repeated until the condition was exhausted: `n` became `0`, so `n > 0` became false. Because the loop lived out its natural life, so to speak, the `else` clause was executed. Now observe the difference here:"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["4\n", "3\n", "2\n"]}], "source": ["n = 5\n", "while n > 0:\n", " n -= 1\n", " print(n)\n", " if n == 2:\n", " break\n", "else:\n", " print('Loop done.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This loop is terminated prematurely with break, so the \u200delse clause isn\u2019t executed."]}, {"cell_type": "markdown", "metadata": {}, "source": ["It may seem as if the meaning of the word `else` doesn\u2019t quite fit the `while` loop as well as it does the if statement. Guido van Rossum, the creator of Python, has actually said that, if he had it to do over again, he\u2019d leave the while loop\u2019s `else` clause out of the language."]}, {"cell_type": "markdown", "metadata": {}, "source": ["One of the following interpretations might help to make it more intuitive:\n", "\n", "- Think of the header of the loop (`while n > 0`) as an `if` statement (`if n > 0`) that gets executed over and over, with the `else` clause finally being executed when the condition becomes false.\n", "\n", "- Think of `else` as though it were `nobreak`, in that the block that follows gets executed if there wasn\u2019t a break."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you don\u2019t find either of these interpretations helpful, then feel free to ignore them."]}, {"cell_type": "markdown", "metadata": {}, "source": ["When might an `else` clause on a while loop be useful? One common situation is if you are searching a list for a specific item. You can use `break` to exit the loop if the item is found, and the `else` clause can contain code that is meant to be executed if the item isn\u2019t found:"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["5\n", "4\n", "3\n"]}], "source": ["n = 5\n", "while n > 0:\n", " print(n)\n", " \n", " if n % 3 == 0:\n", " break\n", " n -= 1\n", "else:\n", " print('found')"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["while n > 0:\n", " print(n)\n", " n -= 1\n", "\n", "print('loop finished')"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Corge not found in list.\n"]}], "source": ["a = ['foo', 'bar', 'baz', 'qux']\n", "s = 'Corge'\n", "\n", "i = 0\n", "while i < len(a):\n", " if a[i] == s:\n", " # Processing for item found\n", " break\n", " i += 1\n", "else:\n", " # Processing for item not found\n", " print(s, 'not found in list.')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** The code shown above is useful to illustrate the concept, but you\u2019d actually be very unlikely to search a list that way.\n", "> \n", "> First of all, lists are usually processed with definite iteration, not a `while` loop. Definite iteration is covered in the next tutorial in this series.\n", "> \n", "> Secondly, Python provides built-in ways to search for an item in a list. You can use the `in` operator:\n", "> \n", "> ```python\n", ">>> if s in a:\n", "... print(s, 'found in list.')\n", "... else:\n", "... print(s, 'not found in list.')\n", "...\n", "corge not found in list.\n", "> ```\n", "> The `list.index()` method would also work. This method raises a `ValueError` exception if the item isn\u2019t found in the list, so you need to understand exception handling to use it. In Python, you use a `try` statement to handle an exception. An example is given below:\n", "> \n", "> ```python\n", ">>> try:\n", "... print(a.index('corge'))\n", "... except ValueError:\n", "... print(s, 'not found in list.')\n", "...\n", "corge not found in list.\n", "> ```\n", "> You will learn about exception handling later in this series."]}, {"cell_type": "markdown", "metadata": {}, "source": ["An `else` clause with a `while` loop is a bit of an oddity, not often seen. But don\u2019t shy away from it if you find a situation in which you feel it adds clarity to your code!"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Infinite Loops"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Suppose you write a `while` loop that theoretically never ends. Sounds weird, right?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Consider this example:\n", "\n", "```python\n", ">>> while True:\n", "... print('foo')\n", "...\n", "foo\n", "foo\n", "foo\n", " .\n", " .\n", " .\n", "foo\n", "foo\n", "foo\n", "KeyboardInterrupt\n", "Traceback (most recent call last):\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This code was terminated by `Ctrl+C`, which generates an interrupt from the keyboard. Otherwise, it would have gone on unendingly. Many foo output lines have been removed and replaced by the vertical ellipsis in the output shown."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Clearly, `True` will never be false, or we\u2019re all in very big trouble. Thus, `while True`: initiates an infinite loop that will theoretically run forever."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Maybe that doesn\u2019t sound like something you\u2019d want to do, but this pattern is actually quite common. For example, you might write code for a service that starts up and runs forever accepting service requests. \u201cForever\u201d in this context means until you shut it down, or until the heat death of the universe, whichever comes first."]}, {"cell_type": "markdown", "metadata": {}, "source": ["More prosaically, remember that loops can be broken out of with the `break` statement. It may be more straightforward to terminate a loop based on conditions recognized within the loop body, rather than on a condition evaluated at the top."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can also specify multiple break statements in a loop:\n", "```python\n", "while True:\n", " if : # One condition for loop termination\n", " break\n", " ...\n", " if : # Another termination condition\n", " break\n", " ...\n", " if : # Yet another\n", " break\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In cases like this, where there are multiple reasons to end the loop, it is often cleaner to `break` out from several different locations, rather than try to specify all the termination conditions in the loop header."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Infinite loops can be very useful. Just remember that you must ensure the loop gets broken out of at some point, so it doesn\u2019t truly become infinite."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Nested `while` Loops"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In general, Python control structures can be nested within one another. For example, `if/elif/else` conditional statements can be nested:"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["son\n"]}], "source": ["age = 12\n", "gender = 'M'\n", "\n", "if age < 18:\n", " if gender == 'M':\n", " print('son')\n", " else:\n", " print('daughter')\n", "elif age >= 18 and age < 65:\n", " if gender == 'M':\n", " print('father')\n", " else:\n", " print('mother')\n", "else:\n", " if gender == 'M':\n", " print('grandfather')\n", " else:\n", " print('grandmother')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Similarly, a `while` loop can be contained within another `while` loop, as shown here:"]}, {"cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "> baz\n", "> qux\n", "bar\n", "> baz\n", "> qux\n"]}], "source": ["a = ['foo', 'bar']\n", "while len(a):\n", " print(a[0])\n", " del a[0]\n", " \n", " b = ['baz', 'qux']\n", " while len(b):\n", " print('>', b[0])\n", " del b[0]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A `break` or `continue` statement found within nested loops applies to the nearest enclosing loop:\n", "\n", "```python\n", "while :\n", " statement\n", " statement\n", "\n", " while :\n", " statement\n", " statement\n", " break # Applies to while : loop\n", "\n", " break # Applies to while : loop\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Additionally, while loops can be nested inside `if/elif/else` statements, and vice versa:\n", "\n", "```python\n", "if :\n", " statement\n", " while :\n", " statement\n", " statement\n", "else:\n", " while :\n", " statement\n", " statement\n", " statement\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["```python\n", "while :\n", " if :\n", " statement\n", " elif :\n", " statement\n", " else:\n", " statement\n", "\n", " if :\n", " statement\n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In fact, all the Python control structures can be intermingled with one another to whatever extent you need. That is as it should be. Imagine how frustrating it would be if there were unexpected restrictions like \u201cA `while` loop can\u2019t be contained within an `if` statement\u201d or \u201c`while` loops can only be nested inside one another at most four deep.\u201d You\u2019d have a very difficult time remembering them all."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## One-Line `while` Loops"]}, {"cell_type": "markdown", "metadata": {}, "source": ["As with an `if` statement, a `while` loop can be specified on one line. If there are multiple statements in the block that makes up the loop body, they can be separated by semicolons (`;`):"]}, {"cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["4\n", "3\n", "2\n", "1\n", "0\n"]}], "source": ["n = 5\n", "while n > 0: n -= 1; print(n)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This only works with simple statements though. You can\u2019t combine two compound statements into one line. Thus, you can specify a `while` loop all on one line as above, and you write an `if` statement on one line:"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n"]}], "source": ["if True: print('foo')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["But you can\u2019t do this:"]}, {"cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [{"ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": ["\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m while n > 0: n -= 1; if True: print('foo')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"]}], "source": ["while n > 0: n -= 1; if True: print('foo')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Remember that [PEP 8](https://www.python.org/dev/peps/pep-0008/#other-recommendations) discourages multiple statements on one line. So you probably shouldn\u2019t be doing any of this very often anyhow."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this tutorial, you learned about **indefinite iteration** using the Python while loop. You\u2019re now able to:\n", "\n", "- Construct basic and complex `while` loops\n", "- Interrupt loop execution with `break` and `continue`\n", "- Use the `else` clause with a while loop\n", "- Deal with infinite loops"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You should now have a good grasp of how to execute a piece of code repetitively."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The next section covers **definite iteration** with for loops\u2014recurrent execution where the number of repetitions is specified explicitly."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git "a/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" "b/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" index 8e3bf96..05c5115 100755 --- "a/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" +++ "b/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" @@ -1,1671 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Python \"for\" Loops (Definite Iteration)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This tutorial will show you how to perform **definite iteration** with a Python for loop." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the previous tutorial in this introductory series, you learned the following:\n", - "\n", - "- Repetitive execution of the same block of code over and over is referred to as iteration.\n", - "- There are two types of **iteration**:\n", - " - **Definite** iteration, in which the number of repetitions is specified explicitly in advance\n", - " - **Indefinite** iteration, in which the code block executes until some condition is met\n", - "\n", - "- In Python, indefinite iteration is performed with a `while` loop." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here’s what you’ll cover in this tutorial:\n", - "\n", - "- You’ll start with a comparison of some different paradigms used by programming languages to implement definite iteration.\n", - "- Then you will learn about **iterables** and **iterators**, two concepts that form the basis of definite iteration in Python.\n", - "- Finally, you’ll tie it all together and learn about Python’s for loops." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Then you will learn about iterables and iterators, two concepts that form the basis of definite iteration in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, you’ll tie it all together and learn about Python’s for loops." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## A Survey of Definite Iteration in Programming" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Definite iteration loops are frequently referred to as ‍`for` loops because for is the keyword that is used to introduce them in nearly all programming languages, including Python.\n", - "\n", - "Historically, programming languages have offered a few assorted flavors of for loop. These are briefly described in the following sections." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Numeric Range Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The most basic for loop is a simple numeric range statement with start and end values. The exact format varies depending on the language but typically looks something like this:\n", - "\n", - "‍‍‍```\n", - "for i = 1 to 10\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here, the body of the loop is executed ten times. The variable i assumes the value `1` on the first iteration, `2` on the second, and so on. This sort of `for` loop is used in the languages BASIC, Algol, and Pascal." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Three-Expression Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Another form of for loop popularized by the C programming language contains three parts:\n", - "\n", - "- An initialization\n", - "- An expression specifying an ending condition\n", - "- An action to be performed at the end of each iteration.\n", - "\n", - "This type of loop has the following form:\n", - "```c\n", - "for (i = 1; i <= 10; i++)\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Technical Note:** In the C programming language, `i++` increments the variable `i`. It is roughly equivalent to `i += 1` in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This loop is interpreted as follows:\n", - "\n", - "- Initialize `i` to `1`.\n", - "- Continue looping as long as `i <= 10`.\n", - "- Increment `i` by `1` after each loop iteration." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Three-expression for loops are popular because the expressions specified for the three parts can be nearly anything, so this has quite a bit more flexibility than the simpler numeric range form shown above. These `for` loops are also featured in the C++, Java, PHP, and Perl languages." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Collection-Based or Iterator-Based Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This type of loop iterates over a collection of objects, rather than specifying numeric values or conditions:\n", - "\n", - "```python\n", - "for i in \n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Each time through the loop, the variable `i` takes on the value of the next object in ``. This type of for loop is arguably the most generalized and abstract. Perl and PHP also support this type of loop, but it is introduced by the keyword `foreach` instead of `for`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Further Reading:** See the [For loop](https://en.wikipedia.org/wiki/For_loop) Wikipedia page for an in-depth look at the implementation of definite iteration across programming languages." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The Python for Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Of the loop types listed above, Python only implements the last: collection-based iteration. At first blush, that may seem like a raw deal, but rest assured that Python’s implementation of definite iteration is so versatile that you won’t end up feeling cheated!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Shortly, you’ll dig into the guts of Python’s `for` loop in detail. But for now, let’s start with a quick prototype and example, just to get acquainted." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python’s for loop looks like this:\n", - "```python\n", - "for in :\n", - " \n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`` is a collection of objects—for example, a list or tuple. The `` in the loop body are denoted by indentation, as with all Python control structures, and are executed once for each item in ``. The loop variable `` takes on the value of the next element in `` each time through the loop." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a representative example:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "bar\n", - "baz\n" - ] - } - ], - "source": [ - "a = ['foo', 'bar', 'baz']\n", - "for i in a:\n", - " print(i)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, `` is the list `a`, and `` is the variable `i`. Each time through the loop, `i` takes on a successive item in `a`, so `print()` displays the values `'foo'`, `'bar'`, and `'baz'`, respectively. A `for` loop like this is the Pythonic way to process the items in an iterable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But what exactly is an iterable? Before examining `for` loops further, it will be beneficial to delve more deeply into what iterables are in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Iterables\n", - "In Python, **iterable** means an object can be used in iteration. The term is used as:\n", - "\n", - "- **An adjective:** An object may be described as iterable.\n", - "- **A noun:** An object may be characterized as an iterable." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If an object is iterable, it can be passed to the built-in Python function `iter()`, which returns something called an **iterator**. Yes, the terminology gets a bit repetitive. Hang in there. It all works out in the end." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Each of the objects in the following example is an iterable and returns some type of iterator when passed to `iter()`:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iter('foobar') # String" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iter(['foo', 'bar', 'baz']) # List" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iter(('foo', 'bar', 'baz')) # Tuple" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iter({'foo', 'bar', 'baz'}) # Set" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iter({'foo': 1, 'bar': 2, 'baz': 3}) # Dict" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "These object types, on the other hand, aren’t iterable:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'int' object is not iterable", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m42\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Integer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable" - ] - } - ], - "source": [ - "iter(42) # Integer " - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'float' object is not iterable", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Float\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'float' object is not iterable" - ] - } - ], - "source": [ - "iter(3.1) # Float" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'builtin_function_or_method' object is not iterable", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Built-in function\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: 'builtin_function_or_method' object is not iterable" - ] - } - ], - "source": [ - "iter(len) # Built-in function" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All the data types you have encountered so far that are collection or container types are iterable. These include the string, list, tuple, dict, set, and frozenset types." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But these are by no means the only types that you can iterate over. Many objects that are built into Python or defined in modules are designed to be iterable. For example, open files in Python are iterable. As you will see soon in the section on file I/O, iterating over an open file object reads data from the file." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In fact, almost any object in Python can be made iterable. Even user-defined objects can be designed in such a way that they can be iterated over. (You will find out how that is done in the upcoming article on object-oriented programming.)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Iterators" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Okay, now you know what it means for an object to be iterable, and you know how to use `iter()` to obtain an iterator from it. Once you’ve got an iterator, what can you do with it?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "An iterator is essentially a value producer that yields successive values from its associated iterable object. The built-in function `next()` is used to obtain the next value from in iterator." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is an example using the same list as above:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "itr = iter(a)\n", - "itr" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'baz'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, `a` is an iterable list and `itr` is the associated iterator, obtained with `iter()`. Each `next(itr)` call obtains the next value from `itr`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice how an iterator retains its state internally. It knows which values have been obtained already, so when you call `next()`, it knows what value to return next." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What happens when the iterator runs out of values? Let’s make one more `next()` call on the iterator above:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "ename": "StopIteration", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mStopIteration\u001b[0m: " - ] - } - ], - "source": [ - "next(itr)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If all the values from an iterator have been returned already, a subsequent `next()` call raises a `StopIteration` exception. Any further attempts to obtain values from the iterator will fail." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can only obtain values from an iterator in one direction. You can’t go backward. There is no `prev()` function. But you can define two independent iterators on the same iterable object:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz']" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "itr1 = iter(a)\n", - "itr2 = iter(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr1)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'bar'" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr1)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'baz'" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr1)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'foo'" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "next(itr2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Even when iterator `itr1` is already at the end of the list, `itr2` is still at the beginning. Each iterator maintains its own internal state, independent of the other." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you want to grab all the values from an iterator at once, you can use the built-in `list()` function. Among other possible uses, `list()` takes an iterator as its argument, and returns a list consisting of all the values that the iterator yielded:" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['foo', 'bar', 'baz']" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = ['foo', 'bar', 'baz']\n", - "itr = iter(a)\n", - "list(itr)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly, the built-in `tuple()` and `set()` functions return a tuple and a set, respectively, from all the values an iterator yields:" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [], - "source": [ - "a = ['foo', 'bar', 'baz']" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "('foo', 'bar', 'baz')" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "itr = iter(a)\n", - "tuple(itr)" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bar', 'baz', 'foo'}" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "itr = iter(a)\n", - "set(itr)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It isn’t necessarily advised to make a habit of this. Part of the elegance of iterators is that they are “lazy.” That means that when you create an iterator, it doesn’t generate all the items it can yield just then. It waits until you ask for them with `next()`. Items are not created until they are requested." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When you use `list()`, `tuple()`, or the like, you are forcing the iterator to generate all its values at once, so they can all be returned. If the total number of objects the iterator returns is very large, that may take a long time." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Further Reading:** It is possible to create an iterator in Python that returns an endless series of objects using generator functions and `itertools`. If you try to grab all the values at once from an endless iterator, the program will hang. Generators and `itertools` will be covered later in advanced section." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The Guts of the Python for Loop" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You now have been introduced to all the concepts you need to fully understand how Python’s for loop works. Before proceeding, let’s review the relevant terms:\n", - "\n", - "|**Term**|**Meaning** |\n", - "|:--|:--|\n", - "|**Iteration**| The process of looping through the objects or items in a collection |\n", - "|**Iterable**| An object (or the adjective used to describe an object) that can be iterated over |\n", - "|**Iterator**| The object that produces successive items or values from its associated iterable |\n", - "|**`iter()`**|\tThe built-in function used to obtain an iterator from an iterable |" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, consider again the simple `for` loop presented at the start of this tutorial:" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "bar\n", - "baz\n" - ] - } - ], - "source": [ - "a = ['foo', 'bar', 'baz']\n", - "for i in a:\n", - " print(i)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This loop can be described entirely in terms of the concepts you have just learned about. To carry out the iteration this for loop describes, Python does the following:\n", - "\n", - "- Calls `iter()` to obtain an iterator for `a`\n", - "- Calls `next()` repeatedly to obtain each item from the iterator in turn\n", - "- Terminates the loop when `next()` raises the `StopIteration` exception" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The loop body is executed once for each item `next()` returns, with loop variable `i` set to the given item for each iteration." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This sequence of events is summarized in the following diagram:\n", - "\n", - "\"for" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Perhaps this seems like a lot of unnecessary monkey business, but the benefit is substantial. Python treats looping over all iterables in exactly this way, and in Python, iterables and iterators abound:\n", - "\n", - "- Many built-in and library objects are iterable.\n", - "- There is a Standard Library module called `itertools` containing many functions that return iterables.\n", - "- User-defined objects created with Python’s object-oriented capability can be made to be iterable.\n", - "- Python features a construct called a generator that allows you to create your own iterator in a simple, straightforward way." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You will discover more about all the above throughout this section. They can all be the target of a `for` loop, and the syntax is the same across the board. It’s elegant in its simplicity and eminently versatile." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Iterating Through a Dictionary" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You saw earlier that an iterator can be obtained from a dictionary with `iter()`, so you know dictionaries must be iterable. What happens when you loop through a dictionary? Let’s see:" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "bar\n", - "baz\n" - ] - } - ], - "source": [ - "d = {'foo': 1, 'bar': 2, 'baz': 3}\n", - "for k in d:\n", - " print(k)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see, when a `for` loop iterates through a dictionary, the loop variable is assigned to the dictionary’s keys." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To access the dictionary values within the loop, you can make a dictionary reference using the key as usual:" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "2\n", - "3\n" - ] - } - ], - "source": [ - "for k in d:\n", - " print(d[k])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also iterate through a dictionary’s values directly by using `.values()`:" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "2\n", - "3\n" - ] - } - ], - "source": [ - "for v in d.values():\n", - " print(v)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In fact, you can iterate through both the keys and values of a dictionary simultaneously. That is because the loop variable of a `for` loop isn’t limited to just a single variable. It can also be a tuple, in which case the assignments are made from the items in the iterable using packing and unpacking, just as with an assignment statement:" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 2\n" - ] - } - ], - "source": [ - "i, j = (1, 2)\n", - "print(i, j)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 2\n", - "3 4\n", - "5 6\n" - ] - } - ], - "source": [ - "for i, j in [(1, 2), (3, 4), (5, 6)]:\n", - " print(i, j)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The Pythonic way to iterate through a dictionary accessing both the keys and values looks like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "k = foo , v = 1\n", - "k = bar , v = 2\n", - "k = baz , v = 3\n" - ] - } - ], - "source": [ - "d = {'foo': 1, 'bar': 2, 'baz': 3}\n", - "for k, v in d.items():\n", - " print('k =', k, ', v =', v)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Note:** Behind the scene for dictionary `.keys`, `.values`, and `.items` will be covered after the object oriented programming (OOP) series and after you get to know how methods work in OOP." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The `range()` Function" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the first section of this tutorial, you saw a type of for loop called a [numeric range loop](#numeric-range-loop), in which starting and ending numeric values are specified. Although this form of for loop isn’t directly built into Python, it is easily arrived at." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, if you wanted to iterate through the values from `0` to `4`, you could simply do this:" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1\n", - "2\n", - "3\n", - "4\n" - ] - } - ], - "source": [ - "for n in (0, 1, 2, 3, 4):\n", - " print(n)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This solution isn’t too bad when there are just a few numbers. But if the number range were much larger, it would become tedious pretty quickly." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Happily, Python provides a better option—the built-in `range()` function, which returns an iterable that yields a sequence of integers." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`range()` returns an iterable that yields integers starting with `0`, up to but not including ``:" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "range(0, 5)" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x = range(5)\n", - "x" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "range" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that `range()` returns an object of class `range`, not a list or tuple of the values. Because a `range` object is an iterable, you can obtain the values by iterating over them with a `for` loop:" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1\n", - "2\n", - "3\n", - "4\n" - ] - } - ], - "source": [ - "for n in x:\n", - " print(n)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You could also snag all the values at once with `list()` or `tuple()`. In a REPL session, that can be a convenient way to quickly display what the values are:" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0, 1, 2, 3, 4]" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(x)" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0, 1, 2, 3, 4)" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tuple(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "However, when `range()` is used in code that is part of a larger application, it is typically considered poor practice to use `list()` or `tuple()` in this way. Like iterators, `range` objects are lazy—the values in the specified range are not generated until they are requested. Using `list()` or `tuple()` on a range object forces all the values to be returned at once. This is rarely necessary, and if the list is long, it can waste time and memory." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`range(, , )` returns an iterable that yields integers starting with ``, up to but not including ``. If specified, `` indicates an amount to skip between values (analogous to the stride value used for string and list slicing):" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[5, 8, 11, 14, 17]" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(range(5, 20, 3))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If `` is omitted, it defaults to `1`:" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[5, 6, 7, 8, 9]" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(range(5, 10, 1))" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[5, 6, 7, 8, 9]" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(range(5, 10))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "All the parameters specified to `range()` must be integers, but any of them can be negative. Naturally, if `` is greater than ``, `` must be negative (if you want any results):" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(range(-5, 5))" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(range(5, -5))" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(range(5, -5, -1))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Technical Note:** Strictly speaking, `range()` isn’t exactly a built-in function. It is implemented as a callable class that creates an immutable sequence type. But for practical purposes, it behaves like a built-in function. This will be covered later after covering OOP." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Altering `for` Loop Behavior" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You saw in the previous tutorial in the previous sections how execution of a `while` loop can be interrupted with `break` and `continue` statements and modified with an `else` clause. These capabilities are available with the `for` loop as well." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The break and continue Statements" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`break` and `continue` work the same way with `for` loops as with `while` loops. `break` terminates the loop completely and proceeds to the first statement following the loop:" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n" - ] - } - ], - "source": [ - "for i in ['foo', 'bar', 'baz', 'qux']:\n", - " if 'b' in i:\n", - " break\n", - " print(i)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`continue` terminates the current iteration and proceeds to the next iteration:" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "qux\n" - ] - } - ], - "source": [ - "for i in ['foo', 'bar', 'baz', 'qux']:\n", - " if 'b' in i:\n", - " continue\n", - " print(i)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The `else` Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A `for` loop can have an `else` clause as well. The interpretation is analogous to that of a `while` loop. The `else` clause will be executed if the loop terminates through exhaustion of the iterable:" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n", - "bar\n", - "baz\n", - "qux\n", - "Done.\n" - ] - } - ], - "source": [ - "for i in ['foo', 'bar', 'baz', 'qux']:\n", - " print(i)\n", - "else:\n", - " print('Done.') # Will execute" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `else` clause won’t be executed if the list is broken out of with a `break` statement:" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo\n" - ] - } - ], - "source": [ - "for i in ['foo', 'bar', 'baz', 'qux']:\n", - " if i == 'bar':\n", - " break\n", - " print(i)\n", - "else:\n", - " print('Done.') # Will not execute" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "This section presented the `for` loop, the workhorse of **definite iteration** in Python." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You also learned about the inner workings of **iterables** and **iterators**, two important object types that underlie definite iteration, but also figure prominently in a wide variety of other Python code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the next two sections in this introductory series, you will shift gears a little and explore how Python programs can interact with the user via **input** from the keyboard and **output** to the console." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Python \"for\" Loops (Definite Iteration)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [A Survey of Definite Iteration in Programming](#a_survey_of_definite_iteration_in_programming)\n * [Numeric Range Loop](#numeric_range_loop)\n * [Three-Expression Loop](#three-expression_loop)\n * [Collection-Based or Iterator-Based Loop](#collection-based_or_iterator-based_loop)\n * [The Python for Loop](#the_python_for_loop)\n * [Iterables](#iterables)\n * [Iterators](#iterators)\n* [The Guts of the Python for Loop](#the_guts_of_the_python_for_loop)\n* [Iterating Through a Dictionary](#iterating_through_a_dictionary)\n* [The `range()` Function](#the_`range()`_function)\n* [Altering `for` Loop Behavior](#altering_`for`_loop_behavior)\n * [The break and continue Statements](#the_break_and_continue_statements)\n * [The `else` Clause](#the_`else`_clause)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This tutorial will show you how to perform **definite iteration** with a Python for loop."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the previous tutorial in this introductory series, you learned the following:\n", "\n", "- Repetitive execution of the same block of code over and over is referred to as iteration.\n", "- There are two types of **iteration**:\n", " - **Definite** iteration, in which the number of repetitions is specified explicitly in advance\n", " - **Indefinite** iteration, in which the code block executes until some condition is met\n", "\n", "- In Python, indefinite iteration is performed with a `while` loop."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here\u2019s what you\u2019ll cover in this tutorial:\n", "\n", "- You\u2019ll start with a comparison of some different paradigms used by programming languages to implement definite iteration.\n", "- Then you will learn about **iterables** and **iterators**, two concepts that form the basis of definite iteration in Python.\n", "- Finally, you\u2019ll tie it all together and learn about Python\u2019s for loops."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Then you will learn about iterables and iterators, two concepts that form the basis of definite iteration in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Finally, you\u2019ll tie it all together and learn about Python\u2019s for loops."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## A Survey of Definite Iteration in Programming"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Definite iteration loops are frequently referred to as \u200d`for` loops because for is the keyword that is used to introduce them in nearly all programming languages, including Python.\n", "\n", "Historically, programming languages have offered a few assorted flavors of for loop. These are briefly described in the following sections."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Numeric Range Loop"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The most basic for loop is a simple numeric range statement with start and end values. The exact format varies depending on the language but typically looks something like this:\n", "\n", "\u200d\u200d\u200d```\n", "for i = 1 to 10\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here, the body of the loop is executed ten times. The variable i assumes the value `1` on the first iteration, `2` on the second, and so on. This sort of `for` loop is used in the languages BASIC, Algol, and Pascal."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Three-Expression Loop"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Another form of for loop popularized by the C programming language contains three parts:\n", "\n", "- An initialization\n", "- An expression specifying an ending condition\n", "- An action to be performed at the end of each iteration.\n", "\n", "This type of loop has the following form:\n", "```c\n", "for (i = 1; i <= 10; i++)\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Technical Note:** In the C programming language, `i++` increments the variable `i`. It is roughly equivalent to `i += 1` in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["This loop is interpreted as follows:\n", "\n", "- Initialize `i` to `1`.\n", "- Continue looping as long as `i <= 10`.\n", "- Increment `i` by `1` after each loop iteration."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Three-expression for loops are popular because the expressions specified for the three parts can be nearly anything, so this has quite a bit more flexibility than the simpler numeric range form shown above. These `for` loops are also featured in the C++, Java, PHP, and Perl languages."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Collection-Based or Iterator-Based Loop"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This type of loop iterates over a collection of objects, rather than specifying numeric values or conditions:\n", "\n", "```python\n", "for i in \n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Each time through the loop, the variable `i` takes on the value of the next object in ``. This type of for loop is arguably the most generalized and abstract. Perl and PHP also support this type of loop, but it is introduced by the keyword `foreach` instead of `for`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Further Reading:** See the [For loop](https://en.wikipedia.org/wiki/For_loop) Wikipedia page for an in-depth look at the implementation of definite iteration across programming languages."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### The Python for Loop"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Of the loop types listed above, Python only implements the last: collection-based iteration. At first blush, that may seem like a raw deal, but rest assured that Python\u2019s implementation of definite iteration is so versatile that you won\u2019t end up feeling cheated!"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Shortly, you\u2019ll dig into the guts of Python\u2019s `for` loop in detail. But for now, let\u2019s start with a quick prototype and example, just to get acquainted."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Python\u2019s for loop looks like this:\n", "```python\n", "for in :\n", " \n", "```"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`` is a collection of objects\u2014for example, a list or tuple. The `` in the loop body are denoted by indentation, as with all Python control structures, and are executed once for each item in ``. The loop variable `` takes on the value of the next element in `` each time through the loop."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here is a representative example:"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "bar\n", "baz\n"]}], "source": ["a = ['foo', 'bar', 'baz']\n", "for i in a:\n", " print(i)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this example, `` is the list `a`, and `` is the variable `i`. Each time through the loop, `i` takes on a successive item in `a`, so `print()` displays the values `'foo'`, `'bar'`, and `'baz'`, respectively. A `for` loop like this is the Pythonic way to process the items in an iterable."]}, {"cell_type": "markdown", "metadata": {}, "source": ["But what exactly is an iterable? Before examining `for` loops further, it will be beneficial to delve more deeply into what iterables are in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Iterables\n", "In Python, **iterable** means an object can be used in iteration. The term is used as:\n", "\n", "- **An adjective:** An object may be described as iterable.\n", "- **A noun:** An object may be characterized as an iterable."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If an object is iterable, it can be passed to the built-in Python function `iter()`, which returns something called an **iterator**. Yes, the terminology gets a bit repetitive. Hang in there. It all works out in the end."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Each of the objects in the following example is an iterable and returns some type of iterator when passed to `iter()`:"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["iter('foobar') # String"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["iter(['foo', 'bar', 'baz']) # List"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["iter(('foo', 'bar', 'baz')) # Tuple"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["iter({'foo', 'bar', 'baz'}) # Set"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["iter({'foo': 1, 'bar': 2, 'baz': 3}) # Dict"]}, {"cell_type": "markdown", "metadata": {}, "source": ["These object types, on the other hand, aren\u2019t iterable:"]}, {"cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'int' object is not iterable", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_76590/2887938158.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m42\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Integer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable"]}], "source": ["iter(42) # Integer "]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'float' object is not iterable", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Float\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'float' object is not iterable"]}], "source": ["iter(3.1) # Float"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "'builtin_function_or_method' object is not iterable", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Built-in function\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'builtin_function_or_method' object is not iterable"]}], "source": ["iter(len) # Built-in function"]}, {"cell_type": "markdown", "metadata": {}, "source": ["All the data types you have encountered so far that are collection or container types are iterable. These include the string, list, tuple, dict, set, and frozenset types."]}, {"cell_type": "markdown", "metadata": {}, "source": ["But these are by no means the only types that you can iterate over. Many objects that are built into Python or defined in modules are designed to be iterable. For example, open files in Python are iterable. As you will see soon in the section on file I/O, iterating over an open file object reads data from the file."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In fact, almost any object in Python can be made iterable. Even user-defined objects can be designed in such a way that they can be iterated over. (You will find out how that is done in the upcoming article on object-oriented programming.)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Iterators"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Okay, now you know what it means for an object to be iterable, and you know how to use `iter()` to obtain an iterator from it. Once you\u2019ve got an iterator, what can you do with it?"]}, {"cell_type": "markdown", "metadata": {}, "source": ["An iterator is essentially a value producer that yields successive values from its associated iterable object. The built-in function `next()` is used to obtain the next value from in iterator."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Here is an example using the same list as above:"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz']"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["itr = iter(a)\n", "itr"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr)"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr)"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["'baz'"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this example, `a` is an iterable list and `itr` is the associated iterator, obtained with `iter()`. Each `next(itr)` call obtains the next value from `itr`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Notice how an iterator retains its state internally. It knows which values have been obtained already, so when you call `next()`, it knows what value to return next."]}, {"cell_type": "markdown", "metadata": {}, "source": ["What happens when the iterator runs out of values? Let\u2019s make one more `next()` call on the iterator above:"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"ename": "StopIteration", "evalue": "", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mStopIteration\u001b[0m: "]}], "source": ["next(itr)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If all the values from an iterator have been returned already, a subsequent `next()` call raises a `StopIteration` exception. Any further attempts to obtain values from the iterator will fail."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can only obtain values from an iterator in one direction. You can\u2019t go backward. There is no `prev()` function. But you can define two independent iterators on the same iterable object:"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz']"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["a"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": ["itr1 = iter(a)\n", "itr2 = iter(a)"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 25, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr1)"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"data": {"text/plain": ["'bar'"]}, "execution_count": 26, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr1)"]}, {"cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [{"data": {"text/plain": ["'baz'"]}, "execution_count": 27, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr1)"]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [{"data": {"text/plain": ["'foo'"]}, "execution_count": 28, "metadata": {}, "output_type": "execute_result"}], "source": ["next(itr2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Even when iterator `itr1` is already at the end of the list, `itr2` is still at the beginning. Each iterator maintains its own internal state, independent of the other."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you want to grab all the values from an iterator at once, you can use the built-in `list()` function. Among other possible uses, `list()` takes an iterator as its argument, and returns a list consisting of all the values that the iterator yielded:"]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"data": {"text/plain": ["['foo', 'bar', 'baz']"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["a = ['foo', 'bar', 'baz']\n", "itr = iter(a)\n", "list(itr)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Similarly, the built-in `tuple()` and `set()` functions return a tuple and a set, respectively, from all the values an iterator yields:"]}, {"cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": ["a = ['foo', 'bar', 'baz']"]}, {"cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [{"data": {"text/plain": ["('foo', 'bar', 'baz')"]}, "execution_count": 52, "metadata": {}, "output_type": "execute_result"}], "source": ["itr = iter(a)\n", "tuple(itr)"]}, {"cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [{"data": {"text/plain": ["{'bar', 'baz', 'foo'}"]}, "execution_count": 53, "metadata": {}, "output_type": "execute_result"}], "source": ["itr = iter(a)\n", "set(itr)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It isn\u2019t necessarily advised to make a habit of this. Part of the elegance of iterators is that they are \u201clazy.\u201d That means that when you create an iterator, it doesn\u2019t generate all the items it can yield just then. It waits until you ask for them with `next()`. Items are not created until they are requested."]}, {"cell_type": "markdown", "metadata": {}, "source": ["When you use `list()`, `tuple()`, or the like, you are forcing the iterator to generate all its values at once, so they can all be returned. If the total number of objects the iterator returns is very large, that may take a long time."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Further Reading:** It is possible to create an iterator in Python that returns an endless series of objects using generator functions and `itertools`. If you try to grab all the values at once from an endless iterator, the program will hang. Generators and `itertools` will be covered later in advanced section."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The Guts of the Python for Loop"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You now have been introduced to all the concepts you need to fully understand how Python\u2019s for loop works. Before proceeding, let\u2019s review the relevant terms:\n", "\n", "|**Term**|**Meaning** |\n", "|:--|:--|\n", "|**Iteration**| The process of looping through the objects or items in a collection |\n", "|**Iterable**| An object (or the adjective used to describe an object) that can be iterated over |\n", "|**Iterator**| The object that produces successive items or values from its associated iterable |\n", "|**`iter()`**|\tThe built-in function used to obtain an iterator from an iterable |"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Now, consider again the simple `for` loop presented at the start of this tutorial:"]}, {"cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "bar\n", "baz\n"]}], "source": ["a = ['foo', 'bar', 'baz']\n", "for i in a:\n", " print(i)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This loop can be described entirely in terms of the concepts you have just learned about. To carry out the iteration this for loop describes, Python does the following:\n", "\n", "- Calls `iter()` to obtain an iterator for `a`\n", "- Calls `next()` repeatedly to obtain each item from the iterator in turn\n", "- Terminates the loop when `next()` raises the `StopIteration` exception"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The loop body is executed once for each item `next()` returns, with loop variable `i` set to the given item for each iteration."]}, {"cell_type": "markdown", "metadata": {}, "source": ["This sequence of events is summarized in the following diagram:\n", "\n", "\"for"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Perhaps this seems like a lot of unnecessary monkey business, but the benefit is substantial. Python treats looping over all iterables in exactly this way, and in Python, iterables and iterators abound:\n", "\n", "- Many built-in and library objects are iterable.\n", "- There is a Standard Library module called `itertools` containing many functions that return iterables.\n", "- User-defined objects created with Python\u2019s object-oriented capability can be made to be iterable.\n", "- Python features a construct called a generator that allows you to create your own iterator in a simple, straightforward way."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You will discover more about all the above throughout this section. They can all be the target of a `for` loop, and the syntax is the same across the board. It\u2019s elegant in its simplicity and eminently versatile."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Iterating Through a Dictionary"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You saw earlier that an iterator can be obtained from a dictionary with `iter()`, so you know dictionaries must be iterable. What happens when you loop through a dictionary? Let\u2019s see:"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": ["d = {\n", " 'one': 1,\n", " 'two': 2,\n", " 'three': 3,\n", "}"]}, {"cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "bar\n", "baz\n"]}], "source": ["d = {'foo': 1, 'bar': 2, 'baz': 3}\n", "for k in d:\n", " print(k)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["As you can see, when a `for` loop iterates through a dictionary, the loop variable is assigned to the dictionary\u2019s keys."]}, {"cell_type": "markdown", "metadata": {}, "source": ["To access the dictionary values within the loop, you can make a dictionary reference using the key as usual:"]}, {"cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1\n", "2\n", "3\n"]}], "source": ["for k in d:\n", " print(d[k])"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can also iterate through a dictionary\u2019s values directly by using `.values()`:"]}, {"cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1\n", "2\n", "3\n"]}], "source": ["for v in d.values():\n", " print(v)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In fact, you can iterate through both the keys and values of a dictionary simultaneously. That is because the loop variable of a `for` loop isn\u2019t limited to just a single variable. It can also be a tuple, in which case the assignments are made from the items in the iterable using packing and unpacking, just as with an assignment statement:"]}, {"cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1 2\n"]}], "source": ["i, j = (1, 2)\n", "print(i, j)"]}, {"cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["1 2\n", "3 4\n", "5 6\n"]}], "source": ["for i, j in [(1, 2), (3, 4), (5, 6)]:\n", " print(i, j)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The Pythonic way to iterate through a dictionary accessing both the keys and values looks like this:"]}, {"cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["k = foo , v = 1\n", "k = bar , v = 2\n", "k = baz , v = 3\n"]}], "source": ["d = {'foo': 1, 'bar': 2, 'baz': 3}\n", "for k, v in d.items():\n", " print('k =', k, ', v =', v)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Note:** Behind the scene for dictionary `.keys`, `.values`, and `.items` will be covered after the object oriented programming (OOP) series and after you get to know how methods work in OOP."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## The `range()` Function"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the first section of this tutorial, you saw a type of for loop called a [numeric range loop](#numeric-range-loop), in which starting and ending numeric values are specified. Although this form of for loop isn\u2019t directly built into Python, it is easily arrived at."]}, {"cell_type": "markdown", "metadata": {}, "source": ["For example, if you wanted to iterate through the values from `0` to `4`, you could simply do this:"]}, {"cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["0\n", "1\n", "2\n", "3\n", "4\n"]}], "source": ["for n in (0, 1, 2, 3, 4):\n", " print(n)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This solution isn\u2019t too bad when there are just a few numbers. But if the number range were much larger, it would become tedious pretty quickly."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Happily, Python provides a better option\u2014the built-in `range()` function, which returns an iterable that yields a sequence of integers."]}, {"cell_type": "markdown", "metadata": {}, "source": ["`range()` returns an iterable that yields integers starting with `0`, up to but not including ``:"]}, {"cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [{"data": {"text/plain": ["range(0, 5)"]}, "execution_count": 42, "metadata": {}, "output_type": "execute_result"}], "source": ["x = range(5)\n", "x"]}, {"cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [{"data": {"text/plain": ["range"]}, "execution_count": 43, "metadata": {}, "output_type": "execute_result"}], "source": ["type(x)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that `range()` returns an object of class `range`, not a list or tuple of the values. Because a `range` object is an iterable, you can obtain the values by iterating over them with a `for` loop:"]}, {"cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["0\n", "1\n", "2\n", "3\n", "4\n"]}], "source": ["for n in x:\n", " print(n)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You could also snag all the values at once with `list()` or `tuple()`. In a REPL session, that can be a convenient way to quickly display what the values are:"]}, {"cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [{"data": {"text/plain": ["[0, 1, 2, 3, 4]"]}, "execution_count": 45, "metadata": {}, "output_type": "execute_result"}], "source": ["list(x)"]}, {"cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [{"data": {"text/plain": ["(0, 1, 2, 3, 4)"]}, "execution_count": 46, "metadata": {}, "output_type": "execute_result"}], "source": ["tuple(x)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["However, when `range()` is used in code that is part of a larger application, it is typically considered poor practice to use `list()` or `tuple()` in this way. Like iterators, `range` objects are lazy\u2014the values in the specified range are not generated until they are requested. Using `list()` or `tuple()` on a range object forces all the values to be returned at once. This is rarely necessary, and if the list is long, it can waste time and memory."]}, {"cell_type": "markdown", "metadata": {}, "source": ["`range(, , )` returns an iterable that yields integers starting with ``, up to but not including ``. If specified, `` indicates an amount to skip between values (analogous to the stride value used for string and list slicing):"]}, {"cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [{"data": {"text/plain": ["[5, 8, 11, 14, 17]"]}, "execution_count": 47, "metadata": {}, "output_type": "execute_result"}], "source": ["list(range(5, 20, 3))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["If `` is omitted, it defaults to `1`:"]}, {"cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [{"data": {"text/plain": ["[5, 6, 7, 8, 9]"]}, "execution_count": 48, "metadata": {}, "output_type": "execute_result"}], "source": ["list(range(5, 10, 1))"]}, {"cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [{"data": {"text/plain": ["[5, 6, 7, 8, 9]"]}, "execution_count": 49, "metadata": {}, "output_type": "execute_result"}], "source": ["list(range(5, 10))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["All the parameters specified to `range()` must be integers, but any of them can be negative. Naturally, if `` is greater than ``, `` must be negative (if you want any results):"]}, {"cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [{"data": {"text/plain": ["[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]"]}, "execution_count": 50, "metadata": {}, "output_type": "execute_result"}], "source": ["list(range(-5, 5))"]}, {"cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [{"data": {"text/plain": ["[]"]}, "execution_count": 51, "metadata": {}, "output_type": "execute_result"}], "source": ["list(range(5, -5))"]}, {"cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [{"data": {"text/plain": ["[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]"]}, "execution_count": 41, "metadata": {}, "output_type": "execute_result"}], "source": ["list(range(5, -5, -1))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Technical Note:** Strictly speaking, `range()` isn\u2019t exactly a built-in function. It is implemented as a callable class that creates an immutable sequence type. But for practical purposes, it behaves like a built-in function. This will be covered later after covering OOP."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Altering `for` Loop Behavior"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You saw in the previous tutorial in the previous sections how execution of a `while` loop can be interrupted with `break` and `continue` statements and modified with an `else` clause. These capabilities are available with the `for` loop as well."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### The break and continue Statements"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`break` and `continue` work the same way with `for` loops as with `while` loops. `break` terminates the loop completely and proceeds to the first statement following the loop:"]}, {"cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n"]}], "source": ["for i in ['foo', 'bar', 'baz', 'qux']:\n", " if 'b' in i:\n", " break\n", " print(i)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`continue` terminates the current iteration and proceeds to the next iteration:"]}, {"cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "qux\n"]}], "source": ["for i in ['foo', 'bar', 'baz', 'qux']:\n", " if 'b' in i:\n", " continue\n", " print(i)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### The `else` Clause"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A `for` loop can have an `else` clause as well. The interpretation is analogous to that of a `while` loop. The `else` clause will be executed if the loop terminates through exhaustion of the iterable:"]}, {"cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n", "bar\n", "baz\n", "qux\n", "Done.\n"]}], "source": ["for i in ['foo', 'bar', 'baz', 'qux']:\n", " print(i)\n", "else:\n", " print('Done.') # Will execute"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `else` clause won\u2019t be executed if the list is broken out of with a `break` statement:"]}, {"cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo\n"]}], "source": ["for i in ['foo', 'bar', 'baz', 'qux']:\n", " if i == 'bar':\n", " break\n", " print(i)\n", "else:\n", " print('Done.') # Will not execute"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Conclusion\n", "This section presented the `for` loop, the workhorse of **definite iteration** in Python."]}, {"cell_type": "markdown", "metadata": {}, "source": ["You also learned about the inner workings of **iterables** and **iterators**, two important object types that underlie definite iteration, but also figure prominently in a wide variety of other Python code."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the next two sections in this introductory series, you will shift gears a little and explore how Python programs can interact with the user via **input** from the keyboard and **output** to the console."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/15 List Comprehension.ipynb b/python/01. Basics/15 List Comprehension.ipynb index cc229c8..d21a090 100644 --- a/python/01. Basics/15 List Comprehension.ipynb +++ b/python/01. Basics/15 List Comprehension.ipynb @@ -1,953 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f58aa0c9", - "metadata": {}, - "source": [ - "# When to Use a List Comprehension in Python" - ] - }, - { - "cell_type": "markdown", - "id": "5f773381", - "metadata": {}, - "source": [ - "Python is famous for allowing you to write code that’s elegant, easy to write, and almost as easy to read as plain English. One of the language’s most distinctive features is the list comprehension, which you can use to create powerful functionality within a single line of code. However, many developers struggle to fully leverage the more advanced features of a list comprehension in Python. Some programmers even use them too much, which can lead to code that’s less efficient and harder to read." - ] - }, - { - "cell_type": "markdown", - "id": "d7e238e3", - "metadata": {}, - "source": [ - "## How to Create Lists in Python" - ] - }, - { - "cell_type": "markdown", - "id": "5f937f87", - "metadata": {}, - "source": [ - "There are a few different ways you can create lists in Python. To better understand the trade-offs of using a list comprehension in Python, let’s first see how to create lists with these approaches." - ] - }, - { - "cell_type": "markdown", - "id": "df590574", - "metadata": {}, - "source": [ - "### Using for Loops" - ] - }, - { - "cell_type": "markdown", - "id": "87440fdd", - "metadata": {}, - "source": [ - "The most common type of loop is the for loop. You can use a for loop to create a list of elements in three steps:\n", - "\n", - "- Instantiate an empty list.\n", - "- Loop over an iterable or range of elements.\n", - "- Append each element to the end of the list." - ] - }, - { - "cell_type": "markdown", - "id": "e60d2a38", - "metadata": {}, - "source": [ - "If you want to create a list containing the first ten perfect squares, then you can complete these steps in three lines of code:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "2c73b929", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "squares = []\n", - "for i in range(10):\n", - " squares.append(i * i)\n", - "squares" - ] - }, - { - "cell_type": "markdown", - "id": "7c41bd32", - "metadata": {}, - "source": [ - "Here, you instantiate an empty list, squares. Then, you use a for loop to iterate over `range(10)`. Finally, you multiply each number by itself and append the result to the end of the list." - ] - }, - { - "cell_type": "markdown", - "id": "4c4ceed1", - "metadata": {}, - "source": [ - "### Using `map()` Objects" - ] - }, - { - "cell_type": "markdown", - "id": "11e32a92", - "metadata": {}, - "source": [ - "`map()` provides an alternative approach that’s based in functional programming. You pass in a function and an iterable, and `map()` will create an object. This object contains the output you would get from running each iterable element through the supplied function." - ] - }, - { - "cell_type": "markdown", - "id": "dcb97c05", - "metadata": {}, - "source": [ - "As an example, consider a situation in which you need to calculate the price after tax for a list of transactions:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "e62aacb6", - "metadata": {}, - "outputs": [], - "source": [ - "txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", - "TAX_RATE = .08" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "96e34612", - "metadata": {}, - "outputs": [], - "source": [ - "def get_price_with_tax(txn):\n", - " return txn * (1 + TAX_RATE)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "baa10386", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "final_prices = map(get_price_with_tax, txns)\n", - "list(final_prices)" - ] - }, - { - "cell_type": "markdown", - "id": "6b958b8b", - "metadata": {}, - "source": [ - "Here, you have an iterable txns and a function `get_price_with_tax()`. You pass both of these arguments to `map()`, and store the resulting object in final_prices. You can easily convert this map object into a list using `list()`." - ] - }, - { - "cell_type": "markdown", - "id": "fb50ab52", - "metadata": {}, - "source": [ - "### Using List Comprehensions" - ] - }, - { - "cell_type": "markdown", - "id": "219dfb6c", - "metadata": {}, - "source": [ - "List comprehensions are a third way of making lists. With this elegant approach, you could rewrite the for loop from the first example in just a single line of code:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "2beeffdd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "squares = [i * i for i in range(10)]\n", - "squares" - ] - }, - { - "cell_type": "markdown", - "id": "c240ed54", - "metadata": {}, - "source": [ - "Rather than creating an empty list and adding each element to the end, you simply define the list and its contents at the same time by following this format:\n", - "\n", - "```python\n", - "new_list = [expression for member in iterable]\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "d150a3b0", - "metadata": {}, - "source": [ - "Every list comprehension in Python includes three elements:\n", - "\n", - "- **expression** is the member itself, a call to a method, or any other valid expression that returns a value. In the example above, the expression `i * i` is the square of the member value.\n", - "- **member** is the object or value in the list or iterable. In the example above, the member value is `i`.\n", - "- **iterable** is a list, set, sequence, generator, or any other object that can return its elements one at a time. In the example above, the iterable is `range(10)`." - ] - }, - { - "cell_type": "markdown", - "id": "ca67f077", - "metadata": {}, - "source": [ - "Because the expression requirement is so flexible, a list comprehension in Python works well in many places where you would use `map()`. You can rewrite the pricing example with its own list comprehension:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "9bcbb0d8", - "metadata": {}, - "outputs": [], - "source": [ - "txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", - "TAX_RATE = .08" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "8fc5c567", - "metadata": {}, - "outputs": [], - "source": [ - "def get_price_with_tax(txn):\n", - " return txn * (1 + TAX_RATE)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "a1ff6b6a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "final_prices = [get_price_with_tax(i) for i in txns]\n", - "final_prices" - ] - }, - { - "cell_type": "markdown", - "id": "460062c4", - "metadata": {}, - "source": [ - "The only distinction between this implementation and `map()` is that the list comprehension in Python returns a list, not a map object." - ] - }, - { - "cell_type": "markdown", - "id": "1ac3dbe9", - "metadata": {}, - "source": [ - "## Benefits of Using List Comprehensions" - ] - }, - { - "cell_type": "markdown", - "id": "93c89e56", - "metadata": {}, - "source": [ - "List comprehensions are often described as being more Pythonic than loops or `map()`. But rather than blindly accepting that assessment, it’s worth it to understand the benefits of using a list comprehension in Python when compared to the alternatives. Later on, you’ll learn about a few scenarios where the alternatives are a better choice." - ] - }, - { - "cell_type": "markdown", - "id": "667b1deb", - "metadata": {}, - "source": [ - "One main benefit of using a list comprehension in Python is that it’s a single tool that you can use in many different situations. In addition to standard list creation, list comprehensions can also be used for mapping and filtering. You don’t have to use a different approach for each scenario." - ] - }, - { - "cell_type": "markdown", - "id": "6f0cfa83", - "metadata": {}, - "source": [ - "This is the main reason why list comprehensions are considered **Pythonic**, as Python embraces simple, powerful tools that you can use in a wide variety of situations. As an added side benefit, whenever you use a list comprehension in Python, you won’t need to remember the proper order of arguments like you would when you call `map()`." - ] - }, - { - "cell_type": "markdown", - "id": "0cc7f834", - "metadata": {}, - "source": [ - "List comprehensions are also more **declarative** than loops, which means they’re easier to read and understand. Loops require you to focus on how the list is created. You have to manually create an empty list, loop over the elements, and add each of them to the end of the list. With a list comprehension in Python, you can instead focus on what you want to go in the list and trust that Python will take care of how the list construction takes place." - ] - }, - { - "cell_type": "markdown", - "id": "8b8662a1", - "metadata": {}, - "source": [ - "## How to Supercharge Your Comprehensions" - ] - }, - { - "cell_type": "markdown", - "id": "4907fcca", - "metadata": {}, - "source": [ - "In order to understand the full value that list comprehensions can provide, it’s helpful to understand their range of possible functionality. You’ll also want to understand the changes that are coming to the list comprehension in Python 3.8." - ] - }, - { - "cell_type": "markdown", - "id": "1849147f", - "metadata": {}, - "source": [ - "### Using Conditional Logic" - ] - }, - { - "cell_type": "markdown", - "id": "9f785fe8", - "metadata": {}, - "source": [ - "Earlier, you saw this formula for how to create list comprehensions:\n", - "\n", - "```python\n", - "new_list = [expression for member in iterable]\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "be67945e", - "metadata": {}, - "source": [ - "While this formula is accurate, it’s also a bit incomplete. A more complete description of the comprehension formula adds support for optional **conditionals**. The most common way to add conditional logic to a list comprehension is to add a conditional to the end of the expression:\n", - "\n", - "```python\n", - "new_list = [expression for member in iterable (if conditional)]\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "ff3b98b8", - "metadata": {}, - "source": [ - "Here, your conditional statement comes just before the closing bracket." - ] - }, - { - "cell_type": "markdown", - "id": "cd7aca65", - "metadata": {}, - "source": [ - "Conditionals are important because they allow list comprehensions to filter out unwanted values, which would normally require a call to `filter()`:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "7dc0e00f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['e', 'o', 'e', 'a', 'e', 'a', 'o', 'a']" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sentence = 'the rocket came back from mars'\n", - "vowels = [i for i in sentence if i in 'aeiou']\n", - "vowels" - ] - }, - { - "cell_type": "markdown", - "id": "65f3c11d", - "metadata": {}, - "source": [ - "In this code block, the conditional statement filters out any characters in sentence that aren’t a vowel." - ] - }, - { - "cell_type": "markdown", - "id": "9fd89f75", - "metadata": {}, - "source": [ - "The conditional can test any valid expression. If you need a more complex filter, then you can even move the conditional logic to a separate function:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "21aa3457", - "metadata": {}, - "outputs": [], - "source": [ - "sentence = 'The rocket, who was named Ted, came back \\\n", - "from Mars because he missed his friends.'" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "78a1f5b5", - "metadata": {}, - "outputs": [], - "source": [ - "def is_consonant(letter):\n", - " vowels = 'aeiou'\n", - " return letter.isalpha() and letter.lower() not in vowels" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "943b870a", - "metadata": {}, - "outputs": [], - "source": [ - "consonants = [i for i in sentence if is_consonant(i)]" - ] - }, - { - "cell_type": "markdown", - "id": "e2ec60d0", - "metadata": {}, - "source": [ - "Here, you create a complex filter `is_consonant()` and pass this function as the conditional statement for your list comprehension. Note that the member value `i` is also passed as an argument to your function." - ] - }, - { - "cell_type": "markdown", - "id": "0d81008b", - "metadata": {}, - "source": [ - "You can place the conditional at the end of the statement for simple filtering, but what if you want to change a member value instead of filtering it out? In this case, it’s useful to place the conditional near the beginning of the expression:\n", - "\n", - "```python\n", - "new_list = [expression (if conditional) for member in iterable]\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "3cd71d06", - "metadata": {}, - "source": [ - "With this formula, you can use conditional logic to select from multiple possible output options. For example, if you have a list of prices, then you may want to replace negative prices with 0 and leave the positive values unchanged:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "f5a18ec4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1.25, 0, 10.22, 3.78, 0, 1.16]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "original_prices = [1.25, -9.45, 10.22, 3.78, -5.92, 1.16]\n", - "prices = [i if i > 0 else 0 for i in original_prices]\n", - "prices" - ] - }, - { - "cell_type": "markdown", - "id": "5caf9204", - "metadata": {}, - "source": [ - "Here, your expression `i` contains a conditional statement, if `i > 0` else `0`. This tells Python to output the value of `i` if the number is positive, but to change `i` to `0` if the number is negative. If this seems overwhelming, then it may be helpful to view the conditional logic as its own function:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "d1381f62", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1.25, 0, 10.22, 3.78, 0, 1.16]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def get_price(price):\n", - " return price if price > 0 else 0\n", - "prices = [get_price(i) for i in original_prices]\n", - "prices" - ] - }, - { - "cell_type": "markdown", - "id": "064c6a70", - "metadata": {}, - "source": [ - "Now, your conditional statement is contained within `get_price()`, and you can use it as part of your list comprehension expression." - ] - }, - { - "cell_type": "markdown", - "id": "474fc0ea", - "metadata": {}, - "source": [ - "### Using Set and Dictionary Comprehensions" - ] - }, - { - "cell_type": "markdown", - "id": "1d2385a4", - "metadata": {}, - "source": [ - "While the list comprehension in Python is a common tool, you can also create set and dictionary comprehensions. A **set** comprehension is almost exactly the same as a list comprehension in Python. The difference is that set comprehensions make sure the output contains no duplicates. You can create a set comprehension by using curly braces instead of brackets:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "568c30fb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'a', 'e', 'i', 'u'}" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "quote = \"life, uh, finds a way\"\n", - "unique_vowels = {i for i in quote if i in 'aeiou'}\n", - "unique_vowels" - ] - }, - { - "cell_type": "markdown", - "id": "1d248f9e", - "metadata": {}, - "source": [ - "Your set comprehension outputs all the unique vowels it found in `quote`. Unlike lists, sets don’t guarantee that items will be saved in any particular order. This is why the first member of the set is `a`, even though the first vowel in quote is `i`." - ] - }, - { - "cell_type": "markdown", - "id": "d5528a3e", - "metadata": {}, - "source": [ - "**Dictionary comprehensions** are similar, with the additional requirement of defining a key:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "8f9f46dc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "squares = {i: i * i for i in range(10)}\n", - "squares" - ] - }, - { - "cell_type": "markdown", - "id": "aaff8d57", - "metadata": {}, - "source": [ - "To create the squares dictionary, you use curly braces (`{}`) as well as a key-value pair (`i: i * i`) in your expression." - ] - }, - { - "cell_type": "markdown", - "id": "970d53c8", - "metadata": {}, - "source": [ - "## When Not to Use a List Comprehension in Python" - ] - }, - { - "cell_type": "markdown", - "id": "98ccc2d1", - "metadata": {}, - "source": [ - "List comprehensions are useful and can help you write elegant code that’s easy to read and debug, but they’re not the right choice for all circumstances. They might make your code run more slowly or use more memory. If your code is less performant or harder to understand, then it’s probably better to choose an alternative." - ] - }, - { - "cell_type": "markdown", - "id": "85c44be6", - "metadata": {}, - "source": [ - "### Watch Out for Nested Comprehensions" - ] - }, - { - "cell_type": "markdown", - "id": "5b51b97b", - "metadata": {}, - "source": [ - "Comprehensions can be **nested** to create combinations of lists, dictionaries, and sets within a collection. For example, say a climate laboratory is tracking the high temperature in five different cities for the first week of June. The perfect data structure for storing this data could be a Python list comprehension nested within a dictionary comprehension:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "f10bbb3b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Austin': [0, 0, 0, 0, 0, 0, 0],\n", - " 'Tacoma': [0, 0, 0, 0, 0, 0, 0],\n", - " 'Topeka': [0, 0, 0, 0, 0, 0, 0],\n", - " 'Sacramento': [0, 0, 0, 0, 0, 0, 0],\n", - " 'Charlotte': [0, 0, 0, 0, 0, 0, 0]}" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cities = ['Austin', 'Tacoma', 'Topeka', 'Sacramento', 'Charlotte']\n", - "temps = {city: [0 for _ in range(7)] for city in cities}\n", - "temps" - ] - }, - { - "cell_type": "markdown", - "id": "41ca8fa2", - "metadata": {}, - "source": [ - "You create the outer collection temps with a dictionary comprehension. The expression is a key-value pair, which contains yet another comprehension. This code will quickly generate a list of data for each city in `cities`." - ] - }, - { - "cell_type": "markdown", - "id": "752369a9", - "metadata": {}, - "source": [ - "Nested lists are a common way to create **matrices**, which are often used for mathematical purposes. Take a look at the code block below:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "9927b614", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[[0, 1, 2, 3, 4],\n", - " [0, 1, 2, 3, 4],\n", - " [0, 1, 2, 3, 4],\n", - " [0, 1, 2, 3, 4],\n", - " [0, 1, 2, 3, 4],\n", - " [0, 1, 2, 3, 4]]" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "matrix = [[i for i in range(5)] for _ in range(6)]\n", - "matrix" - ] - }, - { - "cell_type": "markdown", - "id": "91f049d2", - "metadata": {}, - "source": [ - "The outer list comprehension `[... for _ in range(6)]` creates six rows, while the inner list comprehension `[i for i in range(5)]` fills each of these rows with values." - ] - }, - { - "cell_type": "markdown", - "id": "51ced991", - "metadata": {}, - "source": [ - "So far, the purpose of each nested comprehension is pretty intuitive. However, there are other situations, such as **flattening** nested lists, where the logic arguably makes your code more confusing. Take this example, which uses a nested list comprehension to flatten a matrix:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "29ed6bde", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0,\n", - " 1,\n", - " 2,\n", - " 3,\n", - " 4,\n", - " 0,\n", - " 1,\n", - " 2,\n", - " 3,\n", - " 4,\n", - " 0,\n", - " 1,\n", - " 2,\n", - " 3,\n", - " 4,\n", - " 0,\n", - " 1,\n", - " 2,\n", - " 3,\n", - " 4,\n", - " 0,\n", - " 1,\n", - " 2,\n", - " 3,\n", - " 4,\n", - " 0,\n", - " 1,\n", - " 2,\n", - " 3,\n", - " 4]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "flat = [num for row in matrix for num in row]\n", - "flat" - ] - }, - { - "cell_type": "markdown", - "id": "52288902", - "metadata": {}, - "source": [ - "The code to flatten the matrix is concise, but it may not be so intuitive to understand how it works. On the other hand, if you were to use `for` loops to flatten the same matrix, then your code will be much more straightforward:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "eee26fe5", - "metadata": {}, - "outputs": [], - "source": [ - "matrix = [\n", - " [0, 0, 0],\n", - " [1, 1, 1],\n", - " [2, 2, 2],\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "0aa7e9b8", - "metadata": {}, - "outputs": [], - "source": [ - "flat = []\n", - "for row in matrix:\n", - " for num in row:\n", - " flat.append(num)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "be5af3a0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0, 0, 0, 1, 1, 1, 2, 2, 2]" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "flat" - ] - }, - { - "cell_type": "markdown", - "id": "54bd5157", - "metadata": {}, - "source": [ - "Now you can see that the code traverses one row of the matrix at a time, pulling out all the elements in that row before moving on to the next one." - ] - }, - { - "cell_type": "markdown", - "id": "0f62e378", - "metadata": {}, - "source": [ - "While the single-line nested list comprehension might seem more Pythonic, what’s most important is to write code that your team can easily understand and modify. When you choose your approach, you’ll have to make a judgment call based on whether you think the comprehension helps or hurts readability." - ] - }, - { - "cell_type": "markdown", - "id": "cada16f6", - "metadata": {}, - "source": [ - "## Conclusion" - ] - }, - { - "cell_type": "markdown", - "id": "a6af6814", - "metadata": {}, - "source": [ - "In this tutorial, you learned how to use a list comprehension in Python to accomplish complex tasks without making your code overly complicated." - ] - }, - { - "cell_type": "markdown", - "id": "c2c3695b", - "metadata": {}, - "source": [ - "Now you can:\n", - "\n", - "- Simplify loops and `map()` calls with declarative **list comprehensions**\n", - "- Supercharge your comprehensions with **conditional logic**\n", - "- Create **set** and **dictionary** comprehensions\n", - "- Determine when code clarity or performance dictates an **alternative approach**" - ] - }, - { - "cell_type": "markdown", - "id": "856a033b", - "metadata": {}, - "source": [ - "Whenever you have to choose a list creation method, try multiple implementations and consider what’s easiest to read and understand in your specific scenario. If performance is important, then you can use profiling tools to give you actionable data instead of relying on hunches or guesses about what works the best." - ] - }, - { - "cell_type": "markdown", - "id": "e8ae0177", - "metadata": {}, - "source": [ - "Remember that while Python list comprehensions get a lot of attention, your intuition and ability to use data when it counts will help you write clean code that serves the task at hand. This, ultimately, is the key to making your code Pythonic!" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} +{"cells": [{"cell_type": "markdown", "id": "f58aa0c9", "metadata": {}, "source": ["# When to Use a List Comprehension in Python"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [How to Create Lists in Python](#how_to_create_lists_in_python)\n * [Using for Loops](#using_for_loops)\n * [Using `map()` Objects](#using_`map()`_objects)\n * [Using List Comprehensions](#using_list_comprehensions)\n* [Benefits of Using List Comprehensions](#benefits_of_using_list_comprehensions)\n* [How to Supercharge Your Comprehensions](#how_to_supercharge_your_comprehensions)\n * [Using Conditional Logic](#using_conditional_logic)\n * [Using Set and Dictionary Comprehensions](#using_set_and_dictionary_comprehensions)\n* [When Not to Use a List Comprehension in Python](#when_not_to_use_a_list_comprehension_in_python)\n * [Watch Out for Nested Comprehensions](#watch_out_for_nested_comprehensions)\n* [Conclusion](#conclusion)\n\n---"]}, {"cell_type": "markdown", "id": "5f773381", "metadata": {}, "source": ["Python is famous for allowing you to write code that\u2019s elegant, easy to write, and almost as easy to read as plain English. One of the language\u2019s most distinctive features is the list comprehension, which you can use to create powerful functionality within a single line of code. However, many developers struggle to fully leverage the more advanced features of a list comprehension in Python. Some programmers even use them too much, which can lead to code that\u2019s less efficient and harder to read."]}, {"cell_type": "markdown", "id": "d7e238e3", "metadata": {}, "source": ["", "\n", "## How to Create Lists in Python"]}, {"cell_type": "markdown", "id": "5f937f87", "metadata": {}, "source": ["There are a few different ways you can create lists in Python. To better understand the trade-offs of using a list comprehension in Python, let\u2019s first see how to create lists with these approaches."]}, {"cell_type": "markdown", "id": "df590574", "metadata": {}, "source": ["", "\n", "### Using for Loops"]}, {"cell_type": "markdown", "id": "87440fdd", "metadata": {}, "source": ["The most common type of loop is the for loop. You can use a for loop to create a list of elements in three steps:\n", "\n", "- Instantiate an empty list.\n", "- Loop over an iterable or range of elements.\n", "- Append each element to the end of the list."]}, {"cell_type": "markdown", "id": "e60d2a38", "metadata": {}, "source": ["If you want to create a list containing the first ten perfect squares, then you can complete these steps in three lines of code:"]}, {"cell_type": "code", "execution_count": 27, "id": "2c73b929", "metadata": {}, "outputs": [{"data": {"text/plain": ["[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"]}, "execution_count": 27, "metadata": {}, "output_type": "execute_result"}], "source": ["squares = []\n", "for i in range(10):\n", " squares.append(i * i)\n", "squares"]}, {"cell_type": "markdown", "id": "7c41bd32", "metadata": {}, "source": ["Here, you instantiate an empty list, squares. Then, you use a for loop to iterate over `range(10)`. Finally, you multiply each number by itself and append the result to the end of the list."]}, {"cell_type": "markdown", "id": "4c4ceed1", "metadata": {}, "source": ["", "\n", "### Using `map()` Objects"]}, {"cell_type": "markdown", "id": "11e32a92", "metadata": {}, "source": ["`map()` provides an alternative approach that\u2019s based in functional programming. You pass in a function and an iterable, and `map()` will create an object. This object contains the output you would get from running each iterable element through the supplied function."]}, {"cell_type": "markdown", "id": "dcb97c05", "metadata": {}, "source": ["As an example, consider a situation in which you need to calculate the price after tax for a list of transactions:"]}, {"cell_type": "code", "execution_count": 6, "id": "e62aacb6", "metadata": {}, "outputs": [], "source": ["txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", "TAX_RATE = .08"]}, {"cell_type": "code", "execution_count": 7, "id": "96e34612", "metadata": {}, "outputs": [], "source": ["def get_price_with_tax(txn):\n", " return txn * (1 + TAX_RATE)"]}, {"cell_type": "code", "execution_count": 8, "id": "baa10386", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["final_prices = map(get_price_with_tax, txns)\n", "list(final_prices)"]}, {"cell_type": "markdown", "id": "6b958b8b", "metadata": {}, "source": ["Here, you have an iterable txns and a function `get_price_with_tax()`. You pass both of these arguments to `map()`, and store the resulting object in final_prices. You can easily convert this map object into a list using `list()`."]}, {"cell_type": "markdown", "id": "fb50ab52", "metadata": {}, "source": ["", "\n", "### Using List Comprehensions"]}, {"cell_type": "markdown", "id": "219dfb6c", "metadata": {}, "source": ["List comprehensions are a third way of making lists. With this elegant approach, you could rewrite the for loop from the first example in just a single line of code:"]}, {"cell_type": "code", "execution_count": 87, "id": "2beeffdd", "metadata": {}, "outputs": [{"data": {"text/plain": ["[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"]}, "execution_count": 87, "metadata": {}, "output_type": "execute_result"}], "source": ["squares = [i * i for i in range(10)]\n", "squares"]}, {"cell_type": "markdown", "id": "c240ed54", "metadata": {}, "source": ["Rather than creating an empty list and adding each element to the end, you simply define the list and its contents at the same time by following this format:\n", "\n", "```python\n", "new_list = [expression for member in iterable]\n", "```"]}, {"cell_type": "markdown", "id": "d150a3b0", "metadata": {}, "source": ["Every list comprehension in Python includes three elements:\n", "\n", "- **expression** is the member itself, a call to a method, or any other valid expression that returns a value. In the example above, the expression `i * i` is the square of the member value.\n", "- **member** is the object or value in the list or iterable. In the example above, the member value is `i`.\n", "- **iterable** is a list, set, sequence, generator, or any other object that can return its elements one at a time. In the example above, the iterable is `range(10)`."]}, {"cell_type": "markdown", "id": "ca67f077", "metadata": {}, "source": ["Because the expression requirement is so flexible, a list comprehension in Python works well in many places where you would use `map()`. You can rewrite the pricing example with its own list comprehension:"]}, {"cell_type": "code", "execution_count": 10, "id": "9bcbb0d8", "metadata": {}, "outputs": [], "source": ["txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", "TAX_RATE = .08"]}, {"cell_type": "code", "execution_count": 11, "id": "8fc5c567", "metadata": {}, "outputs": [], "source": ["def get_price_with_tax(txn):\n", " return txn * (1 + TAX_RATE)"]}, {"cell_type": "code", "execution_count": 12, "id": "a1ff6b6a", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["final_prices = [get_price_with_tax(i) for i in txns]\n", "final_prices"]}, {"cell_type": "markdown", "id": "460062c4", "metadata": {}, "source": ["The only distinction between this implementation and `map()` is that the list comprehension in Python returns a list, not a map object."]}, {"cell_type": "markdown", "id": "1ac3dbe9", "metadata": {}, "source": ["", "\n", "## Benefits of Using List Comprehensions"]}, {"cell_type": "markdown", "id": "93c89e56", "metadata": {}, "source": ["List comprehensions are often described as being more Pythonic than loops or `map()`. But rather than blindly accepting that assessment, it\u2019s worth it to understand the benefits of using a list comprehension in Python when compared to the alternatives. Later on, you\u2019ll learn about a few scenarios where the alternatives are a better choice."]}, {"cell_type": "markdown", "id": "667b1deb", "metadata": {}, "source": ["One main benefit of using a list comprehension in Python is that it\u2019s a single tool that you can use in many different situations. In addition to standard list creation, list comprehensions can also be used for mapping and filtering. You don\u2019t have to use a different approach for each scenario."]}, {"cell_type": "markdown", "id": "6f0cfa83", "metadata": {}, "source": ["This is the main reason why list comprehensions are considered **Pythonic**, as Python embraces simple, powerful tools that you can use in a wide variety of situations. As an added side benefit, whenever you use a list comprehension in Python, you won\u2019t need to remember the proper order of arguments like you would when you call `map()`."]}, {"cell_type": "markdown", "id": "0cc7f834", "metadata": {}, "source": ["List comprehensions are also more **declarative** than loops, which means they\u2019re easier to read and understand. Loops require you to focus on how the list is created. You have to manually create an empty list, loop over the elements, and add each of them to the end of the list. With a list comprehension in Python, you can instead focus on what you want to go in the list and trust that Python will take care of how the list construction takes place."]}, {"cell_type": "markdown", "id": "8b8662a1", "metadata": {}, "source": ["", "\n", "## How to Supercharge Your Comprehensions"]}, {"cell_type": "markdown", "id": "4907fcca", "metadata": {}, "source": ["In order to understand the full value that list comprehensions can provide, it\u2019s helpful to understand their range of possible functionality. You\u2019ll also want to understand the changes that are coming to the list comprehension in Python 3.8."]}, {"cell_type": "markdown", "id": "1849147f", "metadata": {}, "source": ["", "\n", "### Using Conditional Logic"]}, {"cell_type": "markdown", "id": "9f785fe8", "metadata": {}, "source": ["Earlier, you saw this formula for how to create list comprehensions:\n", "\n", "```python\n", "new_list = [expression for member in iterable]\n", "```"]}, {"cell_type": "markdown", "id": "be67945e", "metadata": {}, "source": ["While this formula is accurate, it\u2019s also a bit incomplete. A more complete description of the comprehension formula adds support for optional **conditionals**. The most common way to add conditional logic to a list comprehension is to add a conditional to the end of the expression:\n", "\n", "```python\n", "new_list = [expression for member in iterable (if conditional)]\n", "```"]}, {"cell_type": "markdown", "id": "ff3b98b8", "metadata": {}, "source": ["Here, your conditional statement comes just before the closing bracket."]}, {"cell_type": "markdown", "id": "cd7aca65", "metadata": {}, "source": ["Conditionals are important because they allow list comprehensions to filter out unwanted values, which would normally require a call to `filter()`:"]}, {"cell_type": "code", "execution_count": 13, "id": "7dc0e00f", "metadata": {}, "outputs": [{"data": {"text/plain": ["['e', 'o', 'e', 'a', 'e', 'a', 'o', 'a']"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["sentence = 'the rocket came back from mars'\n", "vowels = [i for i in sentence if i in 'aeiou']\n", "vowels"]}, {"cell_type": "markdown", "id": "65f3c11d", "metadata": {}, "source": ["In this code block, the conditional statement filters out any characters in sentence that aren\u2019t a vowel."]}, {"cell_type": "markdown", "id": "9fd89f75", "metadata": {}, "source": ["The conditional can test any valid expression. If you need a more complex filter, then you can even move the conditional logic to a separate function:"]}, {"cell_type": "code", "execution_count": 14, "id": "21aa3457", "metadata": {}, "outputs": [], "source": ["sentence = 'The rocket, who was named Ted, came back \\\n", "from Mars because he missed his friends.'"]}, {"cell_type": "code", "execution_count": 15, "id": "78a1f5b5", "metadata": {}, "outputs": [], "source": ["def is_consonant(letter):\n", " vowels = 'aeiou'\n", " return letter.isalpha() and letter.lower() not in vowels"]}, {"cell_type": "code", "execution_count": 16, "id": "943b870a", "metadata": {}, "outputs": [], "source": ["consonants = [i for i in sentence if is_consonant(i)]"]}, {"cell_type": "markdown", "id": "e2ec60d0", "metadata": {}, "source": ["Here, you create a complex filter `is_consonant()` and pass this function as the conditional statement for your list comprehension. Note that the member value `i` is also passed as an argument to your function."]}, {"cell_type": "markdown", "id": "0d81008b", "metadata": {}, "source": ["You can place the conditional at the end of the statement for simple filtering, but what if you want to change a member value instead of filtering it out? In this case, it\u2019s useful to place the conditional near the beginning of the expression:\n", "\n", "```python\n", "new_list = [expression (if conditional) for member in iterable]\n", "```"]}, {"cell_type": "markdown", "id": "3cd71d06", "metadata": {}, "source": ["With this formula, you can use conditional logic to select from multiple possible output options. For example, if you have a list of prices, then you may want to replace negative prices with 0 and leave the positive values unchanged:"]}, {"cell_type": "code", "execution_count": 17, "id": "f5a18ec4", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1.25, 0, 10.22, 3.78, 0, 1.16]"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["original_prices = [1.25, -9.45, 10.22, 3.78, -5.92, 1.16]\n", "prices = [i if i > 0 else 0 for i in original_prices]\n", "prices"]}, {"cell_type": "markdown", "id": "5caf9204", "metadata": {}, "source": ["Here, your expression `i` contains a conditional statement, if `i > 0` else `0`. This tells Python to output the value of `i` if the number is positive, but to change `i` to `0` if the number is negative. If this seems overwhelming, then it may be helpful to view the conditional logic as its own function:"]}, {"cell_type": "code", "execution_count": 18, "id": "d1381f62", "metadata": {}, "outputs": [{"data": {"text/plain": ["[1.25, 0, 10.22, 3.78, 0, 1.16]"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["def get_price(price):\n", " return price if price > 0 else 0\n", "prices = [get_price(i) for i in original_prices]\n", "prices"]}, {"cell_type": "markdown", "id": "064c6a70", "metadata": {}, "source": ["Now, your conditional statement is contained within `get_price()`, and you can use it as part of your list comprehension expression."]}, {"cell_type": "markdown", "id": "474fc0ea", "metadata": {}, "source": ["", "\n", "### Using Set and Dictionary Comprehensions"]}, {"cell_type": "markdown", "id": "1d2385a4", "metadata": {}, "source": ["While the list comprehension in Python is a common tool, you can also create set and dictionary comprehensions. A **set** comprehension is almost exactly the same as a list comprehension in Python. The difference is that set comprehensions make sure the output contains no duplicates. You can create a set comprehension by using curly braces instead of brackets:"]}, {"cell_type": "code", "execution_count": 110, "id": "568c30fb", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'a', 'e', 'i', 'u'}"]}, "execution_count": 110, "metadata": {}, "output_type": "execute_result"}], "source": ["quote = \"life, uh, finds a way\"\n", "unique_vowels = {i for i in quote if i in 'aeiou'}\n", "unique_vowels"]}, {"cell_type": "markdown", "id": "1d248f9e", "metadata": {}, "source": ["Your set comprehension outputs all the unique vowels it found in `quote`. Unlike lists, sets don\u2019t guarantee that items will be saved in any particular order. This is why the first member of the set is `a`, even though the first vowel in quote is `i`."]}, {"cell_type": "markdown", "id": "d5528a3e", "metadata": {}, "source": ["**Dictionary comprehensions** are similar, with the additional requirement of defining a key:"]}, {"cell_type": "code", "execution_count": 111, "id": "8f9f46dc", "metadata": {}, "outputs": [{"data": {"text/plain": ["{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}"]}, "execution_count": 111, "metadata": {}, "output_type": "execute_result"}], "source": ["squares = {i: i * i for i in range(10)}\n", "squares"]}, {"cell_type": "markdown", "id": "aaff8d57", "metadata": {}, "source": ["To create the squares dictionary, you use curly braces (`{}`) as well as a key-value pair (`i: i * i`) in your expression."]}, {"cell_type": "markdown", "id": "970d53c8", "metadata": {}, "source": ["", "\n", "## When Not to Use a List Comprehension in Python"]}, {"cell_type": "markdown", "id": "98ccc2d1", "metadata": {}, "source": ["List comprehensions are useful and can help you write elegant code that\u2019s easy to read and debug, but they\u2019re not the right choice for all circumstances. They might make your code run more slowly or use more memory. If your code is less performant or harder to understand, then it\u2019s probably better to choose an alternative."]}, {"cell_type": "markdown", "id": "85c44be6", "metadata": {}, "source": ["", "\n", "### Watch Out for Nested Comprehensions"]}, {"cell_type": "markdown", "id": "5b51b97b", "metadata": {}, "source": ["Comprehensions can be **nested** to create combinations of lists, dictionaries, and sets within a collection. For example, say a climate laboratory is tracking the high temperature in five different cities for the first week of June. The perfect data structure for storing this data could be a Python list comprehension nested within a dictionary comprehension:"]}, {"cell_type": "code", "execution_count": 21, "id": "f10bbb3b", "metadata": {}, "outputs": [{"data": {"text/plain": ["{'Austin': [0, 0, 0, 0, 0, 0, 0],\n", " 'Tacoma': [0, 0, 0, 0, 0, 0, 0],\n", " 'Topeka': [0, 0, 0, 0, 0, 0, 0],\n", " 'Sacramento': [0, 0, 0, 0, 0, 0, 0],\n", " 'Charlotte': [0, 0, 0, 0, 0, 0, 0]}"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["cities = ['Austin', 'Tacoma', 'Topeka', 'Sacramento', 'Charlotte']\n", "temps = {city: [0 for _ in range(7)] for city in cities}\n", "temps"]}, {"cell_type": "markdown", "id": "41ca8fa2", "metadata": {}, "source": ["You create the outer collection temps with a dictionary comprehension. The expression is a key-value pair, which contains yet another comprehension. This code will quickly generate a list of data for each city in `cities`."]}, {"cell_type": "markdown", "id": "752369a9", "metadata": {}, "source": ["Nested lists are a common way to create **matrices**, which are often used for mathematical purposes. Take a look at the code block below:"]}, {"cell_type": "code", "execution_count": 22, "id": "9927b614", "metadata": {}, "outputs": [{"data": {"text/plain": ["[[0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4]]"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["matrix = [[i for i in range(5)] for _ in range(6)]\n", "matrix"]}, {"cell_type": "markdown", "id": "91f049d2", "metadata": {}, "source": ["The outer list comprehension `[... for _ in range(6)]` creates six rows, while the inner list comprehension `[i for i in range(5)]` fills each of these rows with values."]}, {"cell_type": "markdown", "id": "51ced991", "metadata": {}, "source": ["So far, the purpose of each nested comprehension is pretty intuitive. However, there are other situations, such as **flattening** nested lists, where the logic arguably makes your code more confusing. Take this example, which uses a nested list comprehension to flatten a matrix:"]}, {"cell_type": "code", "execution_count": 23, "id": "29ed6bde", "metadata": {}, "outputs": [{"data": {"text/plain": ["[0,\n", " 1,\n", " 2,\n", " 3,\n", " 4,\n", " 0,\n", " 1,\n", " 2,\n", " 3,\n", " 4,\n", " 0,\n", " 1,\n", " 2,\n", " 3,\n", " 4,\n", " 0,\n", " 1,\n", " 2,\n", " 3,\n", " 4,\n", " 0,\n", " 1,\n", " 2,\n", " 3,\n", " 4,\n", " 0,\n", " 1,\n", " 2,\n", " 3,\n", " 4]"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["flat = [num for row in matrix for num in row]\n", "flat"]}, {"cell_type": "markdown", "id": "52288902", "metadata": {}, "source": ["The code to flatten the matrix is concise, but it may not be so intuitive to understand how it works. On the other hand, if you were to use `for` loops to flatten the same matrix, then your code will be much more straightforward:"]}, {"cell_type": "code", "execution_count": 24, "id": "eee26fe5", "metadata": {}, "outputs": [], "source": ["matrix = [\n", " [0, 0, 0],\n", " [1, 1, 1],\n", " [2, 2, 2],\n", "]"]}, {"cell_type": "code", "execution_count": 26, "id": "0aa7e9b8", "metadata": {}, "outputs": [], "source": ["flat = []\n", "for row in matrix:\n", " for num in row:\n", " flat.append(num)"]}, {"cell_type": "code", "execution_count": 27, "id": "be5af3a0", "metadata": {}, "outputs": [{"data": {"text/plain": ["[0, 0, 0, 1, 1, 1, 2, 2, 2]"]}, "execution_count": 27, "metadata": {}, "output_type": "execute_result"}], "source": ["flat"]}, {"cell_type": "markdown", "id": "54bd5157", "metadata": {}, "source": ["Now you can see that the code traverses one row of the matrix at a time, pulling out all the elements in that row before moving on to the next one."]}, {"cell_type": "markdown", "id": "0f62e378", "metadata": {}, "source": ["While the single-line nested list comprehension might seem more Pythonic, what\u2019s most important is to write code that your team can easily understand and modify. When you choose your approach, you\u2019ll have to make a judgment call based on whether you think the comprehension helps or hurts readability."]}, {"cell_type": "markdown", "id": "cada16f6", "metadata": {}, "source": ["", "\n", "## Conclusion"]}, {"cell_type": "markdown", "id": "a6af6814", "metadata": {}, "source": ["In this tutorial, you learned how to use a list comprehension in Python to accomplish complex tasks without making your code overly complicated."]}, {"cell_type": "markdown", "id": "c2c3695b", "metadata": {}, "source": ["Now you can:\n", "\n", "- Simplify loops and `map()` calls with declarative **list comprehensions**\n", "- Supercharge your comprehensions with **conditional logic**\n", "- Create **set** and **dictionary** comprehensions\n", "- Determine when code clarity or performance dictates an **alternative approach**"]}, {"cell_type": "markdown", "id": "856a033b", "metadata": {}, "source": ["Whenever you have to choose a list creation method, try multiple implementations and consider what\u2019s easiest to read and understand in your specific scenario. If performance is important, then you can use profiling tools to give you actionable data instead of relying on hunches or guesses about what works the best."]}, {"cell_type": "markdown", "id": "e8ae0177", "metadata": {}, "source": ["Remember that while Python list comprehensions get a lot of attention, your intuition and ability to use data when it counts will help you write clean code that serves the task at hand. This, ultimately, is the key to making your code Pythonic!"]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 5} \ No newline at end of file diff --git a/python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb b/python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb index d7a00ef..d8de5fd 100755 --- a/python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb +++ b/python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb @@ -1,729 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Basic Input, Output, and String Formatting in Python" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To be useful, a program usually needs to communicate with the outside world by obtaining input data from the user and displaying result data back to the user. This tutorial will introduce you to Python input and output." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Input may come directly from the user via the keyboard, or from some external source like a file or database. Output can be displayed directly to the console or IDE, to the screen via a Graphical User Interface (GUI), or again to an external source." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "By the end of this section, you’ll know how to:\n", - "\n", - "- Take user input from the keyboard with the built-in function `input()`\n", - "- Display output to the console with the built-in function `print()`\n", - "- Format string data with the **string modulo operator**" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reading Input From the Keyboard" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Programs often need to obtain data from the user, usually by way of input from the keyboard. The simplest way to accomplish this in Python is with `input()`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> `input([])`\n", - "> \n", - "> Reads a line of input from the keyboard." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`input()` pauses program execution to allow the user to type in a line of input from the keyboard. Once the user presses the _Enter_ key, all characters typed are read and returned as a string:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "some text\n" - ] - }, - { - "data": { - "text/plain": [ - "'some text'" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = input()\n", - "\n", - "s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the newline generated when the user presses the _Enter_ key isn’t included as part of the return string." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you include the optional `` argument, `input()` displays it as a prompt to the user before pausing to read input:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "What is your name? Ali\n" - ] - }, - { - "data": { - "text/plain": [ - "'Ali'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "name = input('What is your name? ')\n", - "\n", - "name" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`input()` always returns a string. If you want a numeric type, then you need to convert the string to the appropriate type with the `int()`, `float()`, or `complex()` built-in functions:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter a number: 10\n" - ] - } - ], - "source": [ - "n = input('Enter a number: ')" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "can only concatenate str (not \"int\") to str", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" - ] - } - ], - "source": [ - "print(n + 100)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Enter a number: 10\n" - ] - } - ], - "source": [ - "n = int(input('Enter a number: '))" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "110\n" - ] - } - ], - "source": [ - "print(n + 100)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the example above, the expression `n + 100` is invalid because `n` is a string and `100` is an integer. `int()` converts `n` to an integer so the `print()` statement finally succeeds." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> **Python Version Note:** Should you find yourself working with Python 2.x code, you might bump into a slight difference in the input functions between Python versions 2 and 3.\n", - "> \n", - "> `raw_input()` in Python 2 reads input from the keyboard and returns it. `raw_input()` in Python 2 behaves just like `input()` in Python 3, as described above.\n", - "> \n", - "> But Python 2 also has a function called `input()`. In Python 2, `input()` reads input from the keyboard, parses and evaluates it as a Python expression, and then returns the resulting value.\n", - "> \n", - "> Python 3 does not provide a single function that does exactly what Python 2’s `input()` does. The effect can be mimicked in Python 3 with the expression `eval(input())`. However, this is considered a security risk because it allows a user to run arbitrary, potentially malicious code.\n", - "> \n", - "> For more information on `eval()` and its potential security risks, check out [Python eval(): Evaluate Expressions Dynamically](https://realpython.com/python-eval-function/)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Writing Output to the Console" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition to obtaining data from the user, a program will also usually need to present data back to the user. You can display program data to the console in Python with `print()`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Unformatted Console Output\n", - "To display objects to the console, pass them as a comma-separated list of arguments to `print()`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> `print(, ..., )`\n", - "> \n", - "> Displays a string representation of each to the console." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "By default, `print()` separates each object by a single space and appends a newline to the end of the output:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Name: Winston Smith\n" - ] - } - ], - "source": [ - "fname = 'Winston'\n", - "lname = 'Smith'\n", - "\n", - "print('Name:', fname, lname)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Any type of object can be specified as an argument to `print()`. If an object isn’t a string, then `print()` converts it to an appropriate string representation displaying it:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "list" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a = [1, 2, 3]\n", - "type(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b = -12\n", - "type(b)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d = {'foo': 1, 'bar': 2}\n", - "type(d)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "builtin_function_or_method" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "type(len)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3] -12 {'foo': 1, 'bar': 2} \n" - ] - } - ], - "source": [ - "print(a, b, d, len)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see, even complex types like lists, dictionaries, and functions can be displayed to the console with `print()`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Keyword Arguments to `print()`\n", - "\n", - "`print()` takes a few additional arguments that provide modest control over the format of the output. Each of these is a special type of argument called a **keyword argument**. This introductory series will include a section on functions and parameter passing so you can learn more about keyword arguments." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For now, here’s what you need to know:\n", - "\n", - "- Keyword arguments have the form `=`.\n", - "- Any keyword arguments passed to `print()` must come at the end, after the list of objects to display." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the following sections, you’ll see how these keyword arguments affect console output produced by `print()`." - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ali....hejazizo\n" - ] - } - ], - "source": [ - "print('ali', 'hejazizo', sep='....')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### The `sep=` Keyword Argument" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Adding the keyword argument `sep=` causes objects to be separated by the string `` instead of the default single space:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo 42 bar\n" - ] - } - ], - "source": [ - "print('foo', 42, 'bar')" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo/42/bar\n" - ] - } - ], - "source": [ - "print('foo', 42, 'bar', sep='/')" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo...42...bar\n" - ] - } - ], - "source": [ - "print('foo', 42, 'bar', sep='...')" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo -> 1\n", - "bar -> 2\n", - "baz -> 3\n" - ] - } - ], - "source": [ - "d = {'foo': 1, 'bar': 2, 'baz': 3}\n", - "for k, v in d.items():\n", - " print(k, v, sep=' -> ')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To squish objects together without any space between them, specify `sep=''`:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo42bar\n" - ] - } - ], - "source": [ - "print('foo', 42, 'bar', sep='')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can specify any arbitrary string as the separator with the `sep=` keyword." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### The `end=` Keyword Argument\n", - "The keyword argument `end=` causes output to be terminated by `` instead of the default newline:" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "foo/42/bar\n" - ] - } - ], - "source": [ - "if True:\n", - " print('foo', end='/')\n", - " print(42, end='/')\n", - " print('bar')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, if you are displaying values in a loop, you might use `end=` to cause the values to be displayed on one line, rather than on individual lines:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1\n", - "2\n", - "3\n", - "4\n", - "5\n", - "6\n", - "7\n", - "8\n", - "9\n" - ] - } - ], - "source": [ - "for n in range(10):\n", - " print(n)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1 2 3 4 5 6 7 8 9 10\n", - "11 12 13 14 15 16 17 18 19 20\n", - "21 22 23 24 25 26 27 28 29 30\n" - ] - } - ], - "source": [ - "for n in range(31):\n", - " print(n, end=(' ' if n % 10 != 0 else '\\n'))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Any string may be specified as the output terminator with the `end=` keyword." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Output Stream Keyword Arguments\n", - "`print()` accepts two additional keyword arguments, both of which affect handling of the output stream:\n", - "\n", - "- `file=`: By default, `print()` sends its output to a default stream called `sys.stdout`, which is usually equivalent to the console. The `file=` argument causes output to be sent to an alternate stream designated by `` instead.\n", - "\n", - "- `flush=True`: Ordinarily, `print()` buffers its output and only writes to the output stream intermittently. `flush=True` specifies that the output stream is forcibly flushed with each `print()`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "These two keyword arguments are presented here for the sake of completeness. You probably don’t need to be too concerned about output streams at this point. They are discussed later in this series in the section on File I/O." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Formatted String Output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`print()` supports formatting of console output that is rudimentary at best. You can choose how to separate printed objects, and you can specify what goes at the end of the printed line. That’s about it." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In many cases, you’ll need more precise control over the appearance of data destined for display. Python provides several ways to format output string data. One of the older ones is the **string modulo operator**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In recent versions of Python, there are newer ways to format string data that are arguably superior to the string modulo operator: the **string `.format()` method**, and **f-strings**. You will learn about these in the next section in this series." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.10" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Basic Input, Output, and String Formatting in Python"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Table of Contents\n\n\n* [Reading Input From the Keyboard](#reading_input_from_the_keyboard)\n* [Writing Output to the Console](#writing_output_to_the_console)\n * [Unformatted Console Output](#unformatted_console_output)\n * [Keyword Arguments to `print()`](#keyword_arguments_to_`print()`)\n * [Output Stream Keyword Arguments](#output_stream_keyword_arguments)\n* [Formatted String Output](#formatted_string_output)\n\n---"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To be useful, a program usually needs to communicate with the outside world by obtaining input data from the user and displaying result data back to the user. This tutorial will introduce you to Python input and output."]}, {"cell_type": "markdown", "metadata": {}, "source": ["Input may come directly from the user via the keyboard, or from some external source like a file or database. Output can be displayed directly to the console or IDE, to the screen via a Graphical User Interface (GUI), or again to an external source."]}, {"cell_type": "markdown", "metadata": {}, "source": ["By the end of this section, you\u2019ll know how to:\n", "\n", "- Take user input from the keyboard with the built-in function `input()`\n", "- Display output to the console with the built-in function `print()`\n", "- Format string data with the **string modulo operator**"]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Reading Input From the Keyboard"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Programs often need to obtain data from the user, usually by way of input from the keyboard. The simplest way to accomplish this in Python is with `input()`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> `input([])`\n", "> \n", "> Reads a line of input from the keyboard."]}, {"cell_type": "markdown", "metadata": {}, "source": ["`input()` pauses program execution to allow the user to type in a line of input from the keyboard. Once the user presses the _Enter_ key, all characters typed are read and returned as a string:"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["some text\n"]}, {"data": {"text/plain": ["'some text'"]}, "execution_count": 1, "metadata": {}, "output_type": "execute_result"}], "source": ["s = input()\n", "\n", "s"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Note that the newline generated when the user presses the _Enter_ key isn\u2019t included as part of the return string."]}, {"cell_type": "markdown", "metadata": {}, "source": ["If you include the optional `` argument, `input()` displays it as a prompt to the user before pausing to read input:"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["What is your name? Ali\n"]}, {"data": {"text/plain": ["'Ali'"]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["name = input('What is your name? ')\n", "\n", "name"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`input()` always returns a string. If you want a numeric type, then you need to convert the string to the appropriate type with the `int()`, `float()`, or `complex()` built-in functions:"]}, {"cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Enter a number: 10\n"]}], "source": ["n = input('Enter a number: ')"]}, {"cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [{"ename": "TypeError", "evalue": "can only concatenate str (not \"int\") to str", "output_type": "error", "traceback": ["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str"]}], "source": ["print(n + 100)"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Enter a number: 10\n"]}], "source": ["n = int(input('Enter a number: '))"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["110\n"]}], "source": ["print(n + 100)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the example above, the expression `n + 100` is invalid because `n` is a string and `100` is an integer. `int()` converts `n` to an integer so the `print()` statement finally succeeds."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> **Python Version Note:** Should you find yourself working with Python 2.x code, you might bump into a slight difference in the input functions between Python versions 2 and 3.\n", "> \n", "> `raw_input()` in Python 2 reads input from the keyboard and returns it. `raw_input()` in Python 2 behaves just like `input()` in Python 3, as described above.\n", "> \n", "> But Python 2 also has a function called `input()`. In Python 2, `input()` reads input from the keyboard, parses and evaluates it as a Python expression, and then returns the resulting value.\n", "> \n", "> Python 3 does not provide a single function that does exactly what Python 2\u2019s `input()` does. The effect can be mimicked in Python 3 with the expression `eval(input())`. However, this is considered a security risk because it allows a user to run arbitrary, potentially malicious code.\n", "> \n", "> For more information on `eval()` and its potential security risks, check out [Python eval(): Evaluate Expressions Dynamically](https://realpython.com/python-eval-function/)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Writing Output to the Console"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In addition to obtaining data from the user, a program will also usually need to present data back to the user. You can display program data to the console in Python with `print()`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Unformatted Console Output\n", "To display objects to the console, pass them as a comma-separated list of arguments to `print()`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["> `print(, ..., )`\n", "> \n", "> Displays a string representation of each to the console."]}, {"cell_type": "markdown", "metadata": {}, "source": ["By default, `print()` separates each object by a single space and appends a newline to the end of the output:"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Name: Winston Smith\n"]}], "source": ["fname = 'Winston'\n", "lname = 'Smith'\n", "\n", "print('Name:', fname, lname)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Any type of object can be specified as an argument to `print()`. If an object isn\u2019t a string, then `print()` converts it to an appropriate string representation displaying it:"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"text/plain": ["list"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["a = [1, 2, 3]\n", "type(a)"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/plain": ["int"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["b = -12\n", "type(b)"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/plain": ["dict"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["d = {'foo': 1, 'bar': 2}\n", "type(d)"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["builtin_function_or_method"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["type(len)"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["[1, 2, 3] -12 {'foo': 1, 'bar': 2} \n"]}], "source": ["print(a, b, d, len)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["As you can see, even complex types like lists, dictionaries, and functions can be displayed to the console with `print()`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Keyword Arguments to `print()`\n", "\n", "`print()` takes a few additional arguments that provide modest control over the format of the output. Each of these is a special type of argument called a **keyword argument**. This introductory series will include a section on functions and parameter passing so you can learn more about keyword arguments."]}, {"cell_type": "markdown", "metadata": {}, "source": ["For now, here\u2019s what you need to know:\n", "\n", "- Keyword arguments have the form `=`.\n", "- Any keyword arguments passed to `print()` must come at the end, after the list of objects to display."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In the following sections, you\u2019ll see how these keyword arguments affect console output produced by `print()`."]}, {"cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["ali....hejazizo\n"]}], "source": ["print('ali', 'hejazizo', sep='....')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### The `sep=` Keyword Argument"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Adding the keyword argument `sep=` causes objects to be separated by the string `` instead of the default single space:"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo 42 bar\n"]}], "source": ["print('foo', 42, 'bar')"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo/42/bar\n"]}], "source": ["print('foo', 42, 'bar', sep='/')"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo...42...bar\n"]}], "source": ["print('foo', 42, 'bar', sep='...')"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo -> 1\n", "bar -> 2\n", "baz -> 3\n"]}], "source": ["d = {'foo': 1, 'bar': 2, 'baz': 3}\n", "for k, v in d.items():\n", " print(k, v, sep=' -> ')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["To squish objects together without any space between them, specify `sep=''`:"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo42bar\n"]}], "source": ["print('foo', 42, 'bar', sep='')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You can specify any arbitrary string as the separator with the `sep=` keyword."]}, {"cell_type": "markdown", "metadata": {}, "source": ["#### The `end=` Keyword Argument\n", "The keyword argument `end=` causes output to be terminated by `` instead of the default newline:"]}, {"cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["foo/42/bar\n"]}], "source": ["if True:\n", " print('foo', end='/')\n", " print(42, end='/')\n", " print('bar')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["For example, if you are displaying values in a loop, you might use `end=` to cause the values to be displayed on one line, rather than on individual lines:"]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n"]}], "source": ["for n in range(10):\n", " print(n)"]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["0\n", "1 2 3 4 5 6 7 8 9 10\n", "11 12 13 14 15 16 17 18 19 20\n", "21 22 23 24 25 26 27 28 29 30\n"]}], "source": ["for n in range(31):\n", " print(n, end=(' ' if n % 10 != 0 else '\\n'))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Any string may be specified as the output terminator with the `end=` keyword."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "### Output Stream Keyword Arguments\n", "`print()` accepts two additional keyword arguments, both of which affect handling of the output stream:\n", "\n", "- `file=`: By default, `print()` sends its output to a default stream called `sys.stdout`, which is usually equivalent to the console. The `file=` argument causes output to be sent to an alternate stream designated by `` instead.\n", "\n", "- `flush=True`: Ordinarily, `print()` buffers its output and only writes to the output stream intermittently. `flush=True` specifies that the output stream is forcibly flushed with each `print()`."]}, {"cell_type": "markdown", "metadata": {}, "source": ["These two keyword arguments are presented here for the sake of completeness. You probably don\u2019t need to be too concerned about output streams at this point. They are discussed later in this series in the section on File I/O."]}, {"cell_type": "markdown", "metadata": {}, "source": ["", "\n", "## Formatted String Output"]}, {"cell_type": "markdown", "metadata": {}, "source": ["`print()` supports formatting of console output that is rudimentary at best. You can choose how to separate printed objects, and you can specify what goes at the end of the printed line. That\u2019s about it."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In many cases, you\u2019ll need more precise control over the appearance of data destined for display. Python provides several ways to format output string data. One of the older ones is the **string modulo operator**."]}, {"cell_type": "markdown", "metadata": {}, "source": ["In recent versions of Python, there are newer ways to format string data that are arguably superior to the string modulo operator: the **string `.format()` method**, and **f-strings**. You will learn about these in the next section in this series."]}], "metadata": {"kernelspec": {"display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10"}}, "nbformat": 4, "nbformat_minor": 4} \ No newline at end of file diff --git a/python/01. Basics/17 Newer Python String Format Techniques.ipynb b/python/01. Basics/17 Newer Python String Format Techniques.ipynb index 2b437d4..efbf26b 100755 --- a/python/01. Basics/17 Newer Python String Format Techniques.ipynb +++ b/python/01. Basics/17 Newer Python String Format Techniques.ipynb @@ -1,4328 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6fc28563", - "metadata": {}, - "source": [ - "# Newer Python String Format Techniques" - ] - }, - { - "cell_type": "markdown", - "id": "aed78bcd", - "metadata": {}, - "source": [ - "The **string modulo operator** is useful, and it’s good for you to be familiar with it because you’re likely to encounter it in older Python code. However, there are two newer ways that you can use Python to format strings that are arguably more preferable." - ] - }, - { - "cell_type": "markdown", - "id": "fa853e41", - "metadata": {}, - "source": [ - "In this section, you’ll learn about:\n", - "\n", - "- The **string `.format()` method**\n", - "- The **formatted string literal**, or **f-string**" - ] - }, - { - "cell_type": "markdown", - "id": "0ad988e6", - "metadata": {}, - "source": [ - "You’ll learn about these formatting techniques in detail and add them to your Python string formatting toolkit. Note that there’s a standard module called string containing a class called `Template`, which provides some `string` formatting through interpolation. The string modulo operator provides more or less the same functionality, so you won’t cover `string.Template` here." - ] - }, - { - "cell_type": "markdown", - "id": "08ad6a1c", - "metadata": {}, - "source": [ - "## The Python String `.format()` Method\n", - "The Python string `.format()` method was introduced in version 2.6. It’s similar in many ways to the string modulo operator, but `.format()` goes well beyond in versatility. The general form of a Python `.format()` call is shown below:\n", - "\n", - "```python\n", - "