├── .gitignore
├── LICENSE.md
├── README.md
├── assets
├── blue_highlight.png
├── green_highlight.png
├── kernel_dropdown.png
├── kernel_dropdown_small.png
├── run_cell.pdf
├── run_cell.png
├── run_cell.svg
└── run_cell_small.png
├── chapter01_introduction
├── practice_questions.ipynb
├── sec01_basic_jupyter.ipynb
├── sec02_literals.ipynb
├── sec03_variables.ipynb
├── sec04_strings.ipynb
├── sec05_numbers_arithmetic.ipynb
├── sec06_boolean_logic.ipynb
└── sec99_intro_recap
├── chapter02_collections
├── .DS_Store
├── practice_questions.ipynb
├── sec01_lists.ipynb
├── sec02_tuples.ipynb
└── sec03_dictionaries.ipynb
├── chapter03_control_flow
├── practice_questions.ipynb
├── sec01_conditionals.ipynb
├── sec02_looping.ipynb
└── sec03_list_comprehensions.ipynb
├── chapter04_functions
└── sec01_functions_basics.ipynb
├── chapter05_classes
└── sec01_classes.ipynb
├── chapter06_numerical
├── sec01_numpy.ipynb
└── sec03_matplotlib.ipynb
├── chapter07_io
├── sec01_writing.ipynb
└── sec02_reading.ipynb
├── cheatsheats
├── python-to-r.ipynb
└── r-numerical.ipynb
└── r-demo
├── R Covidcast Demo.ipynb
├── R_demo.Rmd
├── R_demo.nb.html
└── covidcast_cli_data.csv
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # pyenv
76 | .python-version
77 |
78 | # celery beat schedule file
79 | celerybeat-schedule
80 |
81 | # SageMath parsed files
82 | *.sage.py
83 |
84 | # Environments
85 | .env
86 | .venv
87 | env/
88 | venv/
89 | ENV/
90 | env.bak/
91 | venv.bak/
92 |
93 | # Spyder project settings
94 | .spyderproject
95 | .spyproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
100 | # mkdocs documentation
101 | /site
102 |
103 | # mypy
104 | .mypy_cache/
105 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Everyone is free to download this repository.
2 | Everyone is free to use this repository to learn Python.
3 | Everyone is free to adapt the code examples in this repository for their software projects.
4 | Everyone is free with proper attribution (authorship and link to source) to use the material in any course.
5 |
6 | Packaging or selling the educational materials requires permission from the repository's maintainer, Zachary C. Lipton.
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python, so easy, wow.
2 |
3 | This repo houses a collection of cheat-sheet/tutorials
4 | for teaching the basic concepts Python quickly
5 | and providing a reference when you need a refresher.
6 |
7 | Following my efforts on [Dive into Deep Learning](https://github.com/d2l-ai/d2l-en),
8 | I hope the notebooks in this repository will
9 | make you dangerous in Python as quickly as possible,
10 | while boring you as little as possible.
11 | Sometimes that will mean making tradeoffs along the Pareto-optimal front
12 | between completeness, efficiency, and engagingness.
13 |
14 | Throughout these tutorials we are going to use Python3.
15 | That's mainly because given the choice,
16 | it's better to invest in skills that will be useful
17 | in the foreseeable future.
18 |
19 | These materials are prepared (hopefully!)
20 | with some help from the open source community,
21 | as course materials for the Introduction to Python and R course
22 | as part of the
23 | [MSBA program at Carnegie Mellon University's Tepper School of Business](https://analytics.tepper.cmu.edu/).
24 |
25 | Author: [Zachary C. Lipton](http://zacklipton.com) (& friends)
26 | Contact: [@zacharylipton](https://twitter.com/zacharylipton/)
27 |
28 |
29 | ## Table of contents
30 |
31 | ### Introduction
32 | * [Basic Jupyter](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/sec01_basic_jupyter.ipynb)
33 | * [Literals](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/sec02_literals.ipynb)
34 | * [Variables](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/sec03_variables.ipynb)
35 | * [Strings](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/sec04_strings.ipynb)
36 | * [Numbers (and Arithmetic)](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/sec05_numbers_arithmetic.ipynb)
37 | * [Booleans (and Logic)](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/sec06_boolean_logic.ipynb)
38 | * [Practice Questions](https://github.com/zackchase/python-wow/blob/master/chapter01_introduction/practice_questions.ipynb)
39 |
40 | ### Collections
41 | * [Lists](https://github.com/zackchase/python-wow/blob/master/chapter02_collections/sec01_lists.ipynb)
42 | * [Dictionaries](https://github.com/zackchase/python-wow/blob/master/chapter02_collections/sec02_dictionaries.ipynb)
43 | * [Practice Questions](https://github.com/zackchase/python-wow/blob/master/chapter02_collections/practice_questions.ipynb)
44 |
45 |
46 | ### Control Flow
47 | * [Conditionals (if-then-else)](https://github.com/zackchase/python-wow/blob/master/chapter03_control_flow/sec01_conditionals.ipynb)
48 | * [Looping](https://github.com/zackchase/python-wow/blob/master/chapter03_control_flow/sec02_looping.ipynb)
49 | * [List Comprehensions](https://github.com/zackchase/python-wow/blob/master/chapter03_control_flow/sec03_list_comprehensions.ipynb)
50 | * [Practice Questions](https://github.com/zackchase/python-wow/blob/master/chapter03_control_flow/practice_questions.ipynb)
51 |
52 |
53 | ### Functions
54 | * [Introduction to Functions](https://github.com/zackchase/python-wow/blob/master/chapter04_functions/sec01_functions_basics.ipynb)
55 | * [Practice Questions]()
56 |
57 | ### Classes
58 | * [Introduction to Classes / Object Oriented Programming](https://github.com/zackchase/python-wow/blob/master/chapter05_classes/sec01_classes.ipynb)
59 | * Practice Questions
60 |
61 |
62 |
63 | ### Numerical Python with NumPy and Matplotlib
64 | * [The NumPy Library](https://github.com/zackchase/python-wow/blob/master/chapter06_numerical/sec01_numpy.ipynb)
65 | * [Plotting with Matplotlib](https://github.com/zackchase/python-wow/blob/master/chapter06_numerical/sec03_matplotlib.ipynb)
66 | * Practice Questions
67 |
68 |
69 | ### IO
70 | * [Writing to Files](https://github.com/zackchase/python-wow/blob/master/chapter07_io/sec01_writing.ipynb)
71 | * [Reading from Files](https://github.com/zackchase/python-wow/blob/master/chapter07_io/sec02_reading.ipynb)
72 | * Saving and Loading Python Objects
73 | * Scraping the Web
74 | * Practice Questions
75 |
76 |
77 | ### Python projects
78 | * ...
79 |
--------------------------------------------------------------------------------
/assets/blue_highlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/blue_highlight.png
--------------------------------------------------------------------------------
/assets/green_highlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/green_highlight.png
--------------------------------------------------------------------------------
/assets/kernel_dropdown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/kernel_dropdown.png
--------------------------------------------------------------------------------
/assets/kernel_dropdown_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/kernel_dropdown_small.png
--------------------------------------------------------------------------------
/assets/run_cell.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/run_cell.pdf
--------------------------------------------------------------------------------
/assets/run_cell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/run_cell.png
--------------------------------------------------------------------------------
/assets/run_cell.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/run_cell_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/assets/run_cell_small.png
--------------------------------------------------------------------------------
/chapter01_introduction/practice_questions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Practice Questions on Basics\n",
8 | "\n",
9 | "This notebook contains a bunch of questions aimed at verifying that you know things about literals, variables, strings, ints, floats, and booleans.\n",
10 | "\n",
11 | "## Literals\n",
12 | "\n",
13 | "### Q1 Identify the types of each of the following literals\n",
14 | "```\n",
15 | "\"apple\"\n",
16 | "1\n",
17 | "\"1\"\n",
18 | "1.1\n",
19 | "False\n",
20 | "1.0\n",
21 | "1.1\n",
22 | "\"1.0\"\n",
23 | "True\n",
24 | "None\n",
25 | "```\n",
26 | "\n",
27 | "### Q2 \n",
28 | "\n",
29 | "Add 1 line of code below each comment to perform the tasks specified in the comments:\n",
30 | "\n",
31 | "1. Convert the text in `x` to all caps and print to screen\n",
32 | "2. Convert the text in `y` to all lowercase and print to screen\n",
33 | "3. Concatenate `x` and `y` and print the result to screen\n",
34 | "4. Concatenate `x` and `y` using `+`, adding one space between them and print to screen. \n",
35 | "5. Perform the same task but using Python string formatting with `%`. See examples --- https://www.learnpython.org/en/String_Formatting"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": 1,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "x = \"Miles\"\n",
45 | "y = \"Smiles\"\n",
46 | "\n",
47 | "# 1.\n",
48 | "\n",
49 | "# 2.\n",
50 | "\n",
51 | "# 3.\n",
52 | "\n",
53 | "# 4.\n",
54 | "\n",
55 | "# 5."
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "## Variables\n",
63 | "\n",
64 | "1. Create a variable called \"my_string\" and assign the value \"Miles Davis (Vol. 2)\" to it.\n",
65 | "2. What do you expect to see if you call my_string.upper()?\n",
66 | "3. We just called `.upper()` -- this is function associated with specific object. What is the term for such a function?\n",
67 | "4. After calling `.upper()`, what is the value of the `my_string` variable?\n",
68 | "5. Assign the value reference by `my_string` to a new variable called `new_string`. Now run `my_string = \"Water Babies\"`. Has the value of `new_string` changed? Why or why not?\n",
69 | "\n",
70 | "\n",
71 | "## Casting \n",
72 | "\n",
73 | "1. Create a variable called `x` and assign it the value 3.3\n",
74 | "2. Create a variable called `y` and assign it the value `\"4.2\"`\n",
75 | "4. What datatype is `x`? What data type is `y`?\n",
76 | "3. Can you compose the two together with the `+`? Why or why not?\n",
77 | "5. What do we need to do to, and to which variable, before we can concatenate the two values?\n",
78 | "6. What do we need to do to, and to which variable, before we can *sum* the two values?\n",
79 | "7. For each of the following, can we cast it to a string? \n",
80 | " * \"apple\n",
81 | " * \"4.5\"\n",
82 | " * 9.2\n",
83 | " * 11\n",
84 | " * 2.\n",
85 | "8. For each of the following can we cast it to an int?\n",
86 | " * 3.3\n",
87 | " * 3\n",
88 | " * \"apple\"\n",
89 | "9. For each of the following can we cast it to a float?\n",
90 | " * 3.3\n",
91 | " * 3\n",
92 | " * \"apple\"\n",
93 | "\n",
94 | "\n",
95 | "## Arithmetic\n",
96 | "\n",
97 | "1. Given an integer `x` and integer `y`, what is the type of `x+y`? `x-y`? `x*y`? `x/y`? \n",
98 | "2. Why is type of the division operator different than that of its operands?\n",
99 | "2. Python 2 and many older languages handle integer division differently, truncating the decimal portion of the result. How do we run older-style integer division in Python 3?\n",
100 | "3. Write an expression to perform older-style int division dividing `9` by `25`.\n",
101 | "4. Write an expression using just basic Python to raise 9 to the 5th power.\n",
102 | "5. Do the same but using the `pow` function from the `math` library.\n",
103 | "\n",
104 | "## Boolean logic\n",
105 | "\n",
106 | "1. What are the two allowable Boolean literals? \n",
107 | "2. Assume that `p` and `q` are Python variables taking Boolean values, write Python expressions corresponding to the following the following logic expressions\n",
108 | " * $\\neg p$\n",
109 | " * $p$ AND $q$\n",
110 | " * $p$ OR $q$\n",
111 | " * $p$ XOR $q$\n",
112 | " * $p$ NAND $q$\n",
113 | " \n",
114 | "## General knowledge \n",
115 | "1. What is a programming language?\n",
116 | "2. What is the difference between a compiled and scripted language and which is Python 3? \n",
117 | "3. What are some advantages and disadvantages (in general) of scripted vs compiled languages?\n",
118 | "4. You write a Python program to generate a compiled C program. And you can write a C program that serves as a Python interpreter. Does that mean that all languages are the same? Why or why not?"
119 | ]
120 | }
121 | ],
122 | "metadata": {
123 | "kernelspec": {
124 | "display_name": "Python 3",
125 | "language": "python",
126 | "name": "python3"
127 | },
128 | "language_info": {
129 | "codemirror_mode": {
130 | "name": "ipython",
131 | "version": 3
132 | },
133 | "file_extension": ".py",
134 | "mimetype": "text/x-python",
135 | "name": "python",
136 | "nbconvert_exporter": "python",
137 | "pygments_lexer": "ipython3",
138 | "version": "3.6.5"
139 | }
140 | },
141 | "nbformat": 4,
142 | "nbformat_minor": 2
143 | }
144 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec01_basic_jupyter.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Basic Jupyter\n",
8 | "\n",
9 | "If you've gotten this notebook working in your browser, then you're very close to overcoming the hardest part of all software development: getting the computer turn on, take your code, excecute it, and produce the desired output. [If you're reading this document on GitHub but don't have Jupyter installed, follow these instructions.](http://jupyter.readthedocs.io/en/latest/install.html)\n",
10 | "\n",
11 | "\n",
12 | "To test that you've really gotten this far, click in the code cell below (code cells are indicated with `In [ ]:`). If you click on a cell outside of the textbox, it should turn blue:\n",
13 | "\n",
14 | "\n",
15 | "\n",
16 | "The **blue** border indicates that you are in `Command mode`. On the other hand, if you click inside the textbox, the border should turn **green**:\n",
17 | "\n",
18 | "\n",
19 | "\n",
20 | "Try it out:"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": null,
26 | "metadata": {
27 | "scrolled": true
28 | },
29 | "outputs": [],
30 | "source": [
31 | "message = \"Nǐ hǎo, shìjiè\"\n",
32 | "print(message)"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "You should be able to flip the cell back and forth from green to blue. Once you've selected a cell, you can enter edit mode (green) by pressing `Enter` and you can return to command mode by pressing `Esc`."
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {},
45 | "source": [
46 | "### Executing code\n",
47 | "\n",
48 | "Now you're ready to execute the program. \n",
49 | "Unlike C, Python is an *interpreted* language.\n",
50 | "Recall that for a compiled program,\n",
51 | "we would convert our program into raw machine instructions \n",
52 | "that we can feed directly to our computer's processor. \n",
53 | "With an interpreted language like Python,\n",
54 | "we do not compile the program in advance.\n",
55 | "Instead, we rely on another program, called an interpreter\n",
56 | "which will take our raw code at run time\n",
57 | "and convert it into machine instructions on the fly.\n",
58 | "\n",
59 | "When we launch a Jupyter server,\n",
60 | "we fire up a Python interpreter in the background.\n",
61 | "Each time we *run* a cell, it will take that code\n",
62 | "and feed it to the interpreter. \n",
63 | "Jupyter notebooks actually support multiple \n",
64 | "interpreters, depending on which language \n",
65 | "(or which version of a language) we are running.\n",
66 | "In Jupyter, the interpreter that both runs and allows us \n",
67 | "to introspect our program mid-execution is called a *kernel*.\n",
68 | "For some reason, this definition is often overlooked,\n",
69 | "when Jupyter is introduced, which is annoying \n",
70 | "because the term \"kernel\" is badly overloaded. \n",
71 | "The core part of an operating system which interfaces directly \n",
72 | "with the memory, CPU and devices, is called a \"kernel\",\n",
73 | "the Python interpreter is called a \"kernel\" (as you just learned),\n",
74 | "and once we move on to advanced applications of data science,\n",
75 | "we'll find that the word \"kernel\" often refers \n",
76 | "to a function that computes a dot product in some \n",
77 | "Reproducing Kernel Hilbert Space\n",
78 | "(we'll revisit these topics when discussing ML).\n",
79 | "\n",
80 | "Jupyter supports kernels for many languages, including \n",
81 | "various versions of Julia, Lua, Matlab, Perl, PhP, Python.\n",
82 | "Some of these languages are great, while others \n",
83 | "are horrendous wastes of time that might sap your will to live.\n",
84 | "We'll save the shallow debates about \n",
85 | "best/worst programming languages for another time\n",
86 | "because for the next few weeks I've declared axiomatically\n",
87 | "that the only language you need to worry about is Python 3.\n",
88 | "To make sure that Jupyter is using the Python 3 kernel\n",
89 | "to execute your code, select it from the Kernel dropdown:\n",
90 | "\n",
91 | "\n",
92 | "\n",
93 | "Running code is simple. Just select the cell you want to execute.\n",
94 | "Now you have three main choices. If you prefer the visual interface, \n",
95 | "hit the \"Run\" button above:\n",
96 | "\n",
97 | "\n",
98 | "\n",
99 | "Try it out below"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": null,
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "message = \"Nǐ hǎo, shìjiè\"\n",
109 | "print(message)"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "If everything worked, then you should see `Nǐ hǎo, shìjiè`\n",
117 | "printed just below your code block. \n",
118 | "You just ran your first program! \n",
119 | "Eventually you'll probably get tired \n",
120 | "of having to move your mouse \n",
121 | "every time you want to execute a cell. \n",
122 | "\n",
123 | "As a result, I recommend memorizing the following two-key sequences:\n",
124 | " * `CTRL+Enter` will run a cell and keep focus on that same cell.\n",
125 | " * `Shift+Enter` will run a cell and move focus to the next cell.\n",
126 | " * `Option+Enter` will run a cell and then move focus to a *new* cell \n",
127 | "inserted immediately below the one you just ran."
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {},
133 | "source": [
134 | "### Printing variables\n",
135 | "\n",
136 | "One last detail before we move on. \n",
137 | "You might have noticed that instead of \n",
138 | "the usual `print(\"Hello, world!\")` program, \n",
139 | "we did a couple things differently. \n",
140 | "First, we printed the message in phonetic Chinese \n",
141 | "to avoid the monotony of writing \"Hello, world\" yet again.\n",
142 | "But more importantly, we first wrote our message \n",
143 | "to a variable called `message`. \n",
144 | "We then printed the message:\n",
145 | "\n",
146 | "```\n",
147 | "message = \"Nǐ hǎo, shìjiè\"\n",
148 | "print(message)\n",
149 | "```\n",
150 | "\n",
151 | "As you can see, that's not actually necessary.\n",
152 | "We could have just passed the string literal\n",
153 | "directly to the print statement."
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": null,
159 | "metadata": {},
160 | "outputs": [],
161 | "source": [
162 | "print(\"Nǐ hǎo, shìjiè\")"
163 | ]
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "A variable is just a placeholder where we can store arbitrary data, \n",
170 | "in this case a text string. \n",
171 | "We'll get more into precisely what variables \n",
172 | "and various data types are in the next notebook. \n",
173 | "But we snuck it in early here show off \n",
174 | "three more aspects of how Jupyter notebooks work.\n",
175 | "\n",
176 | "First, notice that variables, once assigned, \n",
177 | "persist across notebook cells. \n",
178 | "So if we take the variable `message` defined above, \n",
179 | "we can print it again without having to define it again:"
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {},
186 | "outputs": [],
187 | "source": [
188 | "print(message)"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "### Quickly printing objects\n",
196 | "Note that if we put a variable name as the last line of a codeblock,\n",
197 | "Jupyter will assume that we want to print it to the screen."
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {},
204 | "outputs": [],
205 | "source": [
206 | "a = 10\n",
207 | "b = 11\n",
208 | "c = 12\n",
209 | "b"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {},
215 | "source": [
216 | "Third, **Jupyter doesn't care in what order the blocks appear in the notebook**. \n",
217 | "It only **in what order the cells are run.** \n",
218 | "We can test this by running the cells below. \n",
219 | "If you run them in the order that they appear,\n",
220 | "you should get an error: ``NameError: name 'message_chinese' is not defined``. \n",
221 | "If you run the second cell first, \n",
222 | "then everything should go smoothly."
223 | ]
224 | },
225 | {
226 | "cell_type": "code",
227 | "execution_count": null,
228 | "metadata": {},
229 | "outputs": [],
230 | "source": [
231 | "print(message_chinese)"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {},
238 | "outputs": [],
239 | "source": [
240 | "message_chinese = \"你好,世界\""
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {},
246 | "source": [
247 | "### The `print` function\n",
248 | "\n",
249 | "Before moving on we might quickly address \n",
250 | "what's going on with these `print` instructions. \n",
251 | "The command `print(\"Hello\")` takes a value (`\"Hello\"`) \n",
252 | "and prints it to the screen. \n",
253 | "If you put this print statement in a script \n",
254 | "and then run it from the terminal, \n",
255 | "the program will output `\"Hello\"` right on the command line. \n",
256 | "\n",
257 | "Here `print` is an example of a function. \n",
258 | "Functions (often called subroutines, e.g. [in Wikipedia](https://en.wikipedia.org/wiki/Subroutine)),\n",
259 | "are blocks of instructions that we want to execute many times.\n",
260 | "Thus we define them one time then reference them later\n",
261 | "from arbitrary parts of our program whenever we want to *invoke* them. \n",
262 | "Some functions are so broadly useful that we may want to distribute them \n",
263 | "in *libraries* so that other programs acan *import* them.\n",
264 | "And a few functions, including `print` are so useful\n",
265 | "that they are baked directly into the programming language itself.\n",
266 | "\n",
267 | "\n",
268 | "We'll teach you all the steps to define your own functions \n",
269 | "when we get to that portion of the tutorial,\n",
270 | "but basically functions take some input (optionally none),\n",
271 | "execute a set of instructions (some lines of code),\n",
272 | "and then produce some output (optionally none).\n",
273 | "\n",
274 | "One tricky thing about teaching programming is that\n",
275 | "it's pedagogically natural to teach basic data types\n",
276 | "operations and program structures like loops and conditionals\n",
277 | "before progressing on to teach functions and objects. \n",
278 | "At the same time, in Python, we can't avoid\n",
279 | "at least using (if not defining) functions from the outset\n",
280 | "and we also can't avoid using objects. \n",
281 | "Indeed everything in Python is an *object*, even functions!\n",
282 | "We'll elaborate more on that later.\n",
283 | "\n",
284 | "Here, we've been passing the `print` function text strings \n",
285 | "and it has been executing code to print that text to the screen. \n",
286 | "The `print` function **does not return any values**, \n",
287 | "but it's very flexible in what kinds of values it takes as input:\n",
288 | "numbers, variables, lists, and more complex objects.\n",
289 | "We've only been using `print` so far to print *string literals*.\n",
290 | "In the coming sections, we'll go deeper into what a literal means,\n",
291 | "how functions work, and how to define our own functions. \n",
292 | "\n",
293 | "## Comments\n",
294 | "\n",
295 | "When we write code, we sometimes need to explain what we're doing. \n",
296 | "The process or clearly explaining the purpose of each component \n",
297 | "of the code is generally called documentation.\n",
298 | "\n",
299 | "We can add documentation to code by using *comments*, \n",
300 | "lines of text that will be visible to other programmers\n",
301 | "but which the Python interpreter will ignore.\n",
302 | "In Python, we mark comments with the pound symbol `#`"
303 | ]
304 | },
305 | {
306 | "cell_type": "code",
307 | "execution_count": null,
308 | "metadata": {},
309 | "outputs": [],
310 | "source": [
311 | "# This is a commennt\n",
312 | "# Every line preceded by a \"#\" \n",
313 | "# ... will not execute"
314 | ]
315 | },
316 | {
317 | "cell_type": "markdown",
318 | "metadata": {},
319 | "source": [
320 | "The previous block of code will not produce any output. \n",
321 | "Moreover, Python won't do any processing,\n",
322 | "besides whatever small amount of parsing is required \n",
323 | "to ingest the comment and ignore it.\n",
324 | "\n",
325 | "## Markdown\n",
326 | "Jupyter notebooks are not just code editors in the web browser.\n",
327 | "They give us an interactive environment for running and writing code,\n",
328 | "for visualizing data, and for explaining ideas in a pedagogical context.\n",
329 | "Accordingly, they let us write formatted text\n",
330 | "using a stripped-down markup language called Markdown. \n",
331 | "This cell is written in Markdown.\n",
332 | "It's not difficult to find Markdown cheatsheets on the Internet. \n",
333 | "[Here's one that I sometimes refer to](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).\n",
334 | "To flip your cell between markdown and code, \n",
335 | "either select the `Cell>Cell Type>Markdown` \n",
336 | "or `Cell>Cell Type>Code` from the dropdowns, respectively, \n",
337 | "or hit `ESC + M` or `ESC + Y` while in command mode, respectively,\n",
338 | "(not capitalized, just the key).\n",
339 | "\n"
340 | ]
341 | }
342 | ],
343 | "metadata": {
344 | "kernelspec": {
345 | "display_name": "Python 3",
346 | "language": "python",
347 | "name": "python3"
348 | },
349 | "language_info": {
350 | "codemirror_mode": {
351 | "name": "ipython",
352 | "version": 3
353 | },
354 | "file_extension": ".py",
355 | "mimetype": "text/x-python",
356 | "name": "python",
357 | "nbconvert_exporter": "python",
358 | "pygments_lexer": "ipython3",
359 | "version": "3.7.4"
360 | }
361 | },
362 | "nbformat": 4,
363 | "nbformat_minor": 2
364 | }
365 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec02_literals.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Literals \n",
8 | "\n",
9 | "If you've already learned any other program language, \n",
10 | "then you've probably come across the terms *literal* and *variable*.\n",
11 | "These concepts are so fundamental that many resources \n",
12 | "assume that you already know what they mean.\n",
13 | "It's not really so much extra effort to unpack these basic ideas, \n",
14 | "so let's do it right here.\n",
15 | "As we noted in the previous notebook, some Python concepts, \n",
16 | "like objects, despite being conceptually more advanced than primitive data types\n",
17 | "are baked to every fiber of the language, including literals,\n",
18 | "so it may seem at times that we are being a bit circular---just \n",
19 | "hang in and we will try not add any more confusion than necessary.\n",
20 | "\n",
21 | "## Literals\n",
22 | "In Python a *literal* is a way of expressing an object \n",
23 | "directly in the syntax of the programming language.\n",
24 | "Usually this is some primitive piece of data, \n",
25 | "like a *number*, *string* (of text), or *Boolean* (True/False) value.\n",
26 | "It's also possible to express more complex objects, \n",
27 | "such as collection of values (e.g. lists and dictionaries) as literals. \n",
28 | "We will get to collections in a subsequent notebook\n",
29 | "and focus our attention on primitive data types here.\n",
30 | "Let's go back to our running example, a silly program \n",
31 | "that just prints text to the screen."
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {},
38 | "outputs": [],
39 | "source": [
40 | "print(\"hello\")"
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "Here `\"hello\"` is called a string literal. \n",
48 | "It's called a \"literal\" because we *literally* \n",
49 | "just stuck the value right there in the code.\n",
50 | "The word *literally* means \"actually\", \"exactly\", \n",
51 | "\"precisely\", \"really\", or \"truly\", and \n",
52 | "that's why we call this kind sort of expression a literal. \n",
53 | "Being a literal doesn't depend on the specific value\n",
54 | "but rather the practice of hard-coding \n",
55 | "a specific value directly into our program. \n",
56 | "The Chinese version:"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": null,
62 | "metadata": {},
63 | "outputs": [],
64 | "source": [
65 | "print(\"你好\")"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "should also be described as using a *literal* in precisely the same way.\n",
73 | "The values `5`, `5.1`, `7e-10`, `True`, and `False` are also literals."
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": [
82 | "print(5, type(5))\n",
83 | "print(5.1, type(5))\n",
84 | "print(7e-10, type(7e-10))\n",
85 | "print(True, type(True))\n",
86 | "print(False, type(False))"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "### String Literals\n",
94 | "\n",
95 | "Strings, which we have already encountered are just one data type, \n",
96 | "specifically the kind that we use to represent text.\n",
97 | "We create a string literal in Python by enclosing a string of text\n",
98 | "with quotation marks. The quotation marks indicate to Python\n",
99 | "that the string is part of a literal \n",
100 | "and not part of our programs code.\n",
101 | "\n",
102 | "We can mark literals in the following ways:\n",
103 | " 1. by marking them with single quotation marks"
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": null,
109 | "metadata": {},
110 | "outputs": [],
111 | "source": [
112 | "print('Hello')"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {},
118 | "source": [
119 | " 2. By marking them with double quotation marks"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": null,
125 | "metadata": {},
126 | "outputs": [],
127 | "source": [
128 | "print(\"Hello\")"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | " 3. And finally, by marking them with triple quotation marks. Triple quotation marks are useful for because they allow us to write multi-line strings."
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {},
142 | "outputs": [],
143 | "source": [
144 | "print(\"\"\"\n",
145 | "Hello, check this out:\n",
146 | "This is a two-line string\n",
147 | "\"\"\")"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "## Numeric Literals\n",
155 | "\n",
156 | "Literals are not restricted to strings. We can also present numbers as literals:"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "print(42)"
166 | ]
167 | },
168 | {
169 | "cell_type": "code",
170 | "execution_count": null,
171 | "metadata": {},
172 | "outputs": [],
173 | "source": [
174 | "print(4.2)"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "There are three main kinds of numbers built in to Python: \n",
182 | "integers (ints), floating point numbers (floats), and complex numbers. \n",
183 | "In the next notebook, we'll get more specific about what a *type* means. \n",
184 | "For now we'll focus on giving some intuition. \n",
185 | "\n",
186 | "### Integer Literals\n",
187 | "\n",
188 | "Integers are the numbers, e.g. $14$, \n",
189 | "that can be written without a fractional component.\n",
190 | "Formally they are the set containing zero ($0$),\n",
191 | "the positive counting numbers ($1,2, ... $), \n",
192 | "and their negative counterparts ($-1, -2, ...$).\n",
193 | "Python will typically assume that any number without a decimal \n",
194 | "is an integer (so `14.28` is *NOT* an integer)\n",
195 | "and that any number with a decimal or in scientific notation is a `float`.\n",
196 | "\n",
197 | "The Python data type corresponding to the mathematical concept \n",
198 | "of an integer is denoted by `int`.\n",
199 | "We can tell that Python thinks that `7` is an `int` in two ways.\n",
200 | "First we'll notice that if we call `print` on it, \n",
201 | "Python prints a number with no fractional component:"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "metadata": {},
208 | "outputs": [],
209 | "source": [
210 | "print(7)"
211 | ]
212 | },
213 | {
214 | "cell_type": "markdown",
215 | "metadata": {},
216 | "source": [
217 | "Second, Python gives us a way to directly \n",
218 | "inspect the type of any object:\n",
219 | "by calling the `type` function on it.\n",
220 | "\n",
221 | "Again we're calling a function even though we haven't really \n",
222 | "gotten into the anatomy of what precisely a function is or how to define onw.\n",
223 | "For now, just hang in and suffice it to say \n",
224 | "that a function takes some input (or possibly no input at all!),\n",
225 | "and executes some operations on your computer in the background\n",
226 | "(say, writing to or reading from a file), \n",
227 | "and finally returning some value (or possibly none at all!).\n",
228 | "\n",
229 | "Recall that we've already been working with one function: `print`. \n",
230 | "This function takes an input, but returns nothing. \n",
231 | "The full picture is a bit complex but that shouldn't worry us now. \n",
232 | "For now, just know that *invoke* a function `func`\n",
233 | "and want to pass it an input, let's call the input `value`, \n",
234 | "the appropriate syntax is `func(value)`. \n",
235 | "Now let's put this lesson to practice by invoking the type function:"
236 | ]
237 | },
238 | {
239 | "cell_type": "code",
240 | "execution_count": null,
241 | "metadata": {},
242 | "outputs": [],
243 | "source": [
244 | "print(type(7))"
245 | ]
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {},
250 | "source": [
251 | "**Side note:** An attentive reader be wondering \n",
252 | "what sort of object does the `type` function return? \n",
253 | "We can check this easily by running:"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {},
260 | "outputs": [],
261 | "source": [
262 | "print(type(type(7)))"
263 | ]
264 | },
265 | {
266 | "cell_type": "markdown",
267 | "metadata": {},
268 | "source": [
269 | "Sure enough, the type of a *type*, is ... *type*! \n",
270 | "Let's move on lest things get too meta before you've learned the ABCs.\n",
271 | "\n",
272 | "\n",
273 | "### Float Literals\n",
274 | "\n",
275 | "If you're following up until now then floating point numbers will be easy. \n",
276 | "Similarly, we'll use `float` to differentiate the Python data type \n",
277 | "from the more general concept of continous numbers. \n",
278 | "We can make a floating point literal by using a decimal:"
279 | ]
280 | },
281 | {
282 | "cell_type": "code",
283 | "execution_count": null,
284 | "metadata": {},
285 | "outputs": [],
286 | "source": [
287 | "print(14.28)\n",
288 | "print(type(14.28))"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "Note that Python doesn't care if we add trailing zeros.\n",
296 | "In other words, `7.1`, `7.10`, and `7.100` are all the same:"
297 | ]
298 | },
299 | {
300 | "cell_type": "code",
301 | "execution_count": null,
302 | "metadata": {},
303 | "outputs": [],
304 | "source": [
305 | "print(7.1)\n",
306 | "print(7.10)\n",
307 | "print(7.100)"
308 | ]
309 | },
310 | {
311 | "cell_type": "markdown",
312 | "metadata": {},
313 | "source": [
314 | "It's important to note that the presence or lack a decimal matters, \n",
315 | "it makes the difference between Python reading a number literal as an `int` or a `float`:"
316 | ]
317 | },
318 | {
319 | "cell_type": "code",
320 | "execution_count": null,
321 | "metadata": {},
322 | "outputs": [],
323 | "source": [
324 | "print(4, type(4))\n",
325 | "print(4., type(4.))"
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {},
331 | "source": [
332 | "## Boolean literal\n",
333 | "\n",
334 | "Python has a few other kinds of data types. \n",
335 | "One of the simplest kinds of data types is the Boolean value.\n",
336 | "These correpsond to two values that can be taken by any logical predicate:\n",
337 | "`True` and `False`. \n",
338 | "These will prove especially useful once \n",
339 | "we start talking working with if-then statements."
340 | ]
341 | },
342 | {
343 | "cell_type": "code",
344 | "execution_count": null,
345 | "metadata": {},
346 | "outputs": [],
347 | "source": [
348 | "print(True, type(True))\n",
349 | "print(False, type(False))"
350 | ]
351 | }
352 | ],
353 | "metadata": {
354 | "kernelspec": {
355 | "display_name": "Python 3",
356 | "language": "python",
357 | "name": "python3"
358 | },
359 | "language_info": {
360 | "codemirror_mode": {
361 | "name": "ipython",
362 | "version": 3
363 | },
364 | "file_extension": ".py",
365 | "mimetype": "text/x-python",
366 | "name": "python",
367 | "nbconvert_exporter": "python",
368 | "pygments_lexer": "ipython3",
369 | "version": "3.7.4"
370 | }
371 | },
372 | "nbformat": 4,
373 | "nbformat_minor": 2
374 | }
375 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec03_variables.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Variables\n",
8 | "\n",
9 | "Now that you have a grasp on *literals*, \n",
10 | "it's worth asking---how else can we refer \n",
11 | "to objects besides hard-coding the values as literals?\n",
12 | "If all values manipulated in a program were *literals*,\n",
13 | "Then it would be rather difficult \n",
14 | "to make programs that behaved differntly\n",
15 | "in different situations. \n",
16 | "All of the values that they needed to access \n",
17 | "would be hard-coded in our program's instructions. \n",
18 | "Programming would be like using a calculator. \n",
19 | "Every program would run the same way every time \n",
20 | "because all the values were hard-coded!\n",
21 | "\n",
22 | "One alternative is to store values in *variables*.\n",
23 | "This simple abstraction is going to make it easy \n",
24 | "to write flexible, complex programs.\n",
25 | "A variable is simply a placeholder that allows us\n",
26 | "to work with symbols that point to values \n",
27 | "rather than with the values themselves. \n",
28 | "\n",
29 | "## Assignment\n",
30 | "\n",
31 | "In programming, ***assignment*** refers to the act \n",
32 | "of associating a *value* with a specific *variable*. \n",
33 | "The assigned value here could be a literal,\n",
34 | "but we could also be passing along the value \n",
35 | "already associated with a different variable.\n",
36 | "Rather than sucking up too much air talking about assignment, \n",
37 | "let's just go ahead and do it first:"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {},
44 | "outputs": [],
45 | "source": [
46 | "my_variable = \"Hello\""
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {},
52 | "source": [
53 | "So what happened here? Basically,\n",
54 | "you can think of the assignment operator `=`\n",
55 | "as a procedure that works as follows:\n",
56 | " * First, it evaluates the expression on the right hand side (RHS) of the assignment operator `=` (in this case, it is simply the *literal* `\"Hello\"`).\n",
57 | " * Second, it associates that value with the variable whose name is given on the left-hand side (LHS), here `my_variable`.\n",
58 | "\n",
59 | "Note that unlike in some other languages,\n",
60 | "the variable on the left hand side \n",
61 | "need not already be declared in our program.\n",
62 | "If we place any valid variable name (cannot be a Python reserved word),\n",
63 | "then Python will create a new variable \n",
64 | "if one with this name doesn't already exist.\n",
65 | " \n",
66 | "Once the assignment of the value to the variable has executed, \n",
67 | "we can subsequently access the value \n",
68 | "via the associated variable `my_variable`.\n",
69 | "Thus we need not copy the same literal throughout the code redundantly."
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {},
76 | "outputs": [],
77 | "source": [
78 | "print(my_variable)"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "## Cutting down on redundancy\n",
86 | "Imagine, for example, that we wanted to greet several people. "
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "print(\"Hello\", \"Alex\")\n",
96 | "print(\"Hello\", \"Bob\")\n",
97 | "print(\"Hello\", \"Courtney\")\n",
98 | "print(\"Hello\", \"Dasha\")\n",
99 | "print(\"Hello\", \"Elouise\")\n",
100 | "print(\"Hello\", \"Fanny\")\n",
101 | "print(\"Hello\", \"Gal\")"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "If we now wanted to change our program \n",
109 | "to use the more colloquial greeting \"Yo\",\n",
110 | "we would have to edit every line in the program.\n",
111 | "If instead we had assigned the greeting to a variable, \n",
112 | "we would only have to change one line.\n",
113 | "Experiment below by changing the greeting."
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {},
120 | "outputs": [],
121 | "source": [
122 | "greeting = \"Yo\"\n",
123 | "print(greeting, \"Alex\")\n",
124 | "print(greeting, \"Bob\")\n",
125 | "print(greeting, \"Courtney\")\n",
126 | "print(greeting, \"Dasha\")\n",
127 | "print(greeting, \"Elouise\")\n",
128 | "print(greeting, \"Fanny\")\n",
129 | "print(greeting, \"Gal\")"
130 | ]
131 | },
132 | {
133 | "cell_type": "markdown",
134 | "metadata": {},
135 | "source": [
136 | "As we discussed above, unlike in some other languages,\n",
137 | "we didn't have to do anything special \n",
138 | "to allocate the memory that `my_variable` requires. \n",
139 | "We also didn't need to specify in advance \n",
140 | "what *type* `my_variable` should store.\n",
141 | "\n",
142 | "Also, you needn't assign a variable \n",
143 | "by providing a literal on the RHS. \n",
144 | "For starters, we can use another variable. \n",
145 | "Let's assign the content of `my_variable` to `my_other_variable`."
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {},
152 | "outputs": [],
153 | "source": [
154 | "my_other_variable = my_variable\n",
155 | "print(my_other_variable)"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "This allows us to write complex piece of software \n",
163 | "that can act on any of a range of inputs.\n",
164 | "We can define the inputs at the top of the program,\n",
165 | "or pass them in as command line arguments,\n",
166 | "or even solicit them interactively,\n",
167 | "by using the `input` function \n",
168 | "(this tends to be more useful for a command line script than in Jupyter)."
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": null,
174 | "metadata": {},
175 | "outputs": [],
176 | "source": [
177 | "age = input(\"What's your age?\")\n",
178 | "print(\"Your age is:\", age)"
179 | ]
180 | },
181 | {
182 | "cell_type": "markdown",
183 | "metadata": {},
184 | "source": [
185 | "### Re-assignment\n",
186 | "\n",
187 | "One natural question might be whether, \n",
188 | "once we assign a value to a variable, \n",
189 | "we can change the value of that variable.\n",
190 | "Some languages mainly functional programming languages like Haskell,\n",
191 | "which are very popular among programming languages professors\n",
192 | "but not widely used by ordinary humans do not permit this.\n",
193 | "While Python incorporates some ideas functional programming,\n",
194 | "in general, people use Python in the imperative style,\n",
195 | "which means, among other things, \n",
196 | "that we can *mutate* the values of variables.\n",
197 | "\n",
198 | "To mutate the value of `my_variable`, \n",
199 | "we can simply execute another assignment:"
200 | ]
201 | },
202 | {
203 | "cell_type": "code",
204 | "execution_count": null,
205 | "metadata": {},
206 | "outputs": [],
207 | "source": [
208 | "my_variable = \"你好\"\n",
209 | "print(\"my_variable: \", my_variable)\n",
210 | "print(\"my_other_variable: \", my_other_variable)"
211 | ]
212 | },
213 | {
214 | "cell_type": "markdown",
215 | "metadata": {},
216 | "source": [
217 | "Notice that updating `my_variable` did not change \n",
218 | "the value of `my_other_variable` which had already been assigned. \n",
219 | "This is an important behavior to take notice of. \n",
220 | "In general, assigning variables to other variables \n",
221 | "will lead to *making a copy* \n",
222 | "when the passed value is a primitive type. \n",
223 | "However, things will get more complicated \n",
224 | "when we start talking about other more complicated objects. \n",
225 | "\n",
226 | "## What can be a variable?\n",
227 | "You might be wondering just what can be stored in a variable? \n",
228 | "So far we've only stuck strings in variables. \n",
229 | "In short, any Python object can be referenced by a variable.\n",
230 | "And nearly everything in Python is an object! \n",
231 | "\n",
232 | "We can store numbers in variables:"
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": null,
238 | "metadata": {},
239 | "outputs": [],
240 | "source": [
241 | "x = 5\n",
242 | "y = 8 \n",
243 | "print(x + y)"
244 | ]
245 | },
246 | {
247 | "cell_type": "markdown",
248 | "metadata": {},
249 | "source": [
250 | "We can store Booleans in variables:"
251 | ]
252 | },
253 | {
254 | "cell_type": "code",
255 | "execution_count": null,
256 | "metadata": {},
257 | "outputs": [],
258 | "source": [
259 | "p = True\n",
260 | "q = False\n",
261 | "print(p and q)"
262 | ]
263 | },
264 | {
265 | "cell_type": "markdown",
266 | "metadata": {},
267 | "source": [
268 | "And we can even assign functions to variables!"
269 | ]
270 | },
271 | {
272 | "cell_type": "code",
273 | "execution_count": null,
274 | "metadata": {},
275 | "outputs": [],
276 | "source": [
277 | "zacks_print_function = print\n",
278 | "zacks_print_function(\"Finally, a more elegantly named print function.\")\n",
279 | "zacks_print_function(my_variable, my_other_variable)\n",
280 | "zacks_print_function(x+y)\n",
281 | "zacks_print_function(p and q)"
282 | ]
283 | },
284 | {
285 | "cell_type": "markdown",
286 | "metadata": {},
287 | "source": [
288 | "## Naming Variables \n",
289 | "\n",
290 | "There are a few naming conventions in Python.\\\n",
291 | "Some of these are rules and others are just stylistic guidelines \n",
292 | "that prevent your code from looking ridiculous.\n",
293 | "\n",
294 | " 1. Variable names should be lower-cased.\n",
295 | " 1. Each name should start with a letter or sometimes an underscore, but never a number."
296 | ]
297 | }
298 | ],
299 | "metadata": {
300 | "kernelspec": {
301 | "display_name": "Python 3",
302 | "language": "python",
303 | "name": "python3"
304 | },
305 | "language_info": {
306 | "codemirror_mode": {
307 | "name": "ipython",
308 | "version": 3
309 | },
310 | "file_extension": ".py",
311 | "mimetype": "text/x-python",
312 | "name": "python",
313 | "nbconvert_exporter": "python",
314 | "pygments_lexer": "ipython3",
315 | "version": "3.7.4"
316 | }
317 | },
318 | "nbformat": 4,
319 | "nbformat_minor": 2
320 | }
321 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec04_strings.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Strings\n",
8 | "\n",
9 | "We've been playing around with strings in the previous notebooks. \n",
10 | "We'll briefly go through a grab-bag of things we can do with strings.\n",
11 | "\n",
12 | "For these examples we'll work with the following strings:"
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": null,
18 | "metadata": {},
19 | "outputs": [],
20 | "source": [
21 | "string1 = \"This is my string! It belongs to ME!\"\n",
22 | "string2 = \"And this string belongs to you!\""
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "### Calculating length"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": null,
35 | "metadata": {},
36 | "outputs": [],
37 | "source": [
38 | "print(len(string1))\n",
39 | "print(len(string2))\n",
40 | "\n",
41 | "string3 = \"fdsnjksfdj\""
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "## Concatenation \n",
49 | "\n",
50 | "Concatenation is a name for the operation \n",
51 | "where we append one string to the end of another, \n",
52 | "yielding a new, longer string."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "string1 = \"Helm, warp one -- \"\n",
62 | "string2 = \"Engage!\"\n",
63 | "string3 = string1 + string2\n",
64 | "\n",
65 | "print(\"string1: \", string1)\n",
66 | "print(\"string2: \", string2)\n",
67 | "print(\"string3: \", string3)"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "Whenever we concatenate two strings, \n",
75 | "the resulting string will have a length \n",
76 | "equal to the sum of the substrings from which it was formed. "
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {},
83 | "outputs": [],
84 | "source": [
85 | "print(len(string1))\n",
86 | "print(len(string2))\n",
87 | "print(len(string3))\n",
88 | "print(len(string1) + len(string2))"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "## String Methods\n",
96 | "\n",
97 | "We'll get more into how objects work in subsequent chapters \n",
98 | "but it's time you learned that objects are associated \n",
99 | "with some functionality by means of *methods*. \n",
100 | "Methods are basically functions that act upon a given object.\n",
101 | "We can invoke an object's methods with syntax \n",
102 | "that looks like this: `object.method_name()`. \n",
103 | "Just as we can provide inputs (also called arguments) \n",
104 | "to an ordinary function, e.g. `print(string1, string2)`,\n",
105 | "some methods require that we supply arguments. \n",
106 | "\n",
107 | "Strings come bundled with a few helpful methods.\n",
108 | "The following handy methods don't require any arguments:\n",
109 | "We can flip all alphabetic characters \n",
110 | "to either *upper* or *lower* or *title* (capitalized initials)\n",
111 | "by calling the `.upper()`, `.lower()`, or `.title()` methods, \n",
112 | "respectively (all three leave numeric and special characters unaltered)."
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {},
119 | "outputs": [],
120 | "source": [
121 | "print(\"regular: \\t\", string3)\n",
122 | "print(\"upper: \\t \\t\", string3.upper())\n",
123 | "print(\"lower: \\t \\t\", string3.lower())\n",
124 | "print(\"title: \\t \\t\", string3.title())\n",
125 | "print(\"original: \\t\", string3)"
126 | ]
127 | },
128 | {
129 | "cell_type": "markdown",
130 | "metadata": {},
131 | "source": [
132 | "Note that calling the method did not change the original string.\n",
133 | "In other words, `.upper()` is a function\n",
134 | "that returns a new string (that is all upper cased),\n",
135 | "while leaving the underlying object unchanged. \n",
136 | "We can see this clearly here:"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": null,
142 | "metadata": {},
143 | "outputs": [],
144 | "source": [
145 | "upper_string = string3.upper()\n",
146 | "print(string3)\n",
147 | "print(upper_string)\n",
148 | "print(type(upper_string))"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {},
154 | "source": [
155 | "In fact, note that strings are immutable. \n",
156 | "Thus while we can convert a string into various\n",
157 | "other related strings, we can never alter the underlying string. \n",
158 | "We can even reassign a variable that once pointed at a given string\n",
159 | "to subsequently point at a new string, but this isn't the same thing\n",
160 | "as mutating a string.\n",
161 | "\n",
162 | "Note that `upper_string` has no idea \n",
163 | "that it was produced by setting `string3` to upper case. \n",
164 | "All trace of the original capitalziation scheme is lost.\n",
165 | "As far as it's concerned, `upper_string` is \n",
166 | "just an ordinary string that happens to contain capital letters."
167 | ]
168 | },
169 | {
170 | "cell_type": "markdown",
171 | "metadata": {},
172 | "source": [
173 | "## Escape Sequences\n",
174 | "\n",
175 | "For certain special characters we can't \n",
176 | "just express them in a string literal.\n",
177 | "We need to use an escape sequence. \n",
178 | "One example is the newline character.\n",
179 | "To express a newline in a string literal,\n",
180 | "we can't actually put a newline in the middle of the code.\n",
181 | "Instead, we use \"\\n\"."
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "metadata": {},
188 | "outputs": [],
189 | "source": [
190 | "print(\"a\\nb\\nc\")"
191 | ]
192 | },
193 | {
194 | "cell_type": "markdown",
195 | "metadata": {},
196 | "source": [
197 | "Similarly `\"\\t\"` indicates a horizontal tab,\n",
198 | "`\"\\\\\"` indicates a backslash, and `\\\"` represents a double quote.\n",
199 | "Note that we only need to escape double quotes \n",
200 | "inside a double-quote-enclosed string literal.\n",
201 | "Likewise, we only need to escape single quotes\n",
202 | "inside a single-quote-enclosed string literal.\n",
203 | "However, either kind of quotation mark\n",
204 | "*can* be indicated via an escape sequence,\n",
205 | "regardless of whether the string is double- or single-quote-enclosed. "
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": null,
211 | "metadata": {},
212 | "outputs": [],
213 | "source": [
214 | "print('\\\"')\n",
215 | "print('\"')\n",
216 | "print(\"\\\"\")"
217 | ]
218 | }
219 | ],
220 | "metadata": {
221 | "kernelspec": {
222 | "display_name": "Python 3",
223 | "language": "python",
224 | "name": "python3"
225 | },
226 | "language_info": {
227 | "codemirror_mode": {
228 | "name": "ipython",
229 | "version": 3
230 | },
231 | "file_extension": ".py",
232 | "mimetype": "text/x-python",
233 | "name": "python",
234 | "nbconvert_exporter": "python",
235 | "pygments_lexer": "ipython3",
236 | "version": "3.7.4"
237 | }
238 | },
239 | "nbformat": 4,
240 | "nbformat_minor": 2
241 | }
242 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec05_numbers_arithmetic.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Numbers\n",
8 | "\n",
9 | "Now let's take a deeper look at how to work with numbers. \n",
10 | "Recall that Python supports `int`, `float` and `complex` number types.\n",
11 | "\n",
12 | "\n",
13 | "## Arithmetic\n",
14 | "To begin let's briefly introduce the basic arithmetic operators:"
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "x = 5\n",
24 | "y = 8\n",
25 | "\n",
26 | "# Basic Debugging\n",
27 | "print(\"x \\t\\t\\t\", type(x), x)\n",
28 | "print(\"y \\t\\t\\t\", type(y), y)\n",
29 | "\n",
30 | "# Addition\n",
31 | "result = x + y\n",
32 | "print('Addition:', 'x + y \\t', type(result), result)\n",
33 | "\n",
34 | "# Subtraction\n",
35 | "result = x - y\n",
36 | "print('Subtraction:', 'x - y \\t', type(result), result)\n",
37 | "\n",
38 | "# Multiplication\n",
39 | "result = x * y\n",
40 | "print('Multiplication:', 'x * y \\t', type(result), result)\n",
41 | "\n",
42 | "# Division\n",
43 | "result = x / y\n",
44 | "print('Division:', 'x / y \\t', type(result), result)\n",
45 | "\n",
46 | "# Exponentiation\n",
47 | "result = x ** y\n",
48 | "print('Exponentiation:', 'x ** y \\t', type(result), result)"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "Note that when we compose together two `int`s \n",
56 | "with most basic arithemtic operators, the results are integers. \n",
57 | "However, if we divide two `int`s, the result is a `float`.\n",
58 | "In older versions of Python (and in many older languages, like C),\n",
59 | "the built-in division operation is integer division.\n",
60 | "Note that in general to return an integer upon dividing two integers,\n",
61 | "we would have to either round the result, or discard the fractional part. \n",
62 | "Classically, the convention is to discard the fractional component.\n",
63 | "\n",
64 | "We can invoke the classic integer division by using the `//` operator."
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "metadata": {},
71 | "outputs": [],
72 | "source": [
73 | "# Division\n",
74 | "result = x // y\n",
75 | "print('Division:', 'x // y \\t', type(result), result)"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "The modulo operator:\n",
83 | "Another convenient operator is the modulo operator: `%`. This does the opposite of integer division. Instead of discarding the remainder, it *only* returns the remainder:"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": null,
89 | "metadata": {},
90 | "outputs": [],
91 | "source": [
92 | "print(8 % 5)\n",
93 | "print(9 % 3)\n",
94 | "print(13 % 4)"
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "## Floating point arithmetic\n",
102 | "\n",
103 | "Python also supports the standard continuous math functions on floating point numbers. There are no big surprises here. "
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": null,
109 | "metadata": {},
110 | "outputs": [],
111 | "source": [
112 | "x = 5.0\n",
113 | "y = 8.0\n",
114 | "\n",
115 | "# Basic Debugging\n",
116 | "print(\"x \\t\\t\\t\", type(x), x)\n",
117 | "print(\"y \\t\\t\\t\", type(y), y)\n",
118 | "\n",
119 | "# Addition\n",
120 | "result = x + y\n",
121 | "print('Addition:', 'x + y \\t', type(result), result)\n",
122 | "\n",
123 | "# Subtraction\n",
124 | "result = x - y\n",
125 | "print('Subtraction:', 'x - y \\t', type(result), result)\n",
126 | "\n",
127 | "# Multiplication\n",
128 | "result = x * y\n",
129 | "print('Multiplication:', 'x * y \\t', type(result), result)\n",
130 | "\n",
131 | "# Division\n",
132 | "result = x / y\n",
133 | "print('Division:', 'x / y \\t', type(result), result)\n",
134 | "\n",
135 | "# Exponentiation\n",
136 | "result = x ** y\n",
137 | "print('Exponentiation:', 'x ** y \\t', type(result), result)"
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {},
143 | "source": [
144 | "## Plus-equals and friends\n",
145 | "\n",
146 | "A very common workflow is that we want \n",
147 | "to update the value of a variable\n",
148 | "by adding, subtracting, multiplying or dividing\n",
149 | "some other value **from its current value**. \n",
150 | "Like many languages, Python supports these operations \n",
151 | "via the `+=`, `-=`, `*=`, and `/=` operators."
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": null,
157 | "metadata": {},
158 | "outputs": [],
159 | "source": [
160 | "x = 10\n",
161 | "print(x)\n",
162 | "x += 1\n",
163 | "print(x)\n",
164 | "x -= 1\n",
165 | "print(x)\n",
166 | "x *= 2 \n",
167 | "print(x)\n",
168 | "x /= 2 \n",
169 | "print(x)"
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "## The standard `math` library\n",
177 | "\n",
178 | "For more advanced operations than those \n",
179 | "built in to the Python programming language,\n",
180 | "you can import the math library. \n",
181 | "Importing a library is easy. \n",
182 | "Just run `import math`\n",
183 | "This gives us access to all the functions \n",
184 | "contained in the `math` package by calling `math.`."
185 | ]
186 | },
187 | {
188 | "cell_type": "code",
189 | "execution_count": null,
190 | "metadata": {},
191 | "outputs": [],
192 | "source": [
193 | "import math\n",
194 | "\n",
195 | "# round up a number \n",
196 | "print(\"math.ceil(5.3):\\t\\t\", math.ceil(5.3))\n",
197 | "\n",
198 | "# round a number down \n",
199 | "print(\"math.floor(5.3):\\t\", math.floor(5.3))\n",
200 | "\n",
201 | "# access trigonometric functions and common constants\n",
202 | "print(\"math.sin(math.pi)\\t\", math.sin(math.pi))"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "metadata": {},
208 | "source": [
209 | "You might notice have expected that $\\text{sin}(\\pi)$\n",
210 | "executed in code as `math.sin(math.pi)` should return the value 0.\n",
211 | "If you look closely, you'll notice that the value returned\n",
212 | "(on my computer `1.2246467991473532e-16`),\n",
213 | "while not *exactly* `0`, is very very close.\n",
214 | "That's because although the computer can simulate continuous mathematics,\n",
215 | "all the memory on the entire machine (or any machine)\n",
216 | "could never store all the digits of $\\pi$.\n",
217 | "So the computer doesn't really store continuous numbers,\n",
218 | "instead it approximates continuous math with floats\n",
219 | "by sotring some significant digits and also\n",
220 | "an exponent to capture the order of magnitude.\n",
221 | "The result is that sometimes we'll be off just a tiny bit,\n",
222 | "if only at extreme precision and orders of magnitude.\n",
223 | "If you're really fascinated about floating point arithmetic, \n",
224 | "perhaps start by checking out [the Wikipedia page](https://en.wikipedia.org/wiki/Floating-point_arithmetic) or the official Python documentation \n",
225 | "on how [the issues and limitations of floating point arithmetic](https://docs.python.org/3/tutorial/floatingpoint.html).\n",
226 | "\n",
227 | "In most commercial programs, such as web apps that you might build at a startup, \n",
228 | "the subtle details of floating point arithmetic won't matter much.\n",
229 | "However, as you get further along your journey into machine learning,\n",
230 | "you will find that the fine details of numerical computing often do matter\n",
231 | "and we will often need to be careful how we implement machine learning models\n",
232 | "to avoid common errors such as overflow and underflow \n",
233 | "that that can plague careless implementations."
234 | ]
235 | },
236 | {
237 | "cell_type": "markdown",
238 | "metadata": {},
239 | "source": [
240 | "## Casting between number types\n",
241 | "\n",
242 | "Sometimes you might want to explicitly treat an integer as a float or vice versa. \n",
243 | "One simple way to do this is by *casting* between these types, \n",
244 | "using the `int()` and `float()` functions:"
245 | ]
246 | },
247 | {
248 | "cell_type": "code",
249 | "execution_count": null,
250 | "metadata": {},
251 | "outputs": [],
252 | "source": [
253 | "print(int(3.4))\n",
254 | "print(float(3))"
255 | ]
256 | },
257 | {
258 | "cell_type": "markdown",
259 | "metadata": {},
260 | "source": [
261 | "You can even convert between numbers and Booleans using the `bool()` function"
262 | ]
263 | },
264 | {
265 | "cell_type": "code",
266 | "execution_count": null,
267 | "metadata": {},
268 | "outputs": [],
269 | "source": [
270 | "print(bool(4))\n",
271 | "print(bool(4.4))\n",
272 | "print(bool(0))\n",
273 | "print(bool(0.0))\n",
274 | "print(int(True))\n",
275 | "print(int(False))\n",
276 | "print(float(True))\n",
277 | "print(float(False))"
278 | ]
279 | },
280 | {
281 | "cell_type": "markdown",
282 | "metadata": {},
283 | "source": [
284 | "Be careful! If you convert directly from a `float` to a `bool`, \n",
285 | "you might think you're evaluating the number 0, \n",
286 | "(and thus should get `False`) but actually you'll get `True` due to the loss of precision."
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {},
293 | "outputs": [],
294 | "source": [
295 | "print(bool(math.sin(math.pi)))"
296 | ]
297 | }
298 | ],
299 | "metadata": {
300 | "kernelspec": {
301 | "display_name": "Python 3",
302 | "language": "python",
303 | "name": "python3"
304 | },
305 | "language_info": {
306 | "codemirror_mode": {
307 | "name": "ipython",
308 | "version": 3
309 | },
310 | "file_extension": ".py",
311 | "mimetype": "text/x-python",
312 | "name": "python",
313 | "nbconvert_exporter": "python",
314 | "pygments_lexer": "ipython3",
315 | "version": "3.7.4"
316 | }
317 | },
318 | "nbformat": 4,
319 | "nbformat_minor": 2
320 | }
321 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec06_boolean_logic.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Boolean logic\n",
8 | "\n",
9 | "Boolean values are useful because we use them \n",
10 | "to perform Boolean arithmetic,\n",
11 | "which should be familiar to you from high school\n",
12 | "as the basic logic operations.\n",
13 | "\n",
14 | "These are operations that operate on Boolean values as inputs\n",
15 | "and produce Boolean values as outputs. \n",
16 | "Among these are the familiar `not`, `and`, and `or` operations:"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": [
25 | "p = True\n",
26 | "q = False\n",
27 | "\n",
28 | "print(\"The not opeprator\")\n",
29 | "print(\"not p: \", not p)\n",
30 | "print(\"not q: \", not q)\n",
31 | "\n",
32 | "print(\"\\nThe and opeprator\")\n",
33 | "print(\"p and p: \", p and p)\n",
34 | "print(\"p and q: \", p and q)\n",
35 | "print(\"q and q: \", q and q)\n",
36 | "\n",
37 | "print(\"\\nThe or opeprator\")\n",
38 | "print(\"p or p: \", p or p)\n",
39 | "print(\"p or q: \", p or q)\n",
40 | "print(\"q or q: \", q or q)\n"
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "From these operations, it's trivial to define any other Boolean operation, for example *exclusive or*, *nand*, or *implies*."
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "## Comparisons\n",
55 | "\n",
56 | "We also often use operators that act upon non-Boolean inputs (say strings or numbers) \n",
57 | "but that produce Boolean values as outputs.\n",
58 | "\n",
59 | "Perhaps the most straightforward relational operators \n",
60 | "are those for testing equality (`==`) and for testing inequality (`!=`)."
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": null,
66 | "metadata": {},
67 | "outputs": [],
68 | "source": [
69 | "# Testing equality\n",
70 | "print(\"'a' == 'b': \\t\", 'a' == 'b')\n",
71 | "\n",
72 | "# Not equal to\n",
73 | "print(\"'a' != 'b': \\t\", 'a' != 'b')"
74 | ]
75 | },
76 | {
77 | "cell_type": "markdown",
78 | "metadata": {},
79 | "source": [
80 | "Note that these operators are defined over many object types.\n",
81 | "Above we tested the equality of strings but we can just \n",
82 | "as easily test the equality of numbers:"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": null,
88 | "metadata": {},
89 | "outputs": [],
90 | "source": [
91 | "# Testing equality\n",
92 | "print(\"5 == 5: \\t\", 5 == 5)\n",
93 | "print(\"5 == 5.0: \\t\", 5 == 5.0)\n",
94 | "print(\"5 == 5.1: \\t\", 5 == 5.1)\n",
95 | "\n",
96 | "# Not equal to\n",
97 | "print(\"5 != 5: \\t\", 5 != 5)\n",
98 | "print(\"5 != 5.0: \\t\", 5 != 5.0)\n",
99 | "print(\"5 != 5.1: \\t\", 5 != 5.1)"
100 | ]
101 | },
102 | {
103 | "cell_type": "markdown",
104 | "metadata": {},
105 | "source": [
106 | "Given numerical values, we often want to test not just \n",
107 | "whether the two have the exact same value \n",
108 | "but rather one is greater than the other. \n",
109 | "The relational operators act upon numbers as inputs\n",
110 | "and produce Boolean values as outputs:"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "metadata": {},
117 | "outputs": [],
118 | "source": [
119 | "# Greater than\n",
120 | "print(\"5 > 6:\\t\\t\", 5 > 6)\n",
121 | "\n",
122 | "# Greater than or equal to\n",
123 | "print(\"5 >= 5:\\t\\t\", 5 >= 5)\n",
124 | "\n",
125 | "# Less than\n",
126 | "print(\"5 < 6:\\t\\t\", 5 < 6)\n",
127 | "\n",
128 | "# Less than or equals\n",
129 | "print(\"5 <= 5:\\t\\t\", 5 <= 5)"
130 | ]
131 | }
132 | ],
133 | "metadata": {
134 | "kernelspec": {
135 | "display_name": "Python 3",
136 | "language": "python",
137 | "name": "python3"
138 | },
139 | "language_info": {
140 | "codemirror_mode": {
141 | "name": "ipython",
142 | "version": 3
143 | },
144 | "file_extension": ".py",
145 | "mimetype": "text/x-python",
146 | "name": "python",
147 | "nbconvert_exporter": "python",
148 | "pygments_lexer": "ipython3",
149 | "version": "3.7.4"
150 | }
151 | },
152 | "nbformat": 4,
153 | "nbformat_minor": 2
154 | }
155 |
--------------------------------------------------------------------------------
/chapter01_introduction/sec99_intro_recap:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": []
9 | }
10 | ],
11 | "metadata": {
12 | "kernelspec": {
13 | "display_name": "Python 3",
14 | "language": "python",
15 | "name": "python3"
16 | },
17 | "language_info": {
18 | "codemirror_mode": {
19 | "name": "ipython",
20 | "version": 3
21 | },
22 | "file_extension": ".py",
23 | "mimetype": "text/x-python",
24 | "name": "python",
25 | "nbconvert_exporter": "python",
26 | "pygments_lexer": "ipython3",
27 | "version": "3.6.5"
28 | }
29 | },
30 | "nbformat": 4,
31 | "nbformat_minor": 2
32 | }
33 |
--------------------------------------------------------------------------------
/chapter02_collections/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zackchase/python-wow/ad5175c96a95ffb5947f13d3ca695e22319bf112/chapter02_collections/.DS_Store
--------------------------------------------------------------------------------
/chapter02_collections/practice_questions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Practice Questions on Collections\n",
8 | "\n",
9 | "This notebook contains a bunch of questions aimed at verifying that you know things about collections.\n",
10 | "The questions below are for your practice. They ask for a mixture of writing short lines of code or expressions, or providing short responses. \n",
11 | "\n",
12 | "## Lists\n",
13 | "\n",
14 | "1. Create an empty list as a literal and assign it to a variable called `my_list`. \n",
15 | "2. Wite a an expression to access the length of that list.\n",
16 | "3. What is the type of `my_list`?\n",
17 | "4. What is the type of the type of `my_list`?\n",
18 | "5. Add the following elements to `my_list`: `4`, `10`, `17`, `3` in that order. Using four calls to the appropriate method that takes an argument and tacks it on to the end of an existing list. \n",
19 | "6. What is the type of `my_list` now?\n",
20 | "7. What is the index corresponding to `17`?\n",
21 | "8. Write a line of code to extract the element corresponding to index `1` and assign it to a variable called my element.\n",
22 | "9. Insert an element `\"intruder\"` to the list at index `2` but otherwise keeping the order among the other elements the same.\n",
23 | "10. Write an expression to extract the 2nd element through the 4th element.\n",
24 | "11. Use the in-built list method to sort the list.\n",
25 | "12. Assign `my_list` to a new variable called `new_list`. \n",
26 | "13. Do `my_list` and `new_list` refer to the same object or are they distinct copies?\n",
27 | "14. Print `my_list` and `new_list`.\n",
28 | "14. Reverse the order of `new_list`.\n",
29 | "14. Now print both `my_list` and `new_list` again.\n",
30 | "14. How is this behavior similar or different to the behavior when assigning a variable of type `int` to another variable?\n",
31 | "14. Say we want to have completely distinct copies of each list. Write a line of code to make a true copy of `my_list` and assign that copy to `new_list2`."
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {},
38 | "outputs": [],
39 | "source": []
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "## Dictionaries\n",
46 | "\n",
47 | "1. Write a dictionary literal that contains a list of 10 actors, each as a name hashed to their age, and assign it to a variable called `actor_ages`.\n",
48 | "2. Extract the list of keys from the dictionary using the `.keys()` method.\n",
49 | "3. Explain, what is the difference between the object returned by `.keys()` and a typical Python list?\n",
50 | "4. Write a line of code that takes the dictionary view obejct returned by `.keys()`, casts it as a proper list and assigned it to a variable called `actors`. \n",
51 | "5. Add a new actor to the list \"Hugh Laurie\", mapped to age `58`. \n",
52 | "6. This list, in each entry so far, maps strings to integers. What other types of values can serve as keys in this dictionary? Can Booleans be keys? Ints? FLo"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": []
61 | }
62 | ],
63 | "metadata": {
64 | "kernelspec": {
65 | "display_name": "Python 3",
66 | "language": "python",
67 | "name": "python3"
68 | },
69 | "language_info": {
70 | "codemirror_mode": {
71 | "name": "ipython",
72 | "version": 3
73 | },
74 | "file_extension": ".py",
75 | "mimetype": "text/x-python",
76 | "name": "python",
77 | "nbconvert_exporter": "python",
78 | "pygments_lexer": "ipython3",
79 | "version": "3.6.5"
80 | }
81 | },
82 | "nbformat": 4,
83 | "nbformat_minor": 2
84 | }
85 |
--------------------------------------------------------------------------------
/chapter02_collections/sec01_lists.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Lists\n",
8 | "\n",
9 | "While we've learned a lot about Pythons' *primitive* values\n",
10 | "including `int`, `float`, `str`, and `bool`,\n",
11 | "there's more to programming than writing lines of code \n",
12 | "to individually manipulate these indivisible \n",
13 | "(more formally called *atomic*) beads of information.\n",
14 | "\n",
15 | "Rather than writing code to manipulate each item a la carte,\n",
16 | "we will instead want to organize our data in various \n",
17 | "structures, sometimes called *collections*,\n",
18 | "in part to facilitate acting upon the whole collection subsequently.\n",
19 | "\n",
20 | "We often want to collect a bunch of *related* values together,\n",
21 | "so we can manipulate them all together.\n",
22 | "Imagine, for eample that you are scraping the web. \n",
23 | "Then you might have a list of 10,000 addresses that you need to scrape.\n",
24 | "One the other hand, if we were keeping track of public health trends,\n",
25 | "then we might want some way to represent a collection of test results,\n",
26 | "where each result represents one member of the population.\n",
27 | "\n",
28 | "The most simple and natural collections \n",
29 | "to work with in Python are `list` objects.\n",
30 | "They represent a collection of values, in some specified **order**.\n",
31 | "The most simple way to work with a list \n",
32 | "is to write one down directly in code as a *list literal*.\n",
33 | "We do this by placing to brackets (`'[`, `]`) \n",
34 | "with some comma-separated values in between:"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "my_list = [13, 2, 3, 1, 8, 5, 1]"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "## Accessing from a list \n",
51 | "\n",
52 | "Now that we've defined this list, we can access its values in the following ways. \n",
53 | "\n",
54 | "### Printing lists"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "print(my_list)"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "### Indexing into a list\n",
71 | "\n",
72 | "We can access its elements by their indices using bracket notation `my_list[]`"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "metadata": {},
79 | "outputs": [],
80 | "source": [
81 | "print(my_list[1])\n",
82 | "print(my_list[2])"
83 | ]
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "metadata": {},
88 | "source": [
89 | "Notice that in bracket notation, we supply an *index* inside the brackets. \n",
90 | "The index indicates which element of the list we are retrieving.\n",
91 | "Each element is associated with an index based on its location, \n",
92 | "i.e., where it appears in the list.\n",
93 | "\n",
94 | "***Note also that all lists start with index 0***"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {},
101 | "outputs": [],
102 | "source": [
103 | "print(my_list[0])"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "***Side note:*** For reasons we don't need to get into,\n",
111 | "indexing at 0 is a sensible convention for indexing items in arrays.\n",
112 | "This owes to historical reasons that are more readily seen\n",
113 | "in programming languages like C that are a bit closer to the metal.\n",
114 | "There, an array is basically a block of consecutive memory locations.\n",
115 | "In C, our reference to an array is a reference to the first item in the list.\n",
116 | "Each index then indicates the offset of that item relative to the first item.\n",
117 | "The index of 0 means go to the head of list and then do not advance any further.\n",
118 | "An index of 1 means go to the head of the list and then advance one item down the list.\n",
119 | "\n",
120 | "While indexing at 0 is a widespread standard that most languages adopt,\n",
121 | "the reasons for it do not matter so much in modern interpreted languages.\n",
122 | "Indeed, not all languages follow the convention.\n",
123 | "Julia, a wonderful language developed at MIT\n",
124 | "specifically for mathematical computing indexes at 1,\n",
125 | "to better match how we talk about collections of items in math notation,\n",
126 | "and so does MatLab (a proprietary language that is almost affordable to academics\n",
127 | "but costs one kidney per license upon graduation). \n",
128 | "\n",
129 | "Given list of unknown length, we often need to find out its length\n",
130 | "in order to know *which indices are valid*.\n",
131 | "We can do that using Python's built-in `len` function:,\n",
132 | "the same as we used to calculate the length of strings:"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {},
139 | "outputs": [],
140 | "source": [
141 | "len(my_list)"
142 | ]
143 | },
144 | {
145 | "cell_type": "markdown",
146 | "metadata": {},
147 | "source": [
148 | "Note that because the list indices start at `0`, \n",
149 | "the last element has index `len(mylist-1)`:"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {},
156 | "outputs": [],
157 | "source": [
158 | "print(my_list[len(my_list) - 1])"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "If we try to access any index larger than that we'll get an error that looks like this:\n",
166 | "\n",
167 | "```\n",
168 | "---------------------------------------------------------------------------\n",
169 | "IndexError Traceback (most recent call last)\n",
170 | " in ()\n",
171 | "----> 1 print(my_list[len(my_list)])\n",
172 | "\n",
173 | "IndexError: list index out of range\n",
174 | "```"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "### Negative Indexing\n",
182 | "\n",
183 | "We can use negative indices where `my_list[-i]`\n",
184 | "is shorthand for `my_list[len(my_list)-i]`\n",
185 | "To access the last element of the list we can use index `[-1]`, \n",
186 | "and to access the 2nd to last element, we can use `[-2]`, etc. "
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "### Slicing Lists\n",
194 | "\n",
195 | "Sometimes we want to access a continuous stretch of values from within our lists. \n",
196 | "To indicate that we want to extract a whole range of indices,\n",
197 | "we insert a colon into our index notation with notatino like `my_list[start:end]`:"
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {},
204 | "outputs": [],
205 | "source": [
206 | "print(my_list[4:6])"
207 | ]
208 | },
209 | {
210 | "cell_type": "markdown",
211 | "metadata": {},
212 | "source": [
213 | "Note that slices are inclusive on the left, but not on the right, \n",
214 | "e.g., [4:6] gives us a list that includes the elements \n",
215 | "with index 4 and index 5, but not index 6.\n",
216 | "\n",
217 | "This is useful because it makes it easy to split lists into two halves:"
218 | ]
219 | },
220 | {
221 | "cell_type": "code",
222 | "execution_count": null,
223 | "metadata": {},
224 | "outputs": [],
225 | "source": [
226 | "split_point = 4\n",
227 | "print(my_list[:split_point])\n",
228 | "print(my_list[split_point:])"
229 | ]
230 | },
231 | {
232 | "cell_type": "markdown",
233 | "metadata": {},
234 | "source": [
235 | "Notice above that we used one nice additional Python slicing feature. \n",
236 | "When we use `[:end]`, Python will assume \n",
237 | "that we start at the beginning of the list, \n",
238 | "thus is equivalent to `[0:end]`. \n",
239 | "Similarly, when we invoke `[end:]`, Python will assume \n",
240 | "that we are going all the way to the end of the list, \n",
241 | "and thus this is equivalent to `[end:len(my_list)]`."
242 | ]
243 | },
244 | {
245 | "cell_type": "markdown",
246 | "metadata": {},
247 | "source": [
248 | "## Lists and Strings\n",
249 | "\n",
250 | "You might notice that lists and strings have some things in common.\n",
251 | "Unlike integers or floats, strings and lists can be of various lengths.\n",
252 | "Moreover supports the `len()` function.\n",
253 | "\n",
254 | "The similarities don't end there. \n",
255 | "In many programming languages, text strings \n",
256 | "are expicitly defined as arrays of characters.\n",
257 | "In Python, while there is no dedicated, separate character type,\n",
258 | "the list-like nature of strings remains. \n",
259 | "\n",
260 | "For starters, we can access indices or slices of strings:"
261 | ]
262 | },
263 | {
264 | "cell_type": "code",
265 | "execution_count": null,
266 | "metadata": {},
267 | "outputs": [],
268 | "source": [
269 | "\"This is a string, I wrote it myself!\"[-18:]"
270 | ]
271 | },
272 | {
273 | "cell_type": "markdown",
274 | "metadata": {},
275 | "source": [
276 | "Similarly, just as we can concatenate two strings together, \n",
277 | "we can concatenate two lists together:"
278 | ]
279 | },
280 | {
281 | "cell_type": "code",
282 | "execution_count": null,
283 | "metadata": {},
284 | "outputs": [],
285 | "source": [
286 | "[1, 1, 2, 3] + [5, 8, 13, 21]"
287 | ]
288 | },
289 | {
290 | "cell_type": "markdown",
291 | "metadata": {},
292 | "source": [
293 | "## Updating elements\n",
294 | "\n",
295 | "Sometimes we'll want to update a single element in a list\n",
296 | "while keeping all others the same.\n",
297 | "This is easy, using `[index]` notation,\n",
298 | "we just a sign a new value to that index:"
299 | ]
300 | },
301 | {
302 | "cell_type": "code",
303 | "execution_count": null,
304 | "metadata": {},
305 | "outputs": [],
306 | "source": [
307 | "my_list2 = my_list\n",
308 | "my_list2[1] = 1985\n",
309 | "print(\"my_list2: \", my_list2)"
310 | ]
311 | },
312 | {
313 | "cell_type": "markdown",
314 | "metadata": {},
315 | "source": [
316 | "We might have thought that we were very clever and by creating the variable `my_list2`, avoided messing up the original `my_list`, let's check to see how successful we were:"
317 | ]
318 | },
319 | {
320 | "cell_type": "code",
321 | "execution_count": null,
322 | "metadata": {},
323 | "outputs": [],
324 | "source": [
325 | "print(\"my_list: \", my_list)\n",
326 | "print(\"my_list2: \", my_list2)"
327 | ]
328 | },
329 | {
330 | "cell_type": "markdown",
331 | "metadata": {},
332 | "source": [
333 | "Not very! See, when we assign `var = some_list`, \n",
334 | "we're not actually making a copy of the list. \n",
335 | "Instead, we are assigning a *reference* to **the same list**! \n",
336 | "To really make a copy, we'll want to use the `copy` package \n",
337 | "and call the `deepcopy` function:"
338 | ]
339 | },
340 | {
341 | "cell_type": "code",
342 | "execution_count": null,
343 | "metadata": {},
344 | "outputs": [],
345 | "source": [
346 | "import copy\n",
347 | "my_list2 = copy.deepcopy(my_list)\n",
348 | "my_list[1] = 2\n",
349 | "print(\"my_list: \", my_list)\n",
350 | "print(\"my_list2: \", my_list2)"
351 | ]
352 | },
353 | {
354 | "cell_type": "markdown",
355 | "metadata": {},
356 | "source": [
357 | "## Appending items to a List\n",
358 | "\n",
359 | "Often, we don't want to just update an item in place, \n",
360 | "we'll actually want to grow the list to accomodate new data. \n",
361 | "The easiest way to do this is with the `append` function:"
362 | ]
363 | },
364 | {
365 | "cell_type": "code",
366 | "execution_count": null,
367 | "metadata": {},
368 | "outputs": [],
369 | "source": [
370 | "my_list.append(21)\n",
371 | "print(\"my_list\", my_list)"
372 | ]
373 | },
374 | {
375 | "cell_type": "markdown",
376 | "metadata": {},
377 | "source": [
378 | "## Removing items from a list\n",
379 | "\n",
380 | "There are a few options for how to remove items from lists.\n",
381 | "One way is to call the lists `.pop()` method \n",
382 | "which takes an index as input and simultaneously ***removes and returns*** that element.\n",
383 | "If we call `.pop()` without providing any index as an argument\n",
384 | "it will default to removing the last element of the list.\n",
385 | "Appending and popping corresponds to using our list as a *stack*.\n",
386 | "Stacks are useful when we want to access data \n",
387 | "in a last in, first out format. \n",
388 | "\n",
389 | "I tend to access my emails in a stack-like fashion, \n",
390 | "but unfortunately that means that email that gets buried\n",
391 | "for over a week may never see the light of day."
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": null,
397 | "metadata": {},
398 | "outputs": [],
399 | "source": [
400 | "print(my_list2)\n",
401 | "x = my_list2.pop(1)\n",
402 | "print(my_list2)"
403 | ]
404 | },
405 | {
406 | "cell_type": "markdown",
407 | "metadata": {},
408 | "source": [
409 | "## Sorting and reversing\n",
410 | "Finally, you might want to take a list \n",
411 | "and sort it according to some ordering.\n",
412 | "To sort according to whatever ordering is default\n",
413 | "(alphabetical for strings, numeric for numbers),\n",
414 | "just call a list's `.sort()` method. "
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": null,
420 | "metadata": {},
421 | "outputs": [],
422 | "source": [
423 | "my_list.sort()\n",
424 | "my_list"
425 | ]
426 | },
427 | {
428 | "cell_type": "markdown",
429 | "metadata": {},
430 | "source": [
431 | "Note that `.sort()` actually changes the order of the items in the list.\n",
432 | "After calling sort, my_list is now permanently sorted\n",
433 | "and we have lost all information about the original\n",
434 | "order in which the iterms appeared. \n",
435 | "\n",
436 | "If you would only like to temporarily access the items in sorted order\n",
437 | "but do not want to disturb the original list, \n",
438 | "you can call the `sorted()` function which will \n",
439 | "return a sorted version of the list while leaving the original untouched."
440 | ]
441 | },
442 | {
443 | "cell_type": "markdown",
444 | "metadata": {},
445 | "source": [
446 | "We can also reverse the order of elements in a list by using the `.reverse()` method."
447 | ]
448 | },
449 | {
450 | "cell_type": "code",
451 | "execution_count": null,
452 | "metadata": {},
453 | "outputs": [],
454 | "source": [
455 | "my_list.reverse()\n",
456 | "my_list"
457 | ]
458 | },
459 | {
460 | "cell_type": "markdown",
461 | "metadata": {},
462 | "source": [
463 | "## Checking membership \n",
464 | "\n",
465 | "Sometimes we want to check to see if a given value is represented in a list. \n",
466 | "We can do this using the built-in syntax ` in `.\n",
467 | "This is a Boolean function that returns True if the element \n",
468 | "is one of the values contained in the list and False otherwise."
469 | ]
470 | },
471 | {
472 | "cell_type": "code",
473 | "execution_count": null,
474 | "metadata": {},
475 | "outputs": [],
476 | "source": [
477 | "print(13 in my_list)\n",
478 | "print(\"rhinocerous\" in my_list)"
479 | ]
480 | },
481 | {
482 | "cell_type": "markdown",
483 | "metadata": {},
484 | "source": [
485 | "### Other list methods\n",
486 | "\n",
487 | "Lists support a number of other methods. These include `.extend(other_list)`\n",
488 | "which works similarly to `.append()` but instead of appending a single element,\n",
489 | "it takes a number of elements in another list and adds them all to our list.\n",
490 | "\n",
491 | "In general, you will not remember every method or attribute of every object,\n",
492 | "and even when you do remember one, you may forget precisely what it is called\n",
493 | "or precisely how to use it. \n",
494 | "\n",
495 | "Thus now is a good time to introduce two handy utilities that we can call in Jupyter.\n",
496 | "First, we can call `dir()` on any object to access its full listing of attributes and methods.\n",
497 | "Below you can run `dir(\"Hello\")` to see the methods associated with a string,\n",
498 | "including the familiar `lower`, `upper`, and `title`. \n",
499 | "You can also call `dir([1,2,3])` to see the full set of methods associated with a list."
500 | ]
501 | },
502 | {
503 | "cell_type": "code",
504 | "execution_count": null,
505 | "metadata": {},
506 | "outputs": [],
507 | "source": [
508 | "# dir(\"Hello\")\n",
509 | "# dir([1,2,3])"
510 | ]
511 | }
512 | ],
513 | "metadata": {
514 | "kernelspec": {
515 | "display_name": "Python 3",
516 | "language": "python",
517 | "name": "python3"
518 | },
519 | "language_info": {
520 | "codemirror_mode": {
521 | "name": "ipython",
522 | "version": 3
523 | },
524 | "file_extension": ".py",
525 | "mimetype": "text/x-python",
526 | "name": "python",
527 | "nbconvert_exporter": "python",
528 | "pygments_lexer": "ipython3",
529 | "version": "3.7.4"
530 | }
531 | },
532 | "nbformat": 4,
533 | "nbformat_minor": 2
534 | }
535 |
--------------------------------------------------------------------------------
/chapter02_collections/sec02_tuples.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Tuples\n",
8 | "If you understand lists, then tuples will really be a breeze.\n",
9 | "Tuples behave almost exactly like lists in many respects \n",
10 | "but offer only a subset of their functionality.\n",
11 | "\n",
12 | "In particular, unlike lists which are *mutable*\n",
13 | "(elements can be assigned, added, or deleted),\n",
14 | "lists are *immutable* meaning that they point \n",
15 | "to a fixed set of objects that cannot \n",
16 | "change after they have been created.\n",
17 | "\n",
18 | "In fact, tuples and lists are so similar\n",
19 | "that its often confusing for newcomers \n",
20 | "for whom it is not readily clear \n",
21 | "why Python supports both datastructures. \n",
22 | "\n",
23 | "To start, let's create a tuple. \n",
24 | "In Python tuple literals are defined just as lists\n",
25 | "but using parenthesis `(...)` instead of square brackets `[]`:"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "my_tuple = (print, 5.0, \"clown\", [\"a\", \"b\", \"c\"])"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "Here we've crearted a tuple with 4 elements:\n",
42 | "the `print` function, the float `5.0`, \n",
43 | "the string `\"clown\"` and the list `[\"a\", \"b\", \"c\"]`.\n",
44 | "Just as with lists we can index into a tuple,\n",
45 | "and we can also access a sub-tuple via slicing:"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {},
52 | "outputs": [],
53 | "source": [
54 | "print(my_tuple[1])\n",
55 | "print(my_tuple[1:3])\n",
56 | "print(my_tuple[-2:])"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "However, crucially, we cannot change the objects that a tuple refers to.\n",
64 | "Note, for example, the error that we get if we try to replace `\"clown\"`\n",
65 | "with some other string."
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": null,
71 | "metadata": {},
72 | "outputs": [],
73 | "source": [
74 | "my_tuple[-2] = \"jester\""
75 | ]
76 | },
77 | {
78 | "cell_type": "markdown",
79 | "metadata": {},
80 | "source": [
81 | "We will also get an error if we attempt to append an item\n",
82 | "informing us that tuple objects have no append method:\n",
83 | "\n",
84 | "```AttributeError: 'tuple' object has no attribute 'append'```"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "### Concatenating tuples\n",
92 | "However, tuples do support concatenation. \n",
93 | "That's kosher because concatenation does not alter either tuple,\n",
94 | "but instead returns a new tuple which is the result of the operation:"
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {},
101 | "outputs": [],
102 | "source": [
103 | "(1,2,3) + (\"a\", \"b\", \"c\")"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "If we want to concatenate a list and a tuple, \n",
111 | "we must first either cast the list as a tuple\n",
112 | "or cast the tuple as a list:"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {},
119 | "outputs": [],
120 | "source": [
121 | "print(list((1,2,3)) + [\"a\", \"b\", \"c\"])\n",
122 | "print((1,2,3) + tuple([\"a\", \"b\", \"c\"]))"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "### Other supported operations\n",
130 | "A variety of other familiar operations \n",
131 | "supported by lists are supported by tuples\n",
132 | "(those that do not mutate the object).\n",
133 | "These include the `in` operation\n",
134 | "for identifying membership:"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": null,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "\"mango\" in (\"lemon\", \"mango\", \"nectarine\")"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "This also includes looking up the index of an item."
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "metadata": {},
157 | "outputs": [],
158 | "source": [
159 | "(\"lemon\", \"mango\", \"nectarine\").index(\"mango\")"
160 | ]
161 | },
162 | {
163 | "cell_type": "markdown",
164 | "metadata": {},
165 | "source": [
166 | "## Common uses of tuples\n",
167 | "Tuples are useful for a variety opf reasons and in a variety of contexts:\n",
168 | " * Tuples are faster than lists. Because they needn't support the capability of changing lenghths, they can be implemented more efficiently.\n",
169 | " * Tuples can be used to prevent misuse of the object in situations where the object truly needs to be immutable. \n",
170 | " * Return values of functions (see more in chapter 4) are typically tuples."
171 | ]
172 | }
173 | ],
174 | "metadata": {
175 | "kernelspec": {
176 | "display_name": "Python 3",
177 | "language": "python",
178 | "name": "python3"
179 | },
180 | "language_info": {
181 | "codemirror_mode": {
182 | "name": "ipython",
183 | "version": 3
184 | },
185 | "file_extension": ".py",
186 | "mimetype": "text/x-python",
187 | "name": "python",
188 | "nbconvert_exporter": "python",
189 | "pygments_lexer": "ipython3",
190 | "version": "3.7.4"
191 | }
192 | },
193 | "nbformat": 4,
194 | "nbformat_minor": 2
195 | }
196 |
--------------------------------------------------------------------------------
/chapter02_collections/sec03_dictionaries.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Dictionaries\n",
8 | "\n",
9 | "If you've gotten your head around lists,\n",
10 | "then dictionaries are quite easy.\n",
11 | "While lists are collections that associate *indices* with *values*,\n",
12 | "dictionaries are simply collections \n",
13 | "that associate *keys* with *values*\n",
14 | "where *keys* need not be numbers. \n",
15 | "For example, we might want a list \n",
16 | "to associate cars with prices.\n",
17 | "\n",
18 | "Just as we can an express a *list literal*, \n",
19 | "Python also supports *dictionary literals*.\n",
20 | "We define a dictionary literal by using curly braces: `{...}`,\n",
21 | "between the braces, we can have any number of `key:value` pairs."
22 | ]
23 | },
24 | {
25 | "cell_type": "code",
26 | "execution_count": null,
27 | "metadata": {},
28 | "outputs": [],
29 | "source": [
30 | "my_dict = {\"Roadster\":200000, \"Model S\":70000, \"Model X\": 100000}\n",
31 | "print(my_dict)"
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {},
37 | "source": [
38 | "Once we've defined a dictionary, we can \n",
39 | "get values out using list-like indexing `[]`.\n",
40 | "Here, instead of indexing with a number, we index with a *key*:"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "my_dict[\"Roadster\"]"
50 | ]
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "## Adding a key-value pair\n",
57 | "\n",
58 | "We can add a new key-value pair to the dictionary as follows:"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {},
65 | "outputs": [],
66 | "source": [
67 | "my_dict[\"Model 3\"] = 35000"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "## Extracting dictionary items/keys as lists\n",
75 | "\n",
76 | "We can extract all items (key, value) tuples from a dictionary \n",
77 | "as a list by using the `.items()` method."
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "my_dict.items()"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "### What is dict_items?\n",
94 | "Note that the items returned by `.items()` are not an ordinary list but rather this new object called by the peculiar name `dict_items`. \n",
95 | "Notably this object is a view of a particular dictionary \n",
96 | "and is still attached ot the dictionary that created it.\n",
97 | "For example, if we access the `dict_items` and assign it to a variable,\n",
98 | "and then subsequently add an item to the dictionary,\n",
99 | "the `dict_items` object will be updated accordingly:"
100 | ]
101 | },
102 | {
103 | "cell_type": "code",
104 | "execution_count": null,
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "cars = my_dict.items()\n",
109 | "my_dict[\"Semi\"] = 300000\n",
110 | "print(cars)"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "Notably, if we first casted the my_dict to a list with `list(my_dict.items())`,\n",
118 | "then it would not have been updated when the dictionary got updated."
119 | ]
120 | },
121 | {
122 | "cell_type": "markdown",
123 | "metadata": {},
124 | "source": [
125 | "### Keys\n",
126 | "When we just want to access the keys, we can call the `.keys()` method."
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {},
133 | "outputs": [],
134 | "source": [
135 | "my_dict.keys()"
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {},
141 | "source": [
142 | "## Some more on views\n",
143 | "\n",
144 | "You might have noticed that dict.keys() returns a `dict_keys` object. \n",
145 | "And you might be wondering, what sort of object is a `dict_keys`? \n",
146 | "\n",
147 | "Indeed, in past versions of Python, `.keys()` would return a list,\n",
148 | "in Python 3 it returns a *dictionary view object*. \n",
149 | "Dictionary view objects (per the [official documentation here](https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects))\n",
150 | "are **dynamic** views on the entries in a dictionary.\n",
151 | "\n",
152 | "Again, although the result looks like a list, \n",
153 | "and we can manipulate it like a list,\n",
154 | "when the underlying dictionary is updated, \n",
155 | "so does the dictionary view object.\n",
156 | "Let's demonstrate this with an example in code:"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "x = my_dict.keys()\n",
166 | "x"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": [
175 | "my_dict[\"Model Y\"] = 190000"
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "metadata": {},
182 | "outputs": [],
183 | "source": [
184 | "x"
185 | ]
186 | }
187 | ],
188 | "metadata": {
189 | "kernelspec": {
190 | "display_name": "Python 3",
191 | "language": "python",
192 | "name": "python3"
193 | },
194 | "language_info": {
195 | "codemirror_mode": {
196 | "name": "ipython",
197 | "version": 3
198 | },
199 | "file_extension": ".py",
200 | "mimetype": "text/x-python",
201 | "name": "python",
202 | "nbconvert_exporter": "python",
203 | "pygments_lexer": "ipython3",
204 | "version": "3.7.4"
205 | }
206 | },
207 | "nbformat": 4,
208 | "nbformat_minor": 2
209 | }
210 |
--------------------------------------------------------------------------------
/chapter03_control_flow/practice_questions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Practice questions on control flow\n",
8 | "\n",
9 | "1. Write a `for` loop to print the numbers from $1$ to $10$ using the `range()` function. \n",
10 | "2. Given a list `my_list` that contains some collection of objects, write a loop to iterate over the elements and prints each to the screen.\n",
11 | "3. Uses a nested loop to implement a naive algorithm to identify the first 1000 prime numbers. For each integer $i$ between 1 and 1000 determine if any integer between $1$ and $\\text{sqrt}(i)$ divides $i$. If not, then $i$ is prime! Use a list to keep track as you go of all the previously observed primes. \n",
12 | "4. Given a dictionary of type `the_dict = {key_1:value_1, ..., key_n:value_n}`, write a `for` loop iterate over each key, value paie in the dictionary and append them as (key, value) tuples to a list. \n",
13 | "5. Do the same thing in one line of code using a list comprehension.\n",
14 | "6. Read in a document, one line at a time. For each line, count the number of words, appending that number of words to a list. Then using a separate loop, pass over the list to perform some calculations, generating a report - what is the largest element in the list? What is the smallest? What is the mean? What is the median?\n",
15 | "7. Read in the same file and iterate over the document one line at a time, printing each line to screen after removing all 4-letter words. \n",
16 | "8. Write a second version of the script that checks the command line arguments for a set of delimiters, then use these to split lines into words. This allows the user to customize the script, say to decide whether hyphenated words should count as one word or two."
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": []
25 | }
26 | ],
27 | "metadata": {
28 | "kernelspec": {
29 | "display_name": "Python 3",
30 | "language": "python",
31 | "name": "python3"
32 | },
33 | "language_info": {
34 | "codemirror_mode": {
35 | "name": "ipython",
36 | "version": 3
37 | },
38 | "file_extension": ".py",
39 | "mimetype": "text/x-python",
40 | "name": "python",
41 | "nbconvert_exporter": "python",
42 | "pygments_lexer": "ipython3",
43 | "version": "3.6.5"
44 | }
45 | },
46 | "nbformat": 4,
47 | "nbformat_minor": 2
48 | }
49 |
--------------------------------------------------------------------------------
/chapter03_control_flow/sec01_conditionals.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Conditionals (if-then-else)\n",
8 | "\n",
9 | "Until now, we've just learned about expressions.\n",
10 | "These include literals and variables,\n",
11 | "together with operators that act upon them to produce new values.\n",
12 | "We've also delved with a few simple functions,\n",
13 | "such as those that print output to the screen or that collect input from users.\n",
14 | "All the programs (really Jupyter code blocks) that we wrote so far \n",
15 | "just execute line by line\n",
16 | "from the first to the last\n",
17 | "and then terminate.\n",
18 | "\n",
19 | "In this module, we'll get into some more sophisticated ways \n",
20 | "that we can structure our programs. \n",
21 | "In particular, we'll want to control \n",
22 | "*which blocks of code execute when*,\n",
23 | "and for *how many times* \n",
24 | "and *on what data*. \n",
25 | "\n",
26 | "\n",
27 | "## Conditional execution with `if` blocks\n",
28 | "\n",
29 | "To start, we can control which code executes when \n",
30 | "by using and `if` block.\n",
31 | "The basic syntax is:\n",
32 | "\n",
33 | "```\n",
34 | "if :\n",
35 | " \n",
36 | " ...\n",
37 | "\n",
38 | "\n",
39 | "```\n",
40 | "\n",
41 | "The condition (``) is any expression that evaluates to `True` or to `False`. You can also get away with using some other types of values, e.g. numbers, but you better be sure that you understand how python is going to behave in these situations. Is 1 `True`? What about `-1`? What about an infinitesimally small nonzero fraction like `1e-40`? These are ultimately choices made by Python's designers and some of them may be arbitrary. \n",
42 | "\n",
43 | "Python can tell which lines are supposed to execute vs not by looking at the indentation!\n",
44 | "This is rather different from the many other languages that ignore whitespace.\n",
45 | "In addition to making things visually pleasant by obviating the need for braces and semi-colons (blocks in many languages look like `{code_line1; code_line2}`),\n",
46 | "the mandated indentation scheme makes it very easy to tell what's going on in a Python program by inspecting it visually. \n",
47 | "Programmers in other languages end up needing to deal with this anyway \n",
48 | "by enforcing style standards.\n",
49 | "\n",
50 | "Let's write a piece of conditional code below:"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 16,
56 | "metadata": {},
57 | "outputs": [
58 | {
59 | "name": "stdout",
60 | "output_type": "stream",
61 | "text": [
62 | "the current hour is: 19\n",
63 | "Good afternoon/evening\n",
64 | "Let's carry on with the rest of the lesson...\n"
65 | ]
66 | }
67 | ],
68 | "source": [
69 | "from datetime import datetime\n",
70 | "\n",
71 | "hour = datetime.now().hour\n",
72 | "print(\"the current hour is: \", hour)\n",
73 | "\n",
74 | "if hour > 12: \n",
75 | " print(\"Good afternoon/evening\")\n",
76 | "\n",
77 | "print(\"Let's carry on with the rest of the lesson...\")"
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {},
83 | "source": [
84 | "Depending on when you are running your code, you may or may not have received a nice greeting from our program. \n",
85 | "\n",
86 | "## Handling mutually exclusive cases with `if: ` ... `else:` ... \n",
87 | "\n",
88 | "Often we don't just want to handle the case when the condition evaluates to `True` - we may want to run an alternative piece of code when the condition *fails*. In these cases we can use the if-else construct:"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": 18,
94 | "metadata": {},
95 | "outputs": [
96 | {
97 | "name": "stdout",
98 | "output_type": "stream",
99 | "text": [
100 | "Good afternoon/evening\n"
101 | ]
102 | }
103 | ],
104 | "source": [
105 | "if hour > 12: \n",
106 | " print(\"Good afternoon/evening\")\n",
107 | "else:\n",
108 | " print(\"Good morning\")"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "## More than 2 cases with `if: ` ... `elif: `... `else:` ... \n",
116 | "\n",
117 | "Finally, we can check an arbitrary number of mutually exclusive conditions by using if-elif-else. `elif` is short hand for \"else if\". An *if-elif-...-else* construct will always start with an if and typically end with an else. There will never be an else in the middle.\n",
118 | "The reader can probably think about it and recognize why."
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": 20,
124 | "metadata": {},
125 | "outputs": [
126 | {
127 | "name": "stdout",
128 | "output_type": "stream",
129 | "text": [
130 | "Good evening!\n"
131 | ]
132 | }
133 | ],
134 | "source": [
135 | "if hour < 9: \n",
136 | " print(\"Good morning!\")\n",
137 | "elif hour < 12:\n",
138 | " print(\"Good day!\")\n",
139 | "elif hour < 7:\n",
140 | " print(\"Good afternoon!\")\n",
141 | "elif hour < 20:\n",
142 | " print(\"Good evening!\")\n",
143 | "elif hour < 23:\n",
144 | " print(\"Good night!\")\n",
145 | "else:\n",
146 | " print(\"Shouldn't you be asleep? We advise that students maintain a healthy work-life balance.\")\n"
147 | ]
148 | }
149 | ],
150 | "metadata": {
151 | "kernelspec": {
152 | "display_name": "Python 3",
153 | "language": "python",
154 | "name": "python3"
155 | },
156 | "language_info": {
157 | "codemirror_mode": {
158 | "name": "ipython",
159 | "version": 3
160 | },
161 | "file_extension": ".py",
162 | "mimetype": "text/x-python",
163 | "name": "python",
164 | "nbconvert_exporter": "python",
165 | "pygments_lexer": "ipython3",
166 | "version": "3.6.5"
167 | }
168 | },
169 | "nbformat": 4,
170 | "nbformat_minor": 2
171 | }
172 |
--------------------------------------------------------------------------------
/chapter03_control_flow/sec02_looping.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Looping\n",
8 | "\n",
9 | "Now that we have come command of collections, \n",
10 | "it's natural that we approach the topic of looping.\n",
11 | "In [the previous section on conditional (if-then) branching](../sec01_conditionals.ipynb) \n",
12 | "we introduced one powerful way of deciding which blocks of code run and when.\n",
13 | "\n",
14 | "The next step is be able to decide *how many times* to execute a block of code.\n",
15 | "Generally, in programming we call this looping.\n",
16 | "In Python, the main looping constructs are (most common) `for` loops and (less often) `while` loops.\n",
17 | "A `for` loop just takes a collection of items and executes the block of code one time for each element in the list."
18 | ]
19 | },
20 | {
21 | "cell_type": "code",
22 | "execution_count": 3,
23 | "metadata": {},
24 | "outputs": [],
25 | "source": [
26 | "sax_players = ['Lester Young', 'Charlie Parker', 'John Coltrane', 'Sonny Rollins', 'Cannonball Adderley']"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 5,
32 | "metadata": {},
33 | "outputs": [
34 | {
35 | "name": "stdout",
36 | "output_type": "stream",
37 | "text": [
38 | "Executing the block!\n",
39 | "Executing the block!\n",
40 | "Executing the block!\n",
41 | "Executing the block!\n",
42 | "Executing the block!\n"
43 | ]
44 | }
45 | ],
46 | "source": [
47 | "for _ in sax_players:\n",
48 | " print(\"Executing the block!\")"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "Now it's not especially exciting to just do the same *exact* thing $n$ times in a row. \n",
56 | "However we can alter the execution in several ways. \n",
57 | "First, we can alter the state of variables inside each execution of the loop,\n",
58 | "this can, in turn, shape the behavior of each subsequent execution of the loop."
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": 13,
64 | "metadata": {},
65 | "outputs": [
66 | {
67 | "name": "stdout",
68 | "output_type": "stream",
69 | "text": [
70 | "We are entering the loop for the 1st time. The 1th saxophonist is Lester Young\n",
71 | "We are entering the loop for the 2st time. The 2th saxophonist is Charlie Parker\n",
72 | "We are entering the loop for the 3st time. The 3th saxophonist is John Coltrane\n",
73 | "We are entering the loop for the 4st time. The 4th saxophonist is Sonny Rollins\n",
74 | "We are entering the loop for the 5st time. The 5th saxophonist is Cannonball Adderley\n"
75 | ]
76 | }
77 | ],
78 | "source": [
79 | "count = 0\n",
80 | "for _ in sax_players:\n",
81 | " print (\"We are entering the loop for the %sst time. The %sth saxophonist is %s\" \n",
82 | " % (count + 1, count+1, sax_players[count])) \n",
83 | " count += 1"
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": [
90 | "## Combining Conditionals and Loops \n",
91 | "\n",
92 | "Now you might notices that this program is a bit lousy. Nobody writes 1th or 2th or 3th. We typically write \"1st\", \"2nd\", \"3rd\", and then use \"th\" for each of the other digits. \n",
93 | "This simple example demonstrates the power of combining conditionals and loops.\n",
94 | "We can use the loop to pass over many elements, \n",
95 | "then for each one, we can behave differerently depending on the context."
96 | ]
97 | },
98 | {
99 | "cell_type": "code",
100 | "execution_count": 12,
101 | "metadata": {},
102 | "outputs": [
103 | {
104 | "name": "stdout",
105 | "output_type": "stream",
106 | "text": [
107 | "We are entering the loop for the 1st time. The 1st saxophonist is Lester Young\n",
108 | "We are entering the loop for the 2nd time. The 2nd saxophonist is Charlie Parker\n",
109 | "We are entering the loop for the 3rd time. The 3rd saxophonist is John Coltrane\n",
110 | "We are entering the loop for the 4th time. The 4th saxophonist is Sonny Rollins\n",
111 | "We are entering the loop for the 5th time. The 5th saxophonist is Cannonball Adderley\n"
112 | ]
113 | }
114 | ],
115 | "source": [
116 | "count = 0\n",
117 | "for _ in sax_players:\n",
118 | " if count + 1 % 10 == 1:\n",
119 | " suffix = \"st\"\n",
120 | " elif count + 1 % 10 == 2:\n",
121 | " suffix = \"nd\"\n",
122 | " elif count + 1 % 10 == 3:\n",
123 | " suffix = \"rd\"\n",
124 | " else:\n",
125 | " suffix = \"th\"\n",
126 | " \n",
127 | " print (\"We are entering the loop for the %s%s time. The %s%s saxophonist is %s\" \n",
128 | " % (count + 1, suffix, count+1, suffix, sax_players[count])) \n",
129 | " count += 1"
130 | ]
131 | },
132 | {
133 | "cell_type": "markdown",
134 | "metadata": {},
135 | "source": [
136 | "## Bookkeeping with `for` loops\n",
137 | "\n",
138 | "Creating and incrementing our variable `count` and then using it to index into our list is a bit onerous. \n",
139 | "Accessing each element of a list is such a common use case that Python makes it super easy. \n",
140 | "We just use this syntax:\n",
141 | "```\n",
142 | "for var in some_iterable_object:\n",
143 | "```\n",
144 | "Here `var` can be any variable name we want to use to access the current element of the list on each pass through the loop. In fact Python was already returning each element in the `sax_players` list but we were just ignoring it (the the `_` syntax lets us discard a value we have no use for).\n",
145 | "Let's rewrite out code to use this functionality:\n"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": 14,
151 | "metadata": {},
152 | "outputs": [
153 | {
154 | "name": "stdout",
155 | "output_type": "stream",
156 | "text": [
157 | "We are entering the loop for the 1st time. The 1st saxophonist is Lester Young\n",
158 | "We are entering the loop for the 2nd time. The 2nd saxophonist is Charlie Parker\n",
159 | "We are entering the loop for the 3rd time. The 3rd saxophonist is John Coltrane\n",
160 | "We are entering the loop for the 4th time. The 4th saxophonist is Sonny Rollins\n",
161 | "We are entering the loop for the 5th time. The 5th saxophonist is Cannonball Adderley\n"
162 | ]
163 | }
164 | ],
165 | "source": [
166 | "count = 0\n",
167 | "for player in sax_players:\n",
168 | " if count + 1 % 10 == 1:\n",
169 | " suffix = \"st\"\n",
170 | " elif count + 1 % 10 == 2:\n",
171 | " suffix = \"nd\"\n",
172 | " elif count + 1 % 10 == 3:\n",
173 | " suffix = \"rd\"\n",
174 | " else:\n",
175 | " suffix = \"th\"\n",
176 | " \n",
177 | " print (\"We are entering the loop for the %s%s time. The %s%s saxophonist is %s\" \n",
178 | " % (count + 1, suffix, count+1, suffix, player)) \n",
179 | " count += 1"
180 | ]
181 | },
182 | {
183 | "cell_type": "markdown",
184 | "metadata": {},
185 | "source": [
186 | "Now additionally, it's so common that we both want to access both the `count` and also the element, \n",
187 | "that Python provides us with with special tool to access both. "
188 | ]
189 | },
190 | {
191 | "cell_type": "code",
192 | "execution_count": 15,
193 | "metadata": {},
194 | "outputs": [
195 | {
196 | "name": "stdout",
197 | "output_type": "stream",
198 | "text": [
199 | "We are entering the loop for the 0st time. The 1st saxophonist is Lester Young\n",
200 | "We are entering the loop for the 1nd time. The 2nd saxophonist is Charlie Parker\n",
201 | "We are entering the loop for the 2rd time. The 3rd saxophonist is John Coltrane\n",
202 | "We are entering the loop for the 3th time. The 4th saxophonist is Sonny Rollins\n",
203 | "We are entering the loop for the 4th time. The 5th saxophonist is Cannonball Adderley\n"
204 | ]
205 | }
206 | ],
207 | "source": [
208 | "for i, player in enumerate(sax_players):\n",
209 | " if i+1 % 10 == 1:\n",
210 | " suffix = \"st\"\n",
211 | " elif i+1 % 10 == 2:\n",
212 | " suffix = \"nd\"\n",
213 | " elif i+1 % 10 == 3:\n",
214 | " suffix = \"rd\"\n",
215 | " else:\n",
216 | " suffix = \"th\"\n",
217 | " \n",
218 | " print (\"We are entering the loop for the %s%s time. The %s%s saxophonist is %s\" \n",
219 | " % (i, suffix, i+1, suffix, player)) \n"
220 | ]
221 | },
222 | {
223 | "cell_type": "markdown",
224 | "metadata": {},
225 | "source": [
226 | "## Looping $n$ times with `range`\n",
227 | "\n",
228 | "Sometimes we want to iterate for some $n$ times where we don't necessarily care about a particular list that has $n$ elements. Here we can use the `range` function. \n",
229 | "Calling `range(n)` takes some integer `n` and returns an object that we can think of as a list of consecutive numbers that begins at `0` and has length `n` (ending at `n - 1`). We can gain some intutition below:"
230 | ]
231 | },
232 | {
233 | "cell_type": "code",
234 | "execution_count": 17,
235 | "metadata": {},
236 | "outputs": [
237 | {
238 | "name": "stdout",
239 | "output_type": "stream",
240 | "text": [
241 | "0\n",
242 | "1\n",
243 | "2\n",
244 | "3\n",
245 | "4\n",
246 | "5\n",
247 | "6\n",
248 | "7\n",
249 | "8\n",
250 | "9\n"
251 | ]
252 | }
253 | ],
254 | "source": [
255 | "for i in range(10):\n",
256 | " print(i)"
257 | ]
258 | },
259 | {
260 | "cell_type": "markdown",
261 | "metadata": {},
262 | "source": [
263 | "The object returned by range is an iterable object. It looks a lot like a list. It's not exactly a list, but it supports all the operations we care about. We can index into it, and we can get its length. "
264 | ]
265 | },
266 | {
267 | "cell_type": "code",
268 | "execution_count": 32,
269 | "metadata": {},
270 | "outputs": [
271 | {
272 | "name": "stdout",
273 | "output_type": "stream",
274 | "text": [
275 | "\n",
276 | "10\n",
277 | "4\n"
278 | ]
279 | }
280 | ],
281 | "source": [
282 | "print(type(range(10)))\n",
283 | "print(len(range(10)))\n",
284 | "print(range(10)[4])"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {},
290 | "source": [
291 | "We can also call `range` with an arbitrary starting and ending point"
292 | ]
293 | },
294 | {
295 | "cell_type": "code",
296 | "execution_count": 30,
297 | "metadata": {},
298 | "outputs": [
299 | {
300 | "name": "stdout",
301 | "output_type": "stream",
302 | "text": [
303 | "4\n",
304 | "5\n",
305 | "6\n",
306 | "7\n"
307 | ]
308 | }
309 | ],
310 | "source": [
311 | "for i in range(4,8):\n",
312 | " print(i)"
313 | ]
314 | },
315 | {
316 | "cell_type": "markdown",
317 | "metadata": {},
318 | "source": [
319 | "You might notice that range(4,8) is a lot like the slice notation that we used to access into lists.\n",
320 | "However, we cannot in fact index into lists with range objects (vs slice notation).\n",
321 | "If you try to run `x = [\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\"][range(3,5)]` you'll get an error:\n",
322 | "\n",
323 | "```\n",
324 | "TypeError: list indices must be integers or slices, not range\n",
325 | "```"
326 | ]
327 | }
328 | ],
329 | "metadata": {
330 | "kernelspec": {
331 | "display_name": "Python 3",
332 | "language": "python",
333 | "name": "python3"
334 | },
335 | "language_info": {
336 | "codemirror_mode": {
337 | "name": "ipython",
338 | "version": 3
339 | },
340 | "file_extension": ".py",
341 | "mimetype": "text/x-python",
342 | "name": "python",
343 | "nbconvert_exporter": "python",
344 | "pygments_lexer": "ipython3",
345 | "version": "3.6.5"
346 | }
347 | },
348 | "nbformat": 4,
349 | "nbformat_minor": 2
350 | }
351 |
--------------------------------------------------------------------------------
/chapter03_control_flow/sec03_list_comprehensions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# List Comprehensions\n",
8 | "\n",
9 | "Sometimes we want to rapidly transform one list or collection into another. \n",
10 | "Python gives us a rapid way of creating lists with *list comprehensions*.\n",
11 | "The basic syntax is to iterate through some iterable object, \n",
12 | "and for each element evaluate some expression,\n",
13 | "these expressions become the elements of the new list. \n",
14 | "\n",
15 | "Let's start with a simple example. Say we want to make a list consisting of the first `50` odd numbers.\n",
16 | "We can create this list by taking the numbers between 0 and 49, multiplying each by 2 and then adding 1:"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 16,
22 | "metadata": {},
23 | "outputs": [
24 | {
25 | "data": {
26 | "text/plain": [
27 | "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]"
28 | ]
29 | },
30 | "execution_count": 16,
31 | "metadata": {},
32 | "output_type": "execute_result"
33 | }
34 | ],
35 | "source": [
36 | "odds = [(i*2 + 1) for i in range(50)]\n",
37 | "odds[:10]"
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "Alternatively, we can also include a conditional insides a list comprehension.\n",
45 | "This allows us to expres the odds in perhaps a more intuitive way:"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": 20,
51 | "metadata": {},
52 | "outputs": [
53 | {
54 | "data": {
55 | "text/plain": [
56 | "[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]"
57 | ]
58 | },
59 | "execution_count": 20,
60 | "metadata": {},
61 | "output_type": "execute_result"
62 | }
63 | ],
64 | "source": [
65 | "odds = [i for i in range(100) if i % 2 == 1]\n",
66 | "odds[:10]"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "Commonly, we might use list comprehensions to access some desired representation of the data stored in a dictionary. \n",
74 | "As trivial examples, we could access either the keys or values of a dictionary as a list by using a comprehension:"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 21,
80 | "metadata": {},
81 | "outputs": [],
82 | "source": [
83 | "my_dict = {\"Roadster\":200000, \"Model S\":70000, \"Model X\": 100000, \"Model 3\": 35000}"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": 22,
89 | "metadata": {},
90 | "outputs": [],
91 | "source": [
92 | "keys = [key for key in my_dict.keys()]"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 23,
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "values = [my_dict[key] for key in my_dict.keys()]"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "## List comprehensions with tuples\n",
109 | "\n",
110 | "We can even return a list of tuples:"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": 25,
116 | "metadata": {},
117 | "outputs": [
118 | {
119 | "data": {
120 | "text/plain": [
121 | "[('Roadster', 400000),\n",
122 | " ('Model S', 140000),\n",
123 | " ('Model X', 200000),\n",
124 | " ('Model 3', 70000)]"
125 | ]
126 | },
127 | "execution_count": 25,
128 | "metadata": {},
129 | "output_type": "execute_result"
130 | }
131 | ],
132 | "source": [
133 | "actual_prices_after_upgrades = [(key, my_dict[key]*2) for key in my_dict.keys()]\n",
134 | "actual_prices_after_upgrades"
135 | ]
136 | }
137 | ],
138 | "metadata": {
139 | "kernelspec": {
140 | "display_name": "Python 3",
141 | "language": "python",
142 | "name": "python3"
143 | },
144 | "language_info": {
145 | "codemirror_mode": {
146 | "name": "ipython",
147 | "version": 3
148 | },
149 | "file_extension": ".py",
150 | "mimetype": "text/x-python",
151 | "name": "python",
152 | "nbconvert_exporter": "python",
153 | "pygments_lexer": "ipython3",
154 | "version": "3.6.5"
155 | }
156 | },
157 | "nbformat": 4,
158 | "nbformat_minor": 2
159 | }
160 |
--------------------------------------------------------------------------------
/chapter04_functions/sec01_functions_basics.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Functions\n",
8 | "\n",
9 | "We have already encountered a variety of functions.\n",
10 | "These include both stand-alone functions such as `print`\n",
11 | "`len`, `sorted`, `ceil`, `floor`, and `round`,\n",
12 | "and methods (functions associated with specific objects)\n",
13 | "such as the `.upper()` and `.lower()` methods \n",
14 | "that we invoked when manipulating strings.\n",
15 | "\n",
16 | "In fact, it's hard to imagine doing anything \n",
17 | "useful in Python without invoking at least one function.\n",
18 | "For the majority of people, their very first program \n",
19 | "consists of the one line `print(\"Hello world!\")`. \n",
20 | "\n",
21 | "Until now we've been using functions \n",
22 | "without concerning ourselves with what precisely they *are*.\n",
23 | "In this notebook, we'll finally get into the nuts and bolts\n",
24 | "but defining our own functions. \n",
25 | "\n",
26 | "Each function is introduced using the word `def ():`\n",
27 | "followed by a code block (indented just as \n",
28 | "with the bodies of loops and conditionals).\n",
29 | "To start, we'll introduce a function \n",
30 | "that takes no inputs and returns no outputs."
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": null,
36 | "metadata": {},
37 | "outputs": [],
38 | "source": [
39 | "def greet():\n",
40 | " print(\"Hello world\")"
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "### Invoking a function\n",
48 | "Now that we have defined the function, \n",
49 | "we can invoke it from anywhere in our code.\n",
50 | "Note that the function must be defined (as above)\n",
51 | "before the line of code that invokes it.\n",
52 | "The function name itself is now a variable\n",
53 | "that lives in the name space."
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {},
60 | "outputs": [],
61 | "source": [
62 | "greet"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "And we can invoke the function by using the same \n",
70 | "parentheses syntax that we have used to invoke \n",
71 | "other functions that we did not define ourselves:"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {},
78 | "outputs": [],
79 | "source": [
80 | "greet()"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "### Functions that return values\n",
88 | "Note that while the greet function takes an action \n",
89 | "(sending data to be printed to standard out),\n",
90 | "it does not actually return any value. \n",
91 | "In other words the expressions `greet()`\n",
92 | "returns only the default value `None` as seen below:"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "x = greet()\n",
102 | "print(x)"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "If we want to return a value such that the function call \n",
110 | "can function syntactically as an expression we can use the return statement."
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "metadata": {},
117 | "outputs": [],
118 | "source": [
119 | "def greet2():\n",
120 | " return \"Hello\""
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "execution_count": null,
126 | "metadata": {},
127 | "outputs": [],
128 | "source": [
129 | "statement = greet2() + \" friend!\"\n",
130 | "print(statement)"
131 | ]
132 | },
133 | {
134 | "cell_type": "markdown",
135 | "metadata": {},
136 | "source": [
137 | "### Making functions useful\n",
138 | "To make functions actually useful, \n",
139 | "you will typically want to the body \n",
140 | "of the function to actually do something.\n",
141 | "For example, below, we can use conditionals \n",
142 | "and the time package to write a function \n",
143 | "that checks the time of day and returns \n",
144 | "a greeting appropriate to the hour."
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {},
151 | "outputs": [],
152 | "source": [
153 | "import time \n",
154 | "def timely_greet():\n",
155 | " hour = time.localtime()[3]\n",
156 | " if (hour > 12) and (hour < 18):\n",
157 | " return(\"Good afternoon\")\n",
158 | " elif hour >= 18:\n",
159 | " return(\"Good evening\")\n",
160 | " else:\n",
161 | " return \"Good morning\"\n",
162 | " \n",
163 | " \n",
164 | " "
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "### Function that take arguments\n",
172 | "\n",
173 | "While we can write some useful functions \n",
174 | "that don't require input from the user,\n",
175 | "more often we want functions that act \n",
176 | "in a context-dependent fashion. \n",
177 | "\n",
178 | "We accomplish this by passing arguments to the function.\n",
179 | "To write a function that takes an argument as input,\n",
180 | "we just put the argument inside the parenthesis\n",
181 | "when declaring the function."
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "metadata": {},
188 | "outputs": [],
189 | "source": [
190 | "def greet3(name):\n",
191 | " print(\"Hello %s!\" % name)"
192 | ]
193 | },
194 | {
195 | "cell_type": "code",
196 | "execution_count": null,
197 | "metadata": {},
198 | "outputs": [],
199 | "source": [
200 | "greet3(\"Caroline\")"
201 | ]
202 | },
203 | {
204 | "cell_type": "markdown",
205 | "metadata": {},
206 | "source": [
207 | "Note that the argument `name` could have been any variable name. \n",
208 | "The chocie `name` was appropriate because of the function \n",
209 | "that it serves in our program, but we could have called it `pickle_rick`\n",
210 | "and our function would function in the exact same way."
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": null,
216 | "metadata": {},
217 | "outputs": [],
218 | "source": [
219 | "def greet4(pickle_rick):\n",
220 | " print(\"Hello %s!\" % pickle_rick)\n",
221 | "greet4(\"Caroline\")"
222 | ]
223 | },
224 | {
225 | "cell_type": "markdown",
226 | "metadata": {},
227 | "source": [
228 | "Inside the fuction body, all arguments that were supplied\n",
229 | "when the functino was invoked are available and accessed \n",
230 | "by the name that we gave to the function when writing its signature."
231 | ]
232 | },
233 | {
234 | "cell_type": "markdown",
235 | "metadata": {},
236 | "source": [
237 | "### Multiple arguments\n",
238 | "\n",
239 | "Often we will want functions that act upon \n",
240 | "multiple inputs to produce some desired output.\n",
241 | "For example, to calculate the amount of money\n",
242 | "we expect to have when an investment matures\n",
243 | "might depend on the principal, the interest rate,\n",
244 | "and the duration of the investment. "
245 | ]
246 | },
247 | {
248 | "cell_type": "code",
249 | "execution_count": null,
250 | "metadata": {},
251 | "outputs": [],
252 | "source": [
253 | "def final_amount(principal, interest, years):\n",
254 | " return principal * (1 + interest/100) ** years\n",
255 | "final_amount(100000, 6, 10)"
256 | ]
257 | },
258 | {
259 | "cell_type": "markdown",
260 | "metadata": {},
261 | "source": [
262 | "### Multiple return values \n",
263 | "\n",
264 | "We also often want functions to return multiple values.\n",
265 | "For example, we can do this by either returning \n",
266 | "a collection containing or the values, \n",
267 | "or by invoking `return x, y` which will return them as a tuple."
268 | ]
269 | },
270 | {
271 | "cell_type": "markdown",
272 | "metadata": {},
273 | "source": [
274 | "### Default values for arguments\n",
275 | "Sometimes, especially in machine learning,\n",
276 | "we will want to have arguments that default\n",
277 | "to some reasonable value but which can optionally be set.\n",
278 | "In these cases we can use a signature\n",
279 | "that looks like `def func(argname=value):`.\n",
280 | "Say for example that most investments lasted 10 years,\n",
281 | "and that we wanted our code to assume this unless otherewise stated.\n",
282 | "Note that default arguments must follow the non-default arguments."
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "execution_count": null,
288 | "metadata": {},
289 | "outputs": [],
290 | "source": [
291 | "def final_amount2(principal, interest = 0., years=10):\n",
292 | " return principal * (1 + interest/100) ** years\n",
293 | "print(final_amount2(100000, 6))\n",
294 | "print(final_amount2(100000, 6, 10))"
295 | ]
296 | },
297 | {
298 | "cell_type": "markdown",
299 | "metadata": {},
300 | "source": [
301 | "You can also access a subset of default arguments by name,\n",
302 | "and you can even access the arguments in a different order."
303 | ]
304 | },
305 | {
306 | "cell_type": "code",
307 | "execution_count": null,
308 | "metadata": {},
309 | "outputs": [],
310 | "source": [
311 | "final_amount2(100000, years=5, interest=10)"
312 | ]
313 | },
314 | {
315 | "cell_type": "markdown",
316 | "metadata": {},
317 | "source": [
318 | "Note that you can access any argument by its name, \n",
319 | "not just those that have a default value."
320 | ]
321 | },
322 | {
323 | "cell_type": "markdown",
324 | "metadata": {},
325 | "source": [
326 | "## Flexible Function Signatures\n",
327 | "\n",
328 | "Sometimes we do not know a priori how many arguments \n",
329 | "our function will be receiving at deployment time.\n",
330 | "If our function is such that it can handle some \n",
331 | "arbitrary set of specified arguments (like `print`),\n",
332 | "we can let this be known by using `*args` and `**kwargs`\n",
333 | "in the function signature to receive regular arguments\n",
334 | "and named *keyword arguments*, respectively.\n",
335 | " * `*args`\n",
336 | " * `**kwargs`\n",
337 | " * Nice simple reference: http://book.pythontips.com/en/latest/args_and_kwargs.html"
338 | ]
339 | },
340 | {
341 | "cell_type": "code",
342 | "execution_count": null,
343 | "metadata": {},
344 | "outputs": [],
345 | "source": [
346 | "# Example of *args\n",
347 | "def fn1(*args):\n",
348 | " print(\"\\nfn1 output:\")\n",
349 | " print(args)\n",
350 | "\n",
351 | "def fn2(**kwargs):\n",
352 | " print(\"\\nfn2 output:\")\n",
353 | " print(kwargs)\n",
354 | "\n",
355 | "def fn3(*args, **kwargs):\n",
356 | " print(\"\\nfn3 output:\")\n",
357 | " print(\"these are the args\", args)\n",
358 | " print(\"these are the kwargs\", kwargs)\n",
359 | "\n",
360 | "fn1(1,2,3,4,5) \n",
361 | "fn2(a=1,b=2,c=3)\n",
362 | "fn3(1, \"a\", 2, \"b\", 3, \"c\", name1=\"Bob\", name2=\"Margaret\")"
363 | ]
364 | },
365 | {
366 | "cell_type": "markdown",
367 | "metadata": {},
368 | "source": [
369 | "## Anomymous functions\n",
370 | "One more exotic behavior that you might \n",
371 | "want to know about at some point \n",
372 | "is the anonymous functions, which are introduced\n",
373 | "with `lambda` statements with syntax like \n",
374 | "`lambda x: statement`.\n",
375 | "If we just run such an expression we see that \n",
376 | "it ***is*** a function."
377 | ]
378 | },
379 | {
380 | "cell_type": "code",
381 | "execution_count": null,
382 | "metadata": {},
383 | "outputs": [],
384 | "source": [
385 | "lambda x: x ** 2"
386 | ]
387 | },
388 | {
389 | "cell_type": "markdown",
390 | "metadata": {},
391 | "source": [
392 | "We can invoke that function just as we would any function,\n",
393 | "using the parenthesis syntax."
394 | ]
395 | },
396 | {
397 | "cell_type": "code",
398 | "execution_count": null,
399 | "metadata": {},
400 | "outputs": [],
401 | "source": [
402 | "(lambda x: x ** 2)(9)"
403 | ]
404 | },
405 | {
406 | "cell_type": "markdown",
407 | "metadata": {},
408 | "source": [
409 | "We can also assign a `lambda` function to a variable."
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": null,
415 | "metadata": {},
416 | "outputs": [],
417 | "source": [
418 | "sq = lambda x: x ** 2\n",
419 | "sq(9)"
420 | ]
421 | },
422 | {
423 | "cell_type": "markdown",
424 | "metadata": {},
425 | "source": [
426 | "## Python generators\n",
427 | "Sometimes we want to write a function that can be invoked like a list\n",
428 | "where it can be called as the argument to a for loop\n",
429 | "and pass back a value to the caller without losing its state\n",
430 | "and then pass the next value when the caller asks for it. \n",
431 | "In these contexts we can use `yield` (vs `return`)\n",
432 | "to pass values back ot the caller.\n",
433 | "\n",
434 | "In short:\n",
435 | " * `return` sends a complete value back to caller\n",
436 | " * `yield` returns an iterable, passes each value back to the caller in sequence, saving enough state to complete the subsequent values when asked for them\n",
437 | " \n",
438 | "Here's a simple example:"
439 | ]
440 | },
441 | {
442 | "cell_type": "code",
443 | "execution_count": null,
444 | "metadata": {},
445 | "outputs": [],
446 | "source": [
447 | "def all_the_numbers():\n",
448 | " i = 1\n",
449 | " while True:\n",
450 | " yield i\n",
451 | " i += 1"
452 | ]
453 | },
454 | {
455 | "cell_type": "markdown",
456 | "metadata": {},
457 | "source": [
458 | "If you uncomment and run the code below, you will find that it will start printing values to screen even though the function itself is an infinite loop and thus would never return!"
459 | ]
460 | },
461 | {
462 | "cell_type": "code",
463 | "execution_count": null,
464 | "metadata": {},
465 | "outputs": [],
466 | "source": [
467 | "for ind in all_the_numbers():\n",
468 | " print(ind)\n",
469 | " if ind > 10:\n",
470 | " break"
471 | ]
472 | },
473 | {
474 | "cell_type": "markdown",
475 | "metadata": {},
476 | "source": [
477 | "## Docstrings\n",
478 | "As a final note, you might recall that for most objects \n",
479 | "and methods that we introspect in Jupyter, we can \n",
480 | "get a bunch of information about them by \n",
481 | "checking the data in their `__doc__` attribute. \n",
482 | "We can populate a function's `__doc__` attribute\n",
483 | "by placing a docstring directly below the signature.\n",
484 | "\n",
485 | "Docstrings are an important because they\n",
486 | " * Describes behavior of the function so people using your function know what it does.\n",
487 | " * Can be accessed via __doc__ when introspecting a program\n",
488 | " * Can be used to programatically generate HTML documentation for your code/library.\n",
489 | "\n",
490 | "A simple example of a docstring:"
491 | ]
492 | },
493 | {
494 | "cell_type": "code",
495 | "execution_count": null,
496 | "metadata": {},
497 | "outputs": [],
498 | "source": [
499 | "def cels_to_fahr(cels):\n",
500 | " \"This function takes in a parameter @cels and converts it to Fahrenheit.\"\n",
501 | " return cels * 9/5 + 32\n",
502 | "\n",
503 | "cels_to_fahr.__doc__"
504 | ]
505 | },
506 | {
507 | "cell_type": "markdown",
508 | "metadata": {},
509 | "source": [
510 | "A more complicated docstring like you might see \n",
511 | "in a real library might look more as follows:"
512 | ]
513 | },
514 | {
515 | "cell_type": "code",
516 | "execution_count": null,
517 | "metadata": {},
518 | "outputs": [],
519 | "source": [
520 | "def check_length(length: int, string: str) -> bool:\n",
521 | " \"\"\"Example function with PEP 484 type annotations.\n",
522 | "\n",
523 | " Args:\n",
524 | " length: The desired length against which the string's actual length will be checked.\n",
525 | " string: The string whose length we are checking. \n",
526 | "\n",
527 | " Returns:\n",
528 | " True if the length of the `string` is `length`, False otherwise. \n",
529 | " \"\"\"\n",
530 | " \n",
531 | " return(len(string) == length)"
532 | ]
533 | },
534 | {
535 | "cell_type": "code",
536 | "execution_count": null,
537 | "metadata": {},
538 | "outputs": [],
539 | "source": [
540 | "check_length.__doc__"
541 | ]
542 | }
543 | ],
544 | "metadata": {
545 | "kernelspec": {
546 | "display_name": "Python 3",
547 | "language": "python",
548 | "name": "python3"
549 | },
550 | "language_info": {
551 | "codemirror_mode": {
552 | "name": "ipython",
553 | "version": 3
554 | },
555 | "file_extension": ".py",
556 | "mimetype": "text/x-python",
557 | "name": "python",
558 | "nbconvert_exporter": "python",
559 | "pygments_lexer": "ipython3",
560 | "version": "3.7.4"
561 | }
562 | },
563 | "nbformat": 4,
564 | "nbformat_minor": 2
565 | }
566 |
--------------------------------------------------------------------------------
/chapter05_classes/sec01_classes.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Classes\n",
8 | "\n",
9 | "Much as we couldn't do anything in Python without functions\n",
10 | "but only just introduced them in the previuos notebook,\n",
11 | "we truly cannot do anything in Python without objects\n",
12 | "because in Python, everything is an object! \n",
13 | "\n",
14 | "In this notebook, we'll finally get \n",
15 | "a more formal sense of what objects are,\n",
16 | "get to see where objects come from,\n",
17 | "and learn how to define new types of objects.\n",
18 | "\n",
19 | "The key idea of *classes* and *objects* are\n",
20 | " * To group together a set of values and a set of functions that act upon them.\n",
21 | " * To define a generic type and then create specific instances of that type.\n",
22 | "\n",
23 | "We define a new class using the `class ` syntax.\n",
24 | "In general, class names should always be capitalized.\n",
25 | "We can create a very simple class below to represent a person:"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": 23,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "class Person:\n",
35 | " name = \"No name yet\""
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "Now we can create specific instances of this simple class \n",
43 | "using the syntax `Person()`. \n",
44 | "The act of creating an instance \n",
45 | "is aptly called *instantiation*."
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": 25,
51 | "metadata": {},
52 | "outputs": [],
53 | "source": [
54 | "marcy = Person()\n",
55 | "nancy = Person()"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "We can check that `marcy` and `nancy` \n",
63 | "are two distinct objects both of type `Person`."
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": 26,
69 | "metadata": {},
70 | "outputs": [
71 | {
72 | "name": "stdout",
73 | "output_type": "stream",
74 | "text": [
75 | "marcy id: 4449875472\n",
76 | "nancy id: 4449874640\n"
77 | ]
78 | }
79 | ],
80 | "source": [
81 | "print(\"marcy id: \", id(marcy))\n",
82 | "print(\"nancy id: \", id(nancy))"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": 28,
88 | "metadata": {},
89 | "outputs": [
90 | {
91 | "name": "stdout",
92 | "output_type": "stream",
93 | "text": [
94 | "marcy's type: \n",
95 | "nancy's type \n"
96 | ]
97 | }
98 | ],
99 | "source": [
100 | "print(\"marcy's type:\", type(marcy))\n",
101 | "print(\"nancy's type\", type(nancy))"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "Next, we can check that each has a name attribute,\n",
109 | "and we can overwrite each to have a more fitting `name`."
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 31,
115 | "metadata": {},
116 | "outputs": [
117 | {
118 | "name": "stdout",
119 | "output_type": "stream",
120 | "text": [
121 | "No name yet\n",
122 | "No name yet\n"
123 | ]
124 | }
125 | ],
126 | "source": [
127 | "print(marcy.name)\n",
128 | "print(nancy.name)"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": 32,
134 | "metadata": {},
135 | "outputs": [
136 | {
137 | "name": "stdout",
138 | "output_type": "stream",
139 | "text": [
140 | "Marcy\n",
141 | "Nancy\n"
142 | ]
143 | }
144 | ],
145 | "source": [
146 | "marcy.name = \"Marcy\"\n",
147 | "nancy.name = \"Nancy\"\n",
148 | "print(marcy.name)\n",
149 | "print(nancy.name)"
150 | ]
151 | },
152 | {
153 | "cell_type": "markdown",
154 | "metadata": {},
155 | "source": [
156 | "### The constructor\n",
157 | "Rather than first creating an object and \n",
158 | "then having to do all th work to make it bespoke,\n",
159 | "we can pass in a set of values that will be used\n",
160 | "to customize the object at the time it is constructed.\n",
161 | "The syntax for this involves defining an `__init__()` method.\n",
162 | "Note that for all methods, the first argument is `self`.\n",
163 | "Here self is a reference to that very object!"
164 | ]
165 | },
166 | {
167 | "cell_type": "code",
168 | "execution_count": 33,
169 | "metadata": {},
170 | "outputs": [],
171 | "source": [
172 | "class Person2:\n",
173 | " def __init__(self, name):\n",
174 | " self.name = name"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 34,
180 | "metadata": {},
181 | "outputs": [
182 | {
183 | "name": "stdout",
184 | "output_type": "stream",
185 | "text": [
186 | "Marcy\n"
187 | ]
188 | }
189 | ],
190 | "source": [
191 | "marcy2 = Person2(\"Marcy\")\n",
192 | "print(marcy2.name)"
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "We can store arbitrary data in an object and write arbitrary methods \n",
200 | "for manipulating its data and returning values. \n",
201 | "One common pattern in machine learning is to use\n",
202 | "a class to represent some model family, say a logistic regression model.\n",
203 | "When we instantiate it, we might pass in some specific hyperparameters,\n",
204 | "such as the learning rate, the strength of regularization, \n",
205 | "the chosen optimizer that we would like to use to search for ideal parameters.\n",
206 | "\n",
207 | "Then we would define a variety of methods to do the key jobs\n",
208 | " * `fit(self, X, y)` --- a method that takes in inputs X and outputs y and fits the parametersto that data\n",
209 | " * `predict(X)` --- a method that takes in new inputs X and generates predictions based on the current parameters (these were learned via a call to the `fit` function.\n",
210 | " * `evaluate(X, y)` --- this method would use the current parameters together with the predict functino to generate predictions on the examples X and measure how close they are to supplied labels y. In general, we will want to evaluate the model on different data than were used to train it."
211 | ]
212 | },
213 | {
214 | "cell_type": "markdown",
215 | "metadata": {},
216 | "source": [
217 | "## The String method:\n",
218 | "\n",
219 | "You may have noticed that we can print variety \n",
220 | "of objects to the screen even though they \n",
221 | "are not really strings.\n",
222 | "Some examples include numbers, lists, dictionaries,\n",
223 | "functions, and types. \n",
224 | "\n",
225 | "The abiity to convert an object into a string \n",
226 | "is useful if only for development purposes.\n",
227 | "When running code in a notebook,\n",
228 | "we can find out critical details \n",
229 | "of the object we are looking at\n",
230 | "by printing it to the screen.\n",
231 | "\n",
232 | "The reason why Python knows how to convert an object into a string\n",
233 | "is that for each class, we define its string representation \n",
234 | "in its `__str__()` method. "
235 | ]
236 | },
237 | {
238 | "cell_type": "code",
239 | "execution_count": 36,
240 | "metadata": {},
241 | "outputs": [],
242 | "source": [
243 | "class Student: \n",
244 | " def __init__(self, name):\n",
245 | " # do some stuff\n",
246 | " # name = name # <=== Why can't we do this?\n",
247 | " self.name = name\n",
248 | " def greet(self):\n",
249 | " print(\"hello, my name is\", self.name)\n",
250 | " \n",
251 | " def __str__(self):\n",
252 | " return \"Student: \" + self.name"
253 | ]
254 | },
255 | {
256 | "cell_type": "code",
257 | "execution_count": 39,
258 | "metadata": {},
259 | "outputs": [
260 | {
261 | "name": "stdout",
262 | "output_type": "stream",
263 | "text": [
264 | "Student: Tina\n"
265 | ]
266 | }
267 | ],
268 | "source": [
269 | "tina = Student(\"Tina\")\n",
270 | "print(tina)"
271 | ]
272 | },
273 | {
274 | "cell_type": "markdown",
275 | "metadata": {},
276 | "source": [
277 | "Note that this is different from what we get\n",
278 | "if we print in the last element of Jupyter cell fashion:"
279 | ]
280 | },
281 | {
282 | "cell_type": "code",
283 | "execution_count": 40,
284 | "metadata": {},
285 | "outputs": [
286 | {
287 | "data": {
288 | "text/plain": [
289 | "<__main__.Student at 0x10937db10>"
290 | ]
291 | },
292 | "execution_count": 40,
293 | "metadata": {},
294 | "output_type": "execute_result"
295 | }
296 | ],
297 | "source": [
298 | "tina"
299 | ]
300 | },
301 | {
302 | "cell_type": "markdown",
303 | "metadata": {},
304 | "source": [
305 | "## Callable objects!\n",
306 | "Sometimes, it's useful shorthand to be able to call an object like it was a function.\n",
307 | "We can define how an object should behave in this context by defining the `__call__(self, ...)` method.\n",
308 | "Then if we have some instance `x` of the object and we call it on some input `x(inputs)`,\n",
309 | "this will be syntactic sugar for writing `x.__call__(inputs)`."
310 | ]
311 | },
312 | {
313 | "cell_type": "markdown",
314 | "metadata": {},
315 | "source": [
316 | "## Inheritance\n",
317 | "One important idea in object-oriented programmin is inheritance.\n",
318 | "The main idea here is that we can make a subtype of an object.\n",
319 | "The subtype will inherit all of the behavior of its parent,\n",
320 | "but we can also add additional behaviors.\n",
321 | "The syntax here is class `NewClass(ParentClass):`.\n",
322 | "If, as below, all we did is then `pass`, \n",
323 | "the subclass would be no different than the parent."
324 | ]
325 | },
326 | {
327 | "cell_type": "code",
328 | "execution_count": 42,
329 | "metadata": {},
330 | "outputs": [],
331 | "source": [
332 | "class Student: \n",
333 | " def __init__(self, name):\n",
334 | " # do some stuff\n",
335 | " # name = name # <=== Why can't we do this?\n",
336 | " self.name = name\n",
337 | " def greet(self):\n",
338 | " print(\"hello, my name is\", self.name)\n",
339 | " \n",
340 | "class Doofus(Student):\n",
341 | " pass"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": 43,
347 | "metadata": {},
348 | "outputs": [
349 | {
350 | "name": "stdout",
351 | "output_type": "stream",
352 | "text": [
353 | "hello, my name is Harry\n"
354 | ]
355 | }
356 | ],
357 | "source": [
358 | "harry = Doofus(\"Harry\")\n",
359 | "harry.greet()"
360 | ]
361 | },
362 | {
363 | "cell_type": "markdown",
364 | "metadata": {},
365 | "source": [
366 | "### Differentiating a child class from its parent\n",
367 | "\n",
368 | "We can differentiate child classes from their parents in the following key ways:\n",
369 | " * By defining an additional function that doesn't exist in the parent.\n",
370 | " * By overwriting a function in the parent with a new version that behaves differently.\n",
371 | " \n",
372 | "### The super() function\n",
373 | "\n",
374 | "Often, when overwriting a parent class's methods, we will want to keep everything that the parent method did but we will want to add some additinoal behavior. \n",
375 | "A common example is that we will want to keep the parent's constructor\n",
376 | "but then add some additinoal functionality to follow. \n",
377 | "We can access the parent class methods by calling super() as follows:"
378 | ]
379 | },
380 | {
381 | "cell_type": "code",
382 | "execution_count": 44,
383 | "metadata": {},
384 | "outputs": [
385 | {
386 | "name": "stdout",
387 | "output_type": "stream",
388 | "text": [
389 | "hello, my name is Harry\n",
390 | "but you can call me Hairy\n"
391 | ]
392 | }
393 | ],
394 | "source": [
395 | "class Doofus(Student):\n",
396 | " def __init__(self, name, nickname):\n",
397 | " self.nickname = nickname\n",
398 | " super().__init__(name)\n",
399 | " def greet(self):\n",
400 | " super().greet()\n",
401 | " print(\"but you can call me\", self.nickname)\n",
402 | " \n",
403 | "harry3 = Doofus(\"Harry\", \"Hairy\")\n",
404 | "harry3.greet()"
405 | ]
406 | }
407 | ],
408 | "metadata": {
409 | "kernelspec": {
410 | "display_name": "Python 3",
411 | "language": "python",
412 | "name": "python3"
413 | },
414 | "language_info": {
415 | "codemirror_mode": {
416 | "name": "ipython",
417 | "version": 3
418 | },
419 | "file_extension": ".py",
420 | "mimetype": "text/x-python",
421 | "name": "python",
422 | "nbconvert_exporter": "python",
423 | "pygments_lexer": "ipython3",
424 | "version": "3.7.4"
425 | }
426 | },
427 | "nbformat": 4,
428 | "nbformat_minor": 2
429 | }
430 |
--------------------------------------------------------------------------------
/chapter07_io/sec01_writing.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "# Take all the elements of this list and write them to a file, with each element separated newlines\n",
10 | "saxophonists = [\"Lester Young\", \"Charlie Parker\", \"John Coltrane\", \"Lee Konitz\", \"Cannonball Adderley\", \"Stan Getz\"]"
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 19,
16 | "metadata": {},
17 | "outputs": [],
18 | "source": [
19 | "f = open(\"saxophonists.txt\", \"w\")"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": 20,
25 | "metadata": {},
26 | "outputs": [],
27 | "source": [
28 | "for sax in saxophonists:\n",
29 | " f.write(sax + \"\\n\")"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 21,
35 | "metadata": {},
36 | "outputs": [],
37 | "source": [
38 | "f.close()"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {},
45 | "outputs": [],
46 | "source": []
47 | }
48 | ],
49 | "metadata": {
50 | "kernelspec": {
51 | "display_name": "Python 3",
52 | "language": "python",
53 | "name": "python3"
54 | },
55 | "language_info": {
56 | "codemirror_mode": {
57 | "name": "ipython",
58 | "version": 3
59 | },
60 | "file_extension": ".py",
61 | "mimetype": "text/x-python",
62 | "name": "python",
63 | "nbconvert_exporter": "python",
64 | "pygments_lexer": "ipython3",
65 | "version": "3.6.5"
66 | }
67 | },
68 | "nbformat": 4,
69 | "nbformat_minor": 2
70 | }
71 |
--------------------------------------------------------------------------------
/chapter07_io/sec02_reading.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Reading from file"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 4,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "with open(\"saxophonists.txt\", \"r\") as f:\n",
17 | " read_text = f.read()\n",
18 | " \n",
19 | "with open(\"saxophonists.txt\", \"r\") as f:\n",
20 | " lines_text = f.readlines()"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": 6,
26 | "metadata": {},
27 | "outputs": [],
28 | "source": [
29 | "saxophonists = read_text.split(\"\\n\")"
30 | ]
31 | },
32 | {
33 | "cell_type": "code",
34 | "execution_count": 8,
35 | "metadata": {},
36 | "outputs": [
37 | {
38 | "name": "stdout",
39 | "output_type": "stream",
40 | "text": [
41 | "['Lester Young', 'Charlie Parker', 'John Coltrane', 'Lee Konitz', 'Cannonball Adderley', 'Stan Getz']\n"
42 | ]
43 | }
44 | ],
45 | "source": [
46 | "saxophonists = saxophonists[:-1]\n",
47 | "print(saxophonists)"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 9,
53 | "metadata": {},
54 | "outputs": [
55 | {
56 | "data": {
57 | "text/plain": [
58 | "['Lester Young\\n',\n",
59 | " 'Charlie Parker\\n',\n",
60 | " 'John Coltrane\\n',\n",
61 | " 'Lee Konitz\\n',\n",
62 | " 'Cannonball Adderley\\n',\n",
63 | " 'Stan Getz\\n']"
64 | ]
65 | },
66 | "execution_count": 9,
67 | "metadata": {},
68 | "output_type": "execute_result"
69 | }
70 | ],
71 | "source": [
72 | "lines_text"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": 11,
78 | "metadata": {},
79 | "outputs": [],
80 | "source": [
81 | "saxophonists2 = [ elem[:-1] for elem in lines_text ]"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": 12,
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "data": {
91 | "text/plain": [
92 | "['Lester Young',\n",
93 | " 'Charlie Parker',\n",
94 | " 'John Coltrane',\n",
95 | " 'Lee Konitz',\n",
96 | " 'Cannonball Adderley',\n",
97 | " 'Stan Getz']"
98 | ]
99 | },
100 | "execution_count": 12,
101 | "metadata": {},
102 | "output_type": "execute_result"
103 | }
104 | ],
105 | "source": [
106 | "saxophonists2"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "metadata": {},
113 | "outputs": [],
114 | "source": []
115 | }
116 | ],
117 | "metadata": {
118 | "kernelspec": {
119 | "display_name": "Python 3",
120 | "language": "python",
121 | "name": "python3"
122 | },
123 | "language_info": {
124 | "codemirror_mode": {
125 | "name": "ipython",
126 | "version": 3
127 | },
128 | "file_extension": ".py",
129 | "mimetype": "text/x-python",
130 | "name": "python",
131 | "nbconvert_exporter": "python",
132 | "pygments_lexer": "ipython3",
133 | "version": "3.6.5"
134 | }
135 | },
136 | "nbformat": 4,
137 | "nbformat_minor": 2
138 | }
139 |
--------------------------------------------------------------------------------
/cheatsheats/python-to-r.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# R basics\n",
8 | "\n",
9 | "We've already mastered some basics of programming using Python. Now we're going to rapidly go through how to port these skills to R.\n",
10 | "\n",
11 | "## Commenting\n",
12 | "Commenting in R is similar to Python, so nothing new to learn here."
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": 10,
18 | "metadata": {},
19 | "outputs": [],
20 | "source": [
21 | "#\n",
22 | "# THIS IS A COMMENT. NOTHING WILL HAPPEN WHEN WE RUN THIS BLOCK!!\n",
23 | "# "
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "## Assignment\n",
31 | "\n",
32 | "R supports three primary ways of performing assignment: '=', '<-', and '<<-'\n",
33 | "The differences among these operators are a bit subtle. \n",
34 | "\n",
35 | "Per [this source], `<-` and `->` can be used anywhere, \n",
36 | "while \"The operators `<<-` and `->>` are normally only used in functions, \n",
37 | "and cause a search to be made through parent environments \n",
38 | "for an existing definition of the variable being assigned\"."
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": 2,
44 | "metadata": {},
45 | "outputs": [
46 | {
47 | "name": "stdout",
48 | "output_type": "stream",
49 | "text": [
50 | "[1] 10\n"
51 | ]
52 | }
53 | ],
54 | "source": [
55 | "x = 10\n",
56 | "print(x)"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": 12,
62 | "metadata": {},
63 | "outputs": [
64 | {
65 | "name": "stdout",
66 | "output_type": "stream",
67 | "text": [
68 | "[1] 12\n",
69 | "[1] 13\n"
70 | ]
71 | }
72 | ],
73 | "source": [
74 | "y <- 12\n",
75 | "print(y)\n",
76 | "13 -> y \n",
77 | "print(y)"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": 14,
83 | "metadata": {},
84 | "outputs": [
85 | {
86 | "name": "stdout",
87 | "output_type": "stream",
88 | "text": [
89 | "[1] 14\n",
90 | "[1] 15\n"
91 | ]
92 | }
93 | ],
94 | "source": [
95 | "z <<- 14\n",
96 | "print(z)\n",
97 | "15 ->> z \n",
98 | "print(z)\n",
99 | "\n",
100 | "\n"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "`<-` is generally preferred over = for \"historical reasons\". \n",
108 | "Also, `<-` can be used to do object assignment in a function call, whereas = will only pass arguments without creating a corresponding object.For example, matrix(1,nrow<-2) creates a variable nrow that can be accessed later, but matrix(1,nrow=2) doesn't."
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "## Lists\n",
116 | "\n",
117 | "There are many ways to create lists in R. One of the most common is the `c` function"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": 16,
123 | "metadata": {},
124 | "outputs": [
125 | {
126 | "name": "stdout",
127 | "output_type": "stream",
128 | "text": [
129 | "[1] 1 2 3 4 5 7 8\n"
130 | ]
131 | }
132 | ],
133 | "source": [
134 | "x <- c(1,2,3,4,5,7,8)\n",
135 | "print(x)"
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {},
141 | "source": [
142 | "***WATCH OUT! *** \n",
143 | "In R, (i) functions are case sensitive, and (ii) some bozo had the idea that it would be reasonable to accept the convention of having clashing functions that have the same name, but for case. So there is a `c` function and a `C` function, a `filter` function and a `Filter` function, these DO NOT do the same thing!\n",
144 | "\n",
145 | "## Accessing and updating list elements\n",
146 | "\n",
147 | "Unlike in Python, R lists are indexed at `1`. We can see that below:"
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": 18,
153 | "metadata": {},
154 | "outputs": [
155 | {
156 | "name": "stdout",
157 | "output_type": "stream",
158 | "text": [
159 | "[1] 15\n",
160 | "[1] 15 2 3 4 5 7 8\n"
161 | ]
162 | }
163 | ],
164 | "source": [
165 | "print(x[1])\n",
166 | "x[1] <- 15\n",
167 | "print(x)"
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "metadata": {},
173 | "source": [
174 | "Moreover, when we access lists with slice notation, the list is inclusive:"
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": 19,
180 | "metadata": {},
181 | "outputs": [
182 | {
183 | "name": "stdout",
184 | "output_type": "stream",
185 | "text": [
186 | "[1] 15 2 3\n"
187 | ]
188 | }
189 | ],
190 | "source": [
191 | "print(x[1:3])"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "To unpack what's going on here let's explain an important detail of R programming.\n",
199 | "Here the `:` operator isn't simply a bit of syntactic sugar used for accessing continuous slices from lists.\n",
200 | "In fact when `start:end` returns a list of consecutive numbers:"
201 | ]
202 | },
203 | {
204 | "cell_type": "code",
205 | "execution_count": 8,
206 | "metadata": {},
207 | "outputs": [
208 | {
209 | "name": "stdout",
210 | "output_type": "stream",
211 | "text": [
212 | "[1] 4 5 6 7\n",
213 | "[1] 7 6 5 4\n",
214 | " [1] -5 -4 -3 -2 -1 0 1 2 3 4 5\n"
215 | ]
216 | }
217 | ],
218 | "source": [
219 | "print(4:7)\n",
220 | "print(7:4)\n",
221 | "print(-5:5)"
222 | ]
223 | },
224 | {
225 | "cell_type": "markdown",
226 | "metadata": {},
227 | "source": [
228 | "Thus, when we use `x[1:3]`, we are really running `x[c(1,2,3)]`"
229 | ]
230 | },
231 | {
232 | "cell_type": "code",
233 | "execution_count": 9,
234 | "metadata": {},
235 | "outputs": [
236 | {
237 | "name": "stdout",
238 | "output_type": "stream",
239 | "text": [
240 | "[1] 15 2 3\n",
241 | "[1] 15 2 3\n"
242 | ]
243 | }
244 | ],
245 | "source": [
246 | "print(x[1:3])\n",
247 | "print(x[c(1,2,3)])"
248 | ]
249 | },
250 | {
251 | "cell_type": "markdown",
252 | "metadata": {},
253 | "source": [
254 | "Moreover, we can access the elements of a list in any arbitrary order:"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": 10,
260 | "metadata": {},
261 | "outputs": [
262 | {
263 | "name": "stdout",
264 | "output_type": "stream",
265 | "text": [
266 | "[1] 5 3 4 2 3 15\n"
267 | ]
268 | }
269 | ],
270 | "source": [
271 | "print(x[c(5,3,4,2,3,1)])"
272 | ]
273 | },
274 | {
275 | "cell_type": "markdown",
276 | "metadata": {},
277 | "source": [
278 | "## Combining lists\n",
279 | "\n",
280 | "### Adding lists\n",
281 | "Note that adding two lists with the `+` operator in R is like adding two numpy arrays (vector addition). "
282 | ]
283 | },
284 | {
285 | "cell_type": "code",
286 | "execution_count": 21,
287 | "metadata": {},
288 | "outputs": [
289 | {
290 | "name": "stdout",
291 | "output_type": "stream",
292 | "text": [
293 | "[1] 4 2 6 4 10 16 11\n"
294 | ]
295 | }
296 | ],
297 | "source": [
298 | "a <- c(1,1,2,3,5,7,9) \n",
299 | "b <- c(3,1,4,1,5,9,2)\n",
300 | "print(a + b)"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "### Concatenation\n",
308 | "Recall that this is different from running `list1 + list2` with ordinary Python lists, \n",
309 | "for which `+` will concatenate the lists.\n",
310 | "We can concatenate the lists by again calling the `c` function with operands `a` and `b`."
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "execution_count": 22,
316 | "metadata": {},
317 | "outputs": [
318 | {
319 | "name": "stdout",
320 | "output_type": "stream",
321 | "text": [
322 | " [1] 1 1 2 3 5 7 9 3 1 4 1 5 9 2\n"
323 | ]
324 | }
325 | ],
326 | "source": [
327 | "print(c(a,b))"
328 | ]
329 | },
330 | {
331 | "cell_type": "markdown",
332 | "metadata": {},
333 | "source": [
334 | "### Length of a list \n",
335 | "We can grab the length of a list by running `length(...)`"
336 | ]
337 | },
338 | {
339 | "cell_type": "code",
340 | "execution_count": 23,
341 | "metadata": {},
342 | "outputs": [
343 | {
344 | "name": "stdout",
345 | "output_type": "stream",
346 | "text": [
347 | "[1] 14\n"
348 | ]
349 | }
350 | ],
351 | "source": [
352 | "print(length(c(a,b)))"
353 | ]
354 | },
355 | {
356 | "cell_type": "markdown",
357 | "metadata": {},
358 | "source": [
359 | "## Basic math\n",
360 | "\n",
361 | "Because R is specifically designed for use in mathematical computation,\n",
362 | "unlike Python where we access math functions via libraries like numpy,\n",
363 | "in R, basic math functions are built in to the language.\n",
364 | "Examples include exponentials, trigonometric functions, etc"
365 | ]
366 | },
367 | {
368 | "cell_type": "code",
369 | "execution_count": 24,
370 | "metadata": {},
371 | "outputs": [
372 | {
373 | "name": "stdout",
374 | "output_type": "stream",
375 | "text": [
376 | "[1] 22026.47\n",
377 | "[1] 0\n",
378 | "[1] 1\n"
379 | ]
380 | }
381 | ],
382 | "source": [
383 | "print(exp(10))\n",
384 | "print(sin(0))\n",
385 | "print(sin(pi/2))"
386 | ]
387 | },
388 | {
389 | "cell_type": "markdown",
390 | "metadata": {},
391 | "source": [
392 | "Note that here, as is typical for R, the language is a bit cluttered,\n",
393 | "and has many ways of doing the exact same thing.\n",
394 | "For example we can calculate powers both with `**` and with `^`:"
395 | ]
396 | },
397 | {
398 | "cell_type": "code",
399 | "execution_count": 26,
400 | "metadata": {},
401 | "outputs": [
402 | {
403 | "name": "stdout",
404 | "output_type": "stream",
405 | "text": [
406 | "[1] 8\n",
407 | "[1] 8\n"
408 | ]
409 | }
410 | ],
411 | "source": [
412 | "print(2 ** 3)\n",
413 | "print(2 ^ 3)"
414 | ]
415 | },
416 | {
417 | "cell_type": "markdown",
418 | "metadata": {},
419 | "source": [
420 | "### Handy Constants\n",
421 | "\n",
422 | "You might have also noticed that in the previous blocks we relied on `pi`, a special constant that is built in to the R language.\n",
423 | "\n",
424 | "## Special numbers\n",
425 | "\n",
426 | "R also has special number Inf, -Inf and NaN (Not a Number).\n",
427 | "It's worth playing around with them to get a feeling for their properties, e.g.:"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": 27,
433 | "metadata": {},
434 | "outputs": [
435 | {
436 | "name": "stdout",
437 | "output_type": "stream",
438 | "text": [
439 | "[1] Inf\n"
440 | ]
441 | }
442 | ],
443 | "source": [
444 | "print(Inf * Inf)"
445 | ]
446 | },
447 | {
448 | "cell_type": "code",
449 | "execution_count": 28,
450 | "metadata": {},
451 | "outputs": [
452 | {
453 | "name": "stdout",
454 | "output_type": "stream",
455 | "text": [
456 | "[1] NaN\n"
457 | ]
458 | }
459 | ],
460 | "source": [
461 | "print(Inf + -Inf)"
462 | ]
463 | },
464 | {
465 | "cell_type": "code",
466 | "execution_count": 29,
467 | "metadata": {},
468 | "outputs": [
469 | {
470 | "name": "stdout",
471 | "output_type": "stream",
472 | "text": [
473 | "[1] -Inf\n"
474 | ]
475 | }
476 | ],
477 | "source": [
478 | "print(Inf * -Inf)"
479 | ]
480 | },
481 | {
482 | "cell_type": "markdown",
483 | "metadata": {},
484 | "source": [
485 | "A number of built-in functions can check for special values. These include `is.finite()`, `is.infinite()`, `is.nan()`, `is.na()`."
486 | ]
487 | },
488 | {
489 | "cell_type": "markdown",
490 | "metadata": {},
491 | "source": [
492 | "## Strings \n",
493 | "\n",
494 | "Unlike Python R does not allow us to concatenate strings with a conveient command like `+`. Instead, we must use the `paste()` function. The basic syntax is `paste(a,b,...)`.\n"
495 | ]
496 | },
497 | {
498 | "cell_type": "code",
499 | "execution_count": 30,
500 | "metadata": {},
501 | "outputs": [
502 | {
503 | "name": "stdout",
504 | "output_type": "stream",
505 | "text": [
506 | "[1] \"Hello, World!\"\n"
507 | ]
508 | }
509 | ],
510 | "source": [
511 | "x <- \"Hello, \"\n",
512 | "y <- \"World!\"\n",
513 | "print(paste(x,y))"
514 | ]
515 | },
516 | {
517 | "cell_type": "markdown",
518 | "metadata": {},
519 | "source": [
520 | "The `paste()` function also can take an optional argument `sep` if we want to add a specified separator (often called a delimiter) between our concatenated strings:"
521 | ]
522 | },
523 | {
524 | "cell_type": "code",
525 | "execution_count": 31,
526 | "metadata": {},
527 | "outputs": [
528 | {
529 | "name": "stdout",
530 | "output_type": "stream",
531 | "text": [
532 | "[1] \"Hello, ||World!\"\n"
533 | ]
534 | }
535 | ],
536 | "source": [
537 | "print(paste(x,y, sep=\"||\"))"
538 | ]
539 | },
540 | {
541 | "cell_type": "markdown",
542 | "metadata": {},
543 | "source": [
544 | "## Functions\n",
545 | "\n",
546 | "There are some key differences in how to define functions in R vs in Python. To start, the syntax to declare a function may seem a bit funky to a C/Python/Java native. Here, the natural way to define a function is to create an *anonymous function* and to assign it to a variable through a conventional assignment operation. Next, there is no explicit `return` statement. Instead, the last value calculated in the body of the function is taken to be its return value."
547 | ]
548 | },
549 | {
550 | "cell_type": "code",
551 | "execution_count": 34,
552 | "metadata": {},
553 | "outputs": [
554 | {
555 | "name": "stdout",
556 | "output_type": "stream",
557 | "text": [
558 | "[1] 100\n"
559 | ]
560 | }
561 | ],
562 | "source": [
563 | "square <- function (n)\n",
564 | "{\n",
565 | " n * n\n",
566 | "}\n",
567 | "print(square(10))"
568 | ]
569 | },
570 | {
571 | "cell_type": "markdown",
572 | "metadata": {},
573 | "source": [
574 | "## For loops\n",
575 | "For loops are rather similar to Python but slightly more verbsose. The ` in ` must be enclosed in parentheses and the code block that is executed on each iteration must be enclosed with curly braces `{...}` as with function calls."
576 | ]
577 | },
578 | {
579 | "cell_type": "code",
580 | "execution_count": 36,
581 | "metadata": {},
582 | "outputs": [
583 | {
584 | "name": "stdout",
585 | "output_type": "stream",
586 | "text": [
587 | "[1] \"we have entered the loop for the iteration # 1\"\n",
588 | "[1] \"we have entered the loop for the iteration # 2\"\n",
589 | "[1] \"we have entered the loop for the iteration # 3\"\n",
590 | "[1] \"we have entered the loop for the iteration # 4\"\n",
591 | "[1] \"we have entered the loop for the iteration # 5\"\n",
592 | "[1] \"we have entered the loop for the iteration # 6\"\n",
593 | "[1] \"we have entered the loop for the iteration # 7\"\n",
594 | "[1] \"we have entered the loop for the iteration # 8\"\n",
595 | "[1] \"we have entered the loop for the iteration # 9\"\n",
596 | "[1] \"we have entered the loop for the iteration # 10\"\n"
597 | ]
598 | }
599 | ],
600 | "source": [
601 | "for (i in 1:10)\n",
602 | "{\n",
603 | " print(paste(\"we have entered the loop for the iteration #\", i))\n",
604 | "}"
605 | ]
606 | },
607 | {
608 | "cell_type": "code",
609 | "execution_count": null,
610 | "metadata": {},
611 | "outputs": [],
612 | "source": []
613 | },
614 | {
615 | "cell_type": "code",
616 | "execution_count": null,
617 | "metadata": {},
618 | "outputs": [],
619 | "source": []
620 | }
621 | ],
622 | "metadata": {
623 | "kernelspec": {
624 | "display_name": "R",
625 | "language": "R",
626 | "name": "ir"
627 | },
628 | "language_info": {
629 | "codemirror_mode": "r",
630 | "file_extension": ".r",
631 | "mimetype": "text/x-r-source",
632 | "name": "R",
633 | "pygments_lexer": "r",
634 | "version": "3.3.1"
635 | }
636 | },
637 | "nbformat": 4,
638 | "nbformat_minor": 2
639 | }
640 |
--------------------------------------------------------------------------------
/r-demo/R Covidcast Demo.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# R Demo with CovidCast Data\n",
8 | "\n",
9 | "This notebook demonstrates some of the basic functionality in R, using COVIDcast data. COVIDcast provides daily access to a range of COVID-related signals, from sources like symptom surveys and medical claims data, as well as standard signals such as confirmed cases and deaths. To run a cell, either press the green play button in the top right corner or press Cmd + Shift + Enter with your cursor in the cell.\n",
10 | "\n",
11 | "If you haven't installed a package you need, install it using `install.packages(PACKAGE_NAME)`. In this tutorial, we'll primarily be working with packages in tidyverse (this includes dplyr for manipulating data, and ggplot2 for plotting)."
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": null,
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "# You only ever need to run this once\n",
21 | "# install.packages(\"tidyverse\")"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {},
27 | "source": [
28 | "Here are the specific packages we'll be using in this tutorial:"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "metadata": {},
35 | "outputs": [],
36 | "source": [
37 | "library(dplyr)\n",
38 | "library(ggplot2)"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "## Load Data\n",
46 | "First, let's load the COVIDcast data as an R dataframe and look at its first few rows. \n",
47 | "Note that the data_source is fb-survey\n",
48 | "(responses to a Facebook survey on symptoms each user is facing), \n",
49 | "and the signal is smoothed-cli (smoothed signal indicating COVID-like illness)."
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": null,
55 | "metadata": {},
56 | "outputs": [],
57 | "source": [
58 | "# We're using an excerpt of the COVIDcast dataset. Load the csv into an R dataframe below:\n",
59 | "df <- read.csv('covidcast_cli_data.csv')\n",
60 | "\n",
61 | "# cast columns containing dates into date types\n",
62 | "df$time_value <- as.Date(df$time_value)\n",
63 | "df$issue <- as.Date(df$issue)\n",
64 | "\n",
65 | "df$geo_value <- as.character(df$geo_value)\n",
66 | "\n",
67 | "# In this tutorial we're only looking at the COVID-like Ilness (CLI) signal. \n",
68 | "# If you'd like to play with the entire COVIDcast API, install the package and load the data by uncommenting and running the following commands:\n",
69 | "\n",
70 | "# devtools::install_github(\"cmu-delphi/covidcast\", ref = \"main\",\n",
71 | "# subdir = \"R-packages/covidcast\") # the covidcast package is not on CRAN yet, so it can be installed using the devtools package:\n",
72 | "# library(covidcast)\n",
73 | "# df <- suppressMessages(\n",
74 | "# covidcast_signal(data_source = \"fb-survey\", signal = \"smoothed_cli\",\n",
75 | "# start_day = \"2020-05-01\", end_day = \"2020-12-01\",\n",
76 | "# geo_type = \"state\")\n",
77 | "# )\n",
78 | "\n",
79 | "df[1:10,]"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "Right now, there are several columns in the dataset \n",
87 | "(here's the documentation which includes their meanings: https://cmu-delphi.github.io/covidcast/covidcastR/reference/covidcast_signal.html).\n",
88 | "Let's create a new dataframe with only the columns we care about for the sake of this analysis. \n",
89 | "To do so, we'll be using the `%>%` operator which ``pipes\" the data \n",
90 | "through from the left hand side into a `select(...)` function on the right hand side.\n",
91 | "Below, we select columns for: \n",
92 | "\n",
93 | "* geo_value: the state\n",
94 | "* time_value: the date\n",
95 | "* value: the value for the smoothed CLI signal\n",
96 | "* stderr: standard error for that value\n",
97 | "* sample_size: sample size available in that geography on that day"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": [
106 | "df <- df %>% select(geo_value, time_value, value, stderr, sample_size)\n",
107 | "\n",
108 | "head(df)"
109 | ]
110 | },
111 | {
112 | "cell_type": "markdown",
113 | "metadata": {},
114 | "source": [
115 | "## Basic data operations\n",
116 | "Let's get some basic information about this data:"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": null,
122 | "metadata": {},
123 | "outputs": [],
124 | "source": [
125 | "# is there any missing data?\n",
126 | "sum(df %>% is.na()) # answer: no\n",
127 | "\n",
128 | "# what's the date range?\n",
129 | "min(df$time_value)\n",
130 | "max(df$time_value) # answer: 5/1/20 to 12/1/20\n",
131 | "\n",
132 | "# what are the unique geo values?\n",
133 | "df %>% select(geo_value) %>% unique() # answer: 52; includes Puerto Rico (pr) and Washington D.C. (dc) as separate states"
134 | ]
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": [
140 | "In exploratory data analysis, it is important to define questions which drive your analysis. In this case, suppose we would like to ask: \"Which states have the most data?\"\n",
141 | "To get a ranked list of the states and their corresponding total sample sizes, we can group the data frame by `geo_value` and sum the `sample_size` values in each group, and then sort by descending total sample size:"
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "execution_count": null,
147 | "metadata": {},
148 | "outputs": [],
149 | "source": [
150 | "state_sample_sizes <- df %>% \n",
151 | " group_by(geo_value) %>%\n",
152 | " summarize(total_sample_size = sum(sample_size)) %>% # compute the sum of sample_sizes for each geo_value\n",
153 | " arrange(-total_sample_size) # order from greatest total_sample_size to least\n",
154 | "\n",
155 | "state_sample_sizes[1:10,]"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "Let's take the top five states with the most data (in this case, it corresponds to the most Facebook survey responses)."
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {},
169 | "outputs": [],
170 | "source": [
171 | "top5 <- (state_sample_sizes[1:5,])$geo_value\n",
172 | "print(top5)"
173 | ]
174 | },
175 | {
176 | "cell_type": "markdown",
177 | "metadata": {},
178 | "source": [
179 | "## Plotting\n",
180 | "The ggplot2 package works well with dplyr, letting you create beautiful plots with just a few lines of code. On the flip side, if you'd like something other than the defaults it may take some finagling. \n",
181 | "Below is an example of how to plot the top five states' CLI values over the entire time range:"
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "metadata": {},
188 | "outputs": [],
189 | "source": [
190 | "df %>%\n",
191 | " filter(geo_value %in% top5) %>%\n",
192 | " ggplot(aes(x=time_value, y=value, color=geo_value)) +\n",
193 | " geom_line() +\n",
194 | " ggtitle('CLI signal in top five states with the most data') +\n",
195 | " xlab('Date') +\n",
196 | " ylab('CLI Smoothed Signal') +\n",
197 | " scale_x_date(date_labels=\"%b\",date_breaks=\"1 month\")"
198 | ]
199 | },
200 | {
201 | "cell_type": "markdown",
202 | "metadata": {},
203 | "source": [
204 | "To provide some context, we can also look at how much survey data was collected in each state over time:\n"
205 | ]
206 | },
207 | {
208 | "cell_type": "code",
209 | "execution_count": null,
210 | "metadata": {},
211 | "outputs": [],
212 | "source": [
213 | "df %>%\n",
214 | " filter(geo_value %in% top5) %>%\n",
215 | " ggplot(aes(x=time_value, y=sample_size, color=geo_value)) +\n",
216 | " geom_line() +\n",
217 | " ggtitle('Sample size from each state of the top five states by sample size') +\n",
218 | " xlab('Date') +\n",
219 | " ylab('Sample size') +\n",
220 | " scale_x_date(date_labels=\"%b\",date_breaks=\"1 month\")"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": null,
226 | "metadata": {},
227 | "outputs": [],
228 | "source": []
229 | }
230 | ],
231 | "metadata": {
232 | "kernelspec": {
233 | "display_name": "R",
234 | "language": "R",
235 | "name": "ir"
236 | },
237 | "language_info": {
238 | "codemirror_mode": "r",
239 | "file_extension": ".r",
240 | "mimetype": "text/x-r-source",
241 | "name": "R",
242 | "pygments_lexer": "r",
243 | "version": "3.6.1"
244 | }
245 | },
246 | "nbformat": 4,
247 | "nbformat_minor": 2
248 | }
249 |
--------------------------------------------------------------------------------
/r-demo/R_demo.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "R Demo"
3 | output: html_notebook
4 | ---
5 |
6 | This notebook demonstrates some of the basic functionality in R, using COVIDcast data. COVIDcast provides daily access to a range of COVID-related signals, from sources like symptom surveys and medical claims data, as well as standard signals such as confirmed cases and deaths. To run a cell, either press the green play button in the top right corner or press Cmd + Shift + Enter with your cursor in the cell.
7 |
8 | If you haven't installed a package you need, install it using `install.packages(PACKAGE_NAME)`. In this tutorial, we'll primarily be working with packages in tidyverse (this includes dplyr for manipulating data, and ggplot2 for plotting).
9 |
10 | ```{r}
11 | # You only ever need to run this once.
12 | install.packages("tidyverse")
13 | ```
14 |
15 | Here are the specific packages we'll be using in this tutorial:
16 | ```{r}
17 | library(dplyr)
18 | library(ggplot2)
19 | ```
20 |
21 | ## Load Data
22 | First, let's load the COVIDcast data as an R dataframe and look at its first few rows. Note that the data_source is fb-survey (responses to a Facebook survey on symptoms each user is facing), and the signal is smoothed-cli (smoothed signal indicating COVID-like illness).
23 | ```{r}
24 | # We're using an excerpt of the COVIDcast dataset. Load the csv into an R dataframe below:
25 | df <- read.csv('covidcast_cli_data.csv')
26 |
27 | # cast columns containing dates into date types
28 | df$time_value <- as.Date(df$time_value)
29 | df$issue <- as.Date(df$issue)
30 |
31 | df$geo_value <- as.character(df$geo_value)
32 |
33 | # In this tutorial we're only looking at the COVID-like Ilness (CLI) signal.
34 | # If you'd like to play with the entire COVIDcast API, install the package and load the data by uncommenting and running the following commands:
35 |
36 | # devtools::install_github("cmu-delphi/covidcast", ref = "main",
37 | # subdir = "R-packages/covidcast") # the covidcast package is not on CRAN yet, so it can be installed using the devtools package:
38 | # library(covidcast)
39 | # df <- suppressMessages(
40 | # covidcast_signal(data_source = "fb-survey", signal = "smoothed_cli",
41 | # start_day = "2020-05-01", end_day = "2020-12-01",
42 | # geo_type = "state")
43 | # )
44 |
45 | head(df)
46 | ```
47 |
48 |
49 | Right now, there are several columns in the dataset (here's the documentation which includes their meanings: https://cmu-delphi.github.io/covidcast/covidcastR/reference/covidcast_signal.html).
50 | Let's create a new dataframe with only the columns we care about for the sake of this analysis. To do so, we'll be using the `%>%` operator which ``pipes" the data through from the left hand side into a `select(...)` function on the right hand side. Below, we select columns for:
51 |
52 | * geo_value: the state
53 | * time_value: the date
54 | * value: the value for the smoothed CLI signal
55 | * stderr: standard error for that value
56 | * sample_size: sample size available in that geography on that day
57 |
58 | ```{r}
59 | df <- df %>% select(geo_value, time_value, value, stderr, sample_size)
60 |
61 | head(df)
62 | ```
63 |
64 | ## Basic data operations
65 | Let's get some basic information about this data:
66 | ```{r}
67 | # is there any missing data?
68 | sum(df %>% is.na()) # answer: no
69 |
70 | # what's the date range?
71 | min(df$time_value)
72 | max(df$time_value) # answer: 5/1/20 to 12/1/20
73 |
74 | # what are the unique geo values?
75 | df %>% select(geo_value) %>% unique() # answer: 52; includes Puerto Rico (pr) and Washington D.C. (dc) as separate states
76 | ```
77 |
78 |
79 | In exploratory data analysis, it is important to define questions which drive your analysis. In this case, suppose we would like to ask: "Which states have the most data?"
80 | To get a ranked list of the states and their corresponding total sample sizes, we can group the data frame by `geo_value` and sum the `sample_size` values in each group, and then sort by descending total sample size:
81 | ```{r}
82 | state_sample_sizes <- df %>%
83 | group_by(geo_value) %>%
84 | summarize(total_sample_size = sum(sample_size)) %>% # compute the sum of sample_sizes for each geo_value
85 | arrange(-total_sample_size) # order from greatest total_sample_size to least
86 |
87 | state_sample_sizes[1:10,]
88 | ```
89 |
90 | Let's take the top five states with the most data (in this case, it corresponds to the most Facebook survey responses).
91 | ```{r}
92 | top5 <- (state_sample_sizes[1:5,])$geo_value
93 | print(top5)
94 | ```
95 |
96 | ## Plotting
97 | The ggplot2 package works well with dplyr, letting you create beautiful plots with just a few lines of code. On the flip side, if you'd like something other than the defaults it may take some finagling.
98 | Below is an example of how to plot the top five states' CLI values over the entire time range:
99 | ```{r}
100 | df %>%
101 | filter(geo_value %in% top5) %>%
102 | ggplot(aes(x=time_value, y=value, color=geo_value)) +
103 | geom_line() +
104 | ggtitle('CLI signal in top five states with the most data') +
105 | xlab('Date') +
106 | ylab('CLI Smoothed Signal') +
107 | scale_x_date(date_labels="%b",date_breaks="1 month")
108 | ```
109 |
110 | To provide some context, we can also look at how much survey data was collected in each state over time:
111 | ```{r}
112 | df %>%
113 | filter(geo_value %in% top5) %>%
114 | ggplot(aes(x=time_value, y=sample_size, color=geo_value)) +
115 | geom_line() +
116 | ggtitle('Sample size from each state of the top five states by sample size') +
117 | xlab('Date') +
118 | ylab('Sample size') +
119 | scale_x_date(date_labels="%b",date_breaks="1 month")
120 | ```
121 |
--------------------------------------------------------------------------------