diff --git a/README.md b/README.md
index 2ca4d2d..1535fec 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,82 @@
-# notebooks
+# Introduction to Python using Jupyter Notebooks
-This is a collaboration repo for developing Jupyter Notebooks for teaching Python programming with an emphasis on the fundamentals of Cyber Operations.
\ No newline at end of file
+This is a collection of Jupyter Notebooks for teaching Python programming with an emphasis on the fundamentals of Cyber Operations. It's not meant to be a complete Python textbook, but rather an organized reference guide to allow you to see interactive examples on specific Python topics.
+
+## Topics
+
+0. Introduction
+ * Using Jupyter notebooks
+ * Your First Python Program
+
+
+1. Basic operations
+ * Variables, Assignment Statements, Expressions
+ * Reading console input
+ * Numeric Data Types
+ * Operator Precedence
+ * Strings
+ * Type Conversions and Rounding
+
+
+2. Functions and Objects
+ * Common Functions
+ * Object and Methods
+ * Formatting output (`.format()`)
+
+
+3. Branch Logic
+ * Boolean Data Types
+ * `if` Statements
+ * `if` - `else` Statements
+ * `if` - `elif` - `else` Statements
+ * Logical operators (`and`, `or`, `not`)
+ * Operator Precedence
+
+
+4. Iteration (Loops)
+ * `for` Loop
+ * `while` Loop
+ * Nested Loops
+ * `break` and `continue`
+
+
+5. Functions
+ * Introduction
+ * Defining Functions
+ * Calling Functions
+ * Arguments and Parameters
+ * Pass by Reference
+ * Variable Scope
+ * Returning Multiple Values
+
+
+6. Lists, Dictionaries, Sets, Tuples
+ * Creating
+ * Accessing Data
+
+
+7. File I/O
+ * Modes: read (`'r'`), write (`'w'`), append(`'a'`)
+ * Ways to Read: `read()`, `readline()`, `readlines()`
+ * Writing and Closing: `write()`, `close()`
+
+
+8. Crypto
+ * Hashing Strings
+
+
+9. Exception Handling
+ * Catching exceptions
+ * Raising exceptions
+
+
+10. Recursion
+ * Introduction
+ * Examples
+
+
+11. OOP
+ * User-defined Classes
+
+
+12. Misc Topics
diff --git a/chapters/02_operations/placeholder.txt b/chapters/02_operators/placeholder.txt
similarity index 100%
rename from chapters/02_operations/placeholder.txt
rename to chapters/02_operators/placeholder.txt
diff --git a/content/00_intro00.ipynb b/content/00_intro00.ipynb
new file mode 100644
index 0000000..d83aacf
--- /dev/null
+++ b/content/00_intro00.ipynb
@@ -0,0 +1,165 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Welcome to Jupyter Notebooks!\n",
+ "\n",
+ "Jupyter Notebooks are powerful interactive documents that allow you to run code blocks directly inside them."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Quickstart Guide for Jupyter Notebooks:\n",
+ "\n",
+ "* Jupyter Notebooks are arranged as a collection of \"cells\". Cells can contain instructions / descriptions or code.\n",
+ "* A cell is selected if you see a blue bar to its left.\n",
+ "* To minimize a cell, click once on its blue bar. Click the blue bar again to expand.\n",
+ "* To edit a code cell, click on it.\n",
+ "* To run a code cell, make sure it's selected and press **Cntl-Enter**.\n",
+ " * You can repeatedly run a cell as long as it's highlighted. Each re-run of a cell will start by clearing its output.\n",
+ "* To clear the output in a code cell: Right-click it; select **Clear Outputs**.\n",
+ "* To clear the output for all code cells in a notebook, right-click on the window and select **Clear All Outputs**\n",
+ "* If a particular code cell appears to \"hang\" or won't run, select **Restart Kernel...** from the **Kernel** menu."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "Throughout these notebooks, you'll occasionally see a green check mark like the one shown above. These are knowledge checkpoints intended to test your skills and understanding of the material. They usually involve asking a question before having you run a snippet of code to check your answer.\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Code Examples\n",
+ "Here are some examples of executable Python3 code blocks that you'll see in Jupyter Notebooks."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To run the code below, click (once) on the code block and press `Cntl-Enter`.\n",
+ "\n",
+ "This code example is interactive and will ask you for input.\n",
+ "\n",
+ "To re-run the code, press `Cntl-Enter` again.\n",
+ "\n",
+ "To clear the output, right-click on the cell and select `Clear Outputs`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"This is a Python Program\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Here's another example that demonstrates simple addition. Try running it."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(10 + 25)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally, here's a simple \"Magic 8-Ball\" game. Credit for idea to: [Python for Beginners](https://www.pythonforbeginners.com/code-snippets-source-code/magic-8-ball-written-in-python/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Closing jupyter lab\n",
+ "\n",
+ "When you're done using jupyter lab, the easiest way to exit is to select \"Shutdown\" from the File menu in the browser. You can then close the browser window where it's running (saving any changes to your notebooks if desired).\n",
+ "\n",
+ "
\n",
+ "
\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Additional Resources\n",
+ "\n",
+ "There is so much more to Jupyter Notebooks than what's listed above, but it will get you started. Trying Googling \"Jupyter Notebooks\", or check out some of these resources:\n",
+ "\n",
+ "*NOTE: Jupyter Lab is the next evolution of the Jupyter infrastructure. The basic program (jupyter notebook) started it all.*\n",
+ "\n",
+ "[Getting Started With Jupyter Notebook for Python](https://medium.com/codingthesmartway-com-blog/getting-started-with-jupyter-notebook-for-python-4e7082bd5d46)\n",
+ "\n",
+ "[Jupyter Notebook for Beginners: A Tutorial](https://www.dataquest.io/blog/jupyter-notebook-tutorial/)\n",
+ "\n",
+ "[Jupyter Notebook Tutorial: Introduction, Setup, and Walkthrough](https://www.youtube.com/watch?v=HW29067qVWk) *YouTube Video*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "*MIT License*\n",
+ "\n",
+ "*Copyright 2019-2020 Peter Nardi*\n",
+ "\n",
+ "*Terms of use:*\n",
+ "\n",
+ "*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*\n",
+ "\n",
+ "*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*\n",
+ "\n",
+ "*THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/content/00_intro01.ipynb b/content/00_intro01.ipynb
new file mode 100644
index 0000000..2b5eb19
--- /dev/null
+++ b/content/00_intro01.ipynb
@@ -0,0 +1,276 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Welcome To Python!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Python provides a modern, flexible programming environment that scales from introductory programming courses, to full-fledged enterprise applications. It's a great place to start if you want to learn how to write computer programs and it runs on just about any system you might have (Windows, Mac, Linux). If you're curious about the history of Python (*for example, why is it called Python?*) then please visit [The Python History Wiki](https://en.wikipedia.org/wiki/History_of_Python):"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Jumping right in\n",
+ "\n",
+ "No introduction to computer programming would complete without writing the wildly popular [Hello World](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) program. The complete program in Python looks like this:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Hello World\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "Do you remember how to run a code cell? Visit the first jupyter notebook if you need a refresher. To test your knowledge, run the code cell above and observe the output. Then modify the program to print your name, rather than `Hello World` and run it again."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "While this first program is very simple, it introduces an important concept: Having Python print information to the screen. A computer program that only calculated results, but never provided them to you would not be very useful.\n",
+ "\n",
+ "In the first notebook we introduced this Python program:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(10 + 25)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "It's your turn. Modify the program above to print the sum of the first 10 even integers (starting from 2). When you ran the program did you get 110?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Comments\n",
+ "\n",
+ "There's a particular name for the file that contains your code. Programmers call it *source code* (or a *source file*). A *source file* contains the instructions that you write directing the computer to perform specific operations. Occasionally you'll write a section of code that requires some comments to describe your thinking when you wrote it. These aren't executable instructions, they're just notes that help you (or someone else looking at your code) follow the flow of your logic. If you ever write a computer program, then come back to it days or weeks later, these comments can be very useful to help you pick up your train of thought. You can also use comments to mark areas of your code as \"To Do\" items; things that you'll get back to later.\n",
+ "\n",
+ "In Python, non-executable comments are delineated with the hashtag character (`#`). Here's an example (run it to see what prints):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# This is a comment, it will not run\n",
+ "\n",
+ "print(\"This is my code\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Notice that line 2 in the code above is blank. Python ignores blank lines, but using them to format your code can make it neater and easier to read."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Speaking of Spaces\n",
+ "\n",
+ "If you can put blank lines (spaces) between blocks of code, what about spaces within a single line of code?\n",
+ "\n",
+ "Python is quite forgiving about how things are spaced-out. If often comes down to readability. Can you (or your instructor) easily read your code and follow along? While the program may run just fine, be mindful that you can change the intended result because of the particular spacing you used.\n",
+ "\n",
+ "Here are some examples:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# This code prints 20\n",
+ "print(2 + 4 + 6 + 8)\n",
+ "\n",
+ "# This code also prints 20\n",
+ "print(2+4 + 6 + 8)\n",
+ "\n",
+ "# Which is easier to read?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Does the difference in spacing between the two lines below\n",
+ "# make a difference in the output?\n",
+ "\n",
+ "print(\"Go Navy!\")\n",
+ "print(\" Go Navy !\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You should have seen a difference. Python is explicitly complying with your instructions to print everything (including the spaces) between the two quotation marks."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Error Messages and Writing Code"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Python prints error messages when something goes wrong with your program. Getting error messages is a natural and important part of writing code. There is no such thing as a coder who never got an error message -- that person doesn't exist. You should expect and embrace error messages when you write code. The error messages provide important information that helps you fix problems.\n",
+ "\n",
+ "An error in a computer program is commonly called a *bug* and the term used to describe fixing those errors is *debugging*. [(why are coding errors called bugs?)](https://en.wikipedia.org/wiki/Software_bug) Below is a simple program that has a bug. Run the code and observe the resulting error message."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Go Navy!)\n",
+ "print(2 + 3)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The problem with the code above is that line 1 is missing a matching quotation mark after the exclamation point. Is that what the error message said?\n",
+ "\n",
+ "It would be great if Python always told you *exactly* what was wrong with your program. Python will get you close, usually telling you *something* went wrong, but sometimes it's imprecise about exactly *where the problem is* and *what* went wrong. This is not unique to Python; all programming languages \"do their best\" to show you where errors are.\n",
+ "\n",
+ "When you write a computer program you should follow this design philosophy: ***build a little; test a little***. Focus on a specific capability, get it working well, then move on to the next capability in your program. Begin by sketching your thoughts on paper with flowcharts and diagrams. Software engineers would refer to this as *Modular Design*. Don't approach a massive programming task by just typing-away. Organize your thoughts first, asking questions like:\n",
+ "\n",
+ "- What is this program supposed to do?\n",
+ "- What are my inputs and outputs?\n",
+ "- What's the best way to approach this problem?\n",
+ "- How can I break it up into pieces?\n",
+ "- How can I test my code to make sure it handles all possible inputs?\n",
+ "\n",
+ "Learning to program a computer is a hands-on activity. To get better at writing computer programs, there simply is no substitute for having your hands on the keyboard. As you get more practice you'll get better at it. It takes time and patience. Programming a computer is very similar to learning to speak a new language or learning how to play an instrument - the more you do it, the better you get.\n",
+ "\n",
+ "Oh yes, and don't forget to embrace your error messages!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### A Final Word About Python Reference Documentation\n",
+ "\n",
+ "The reference document for Python is ***outstanding***! You can find it at [https://www.python.org/](https://www.python.org/). I strongly recommend bookmarking that site. Once you're there, you can get the latest documentation by clicking on `Documentation` then `Python 3.x Docs` (see picture below). Throughout these notebooks I'll often provide links directly into the documentation, because the Python developers do such a great job of explaining things. \n",
+ "\n",
+ "
\n",
+ "
\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Additional Resources\n",
+ "\n",
+ "[An Informal Introduction to Python](https://docs.python.org/3/tutorial/introduction.html)\n",
+ "\n",
+ "[Python Resources for Beginners](https://wiki.python.org/moin/BeginnersGuide/Programmers)\n",
+ "\n",
+ "[Python Introduction (w3schools)](https://www.w3schools.com/python/python_intro.asp)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "*MIT License*\n",
+ "\n",
+ "*Copyright 2019-2020 Peter Nardi*\n",
+ "\n",
+ "*Terms of use:*\n",
+ "\n",
+ "*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*\n",
+ "\n",
+ "*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*\n",
+ "\n",
+ "*THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/content/01_operations00.ipynb b/content/01_operations00.ipynb
new file mode 100644
index 0000000..33aef37
--- /dev/null
+++ b/content/01_operations00.ipynb
@@ -0,0 +1,380 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Basic Operations"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Variables, Assignment Statements, Expressions\n",
+ "\n",
+ "In programming languages, a variable is a container than can hold a value that changes over time (hence the name, *variable*). In Python, variables can hold data of many different types. We'll dive deeper into data types in future notebooks, but for now we'll stick with integers. We place values into variables using the assignment operator, which is the equal sign: `=`. We can use arithmetic operators on variables just like we can with integers:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "length = 20\n",
+ "width = 30\n",
+ "area = length * width\n",
+ "print(length)\n",
+ "print(width)\n",
+ "print(area)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can combine operations in more complex expressions. Run the example below which calculates the perimeter of a square."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "width = 10\n",
+ "length = 20\n",
+ "perimeter = (2 * width) + (2 * length)\n",
+ "print(perimeter)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can also use Python's `print()` statement to display the value of more than one variable on a single line by separating each one with commas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "length = 20\n",
+ "width = 30\n",
+ "area = length * width\n",
+ "print(length, width, area)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Below is an interesting use of variables that is often difficult to understand when you see it for the first time. Run the code cell below and examine the output."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "score = 45\n",
+ "print(score)\n",
+ "score = score + 10\n",
+ "print(score)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "What's going on? How can `score` show up on both the left and right side of an equal sign? If the line of code which reads: `score = score + 10` were given in an algebra class, you might say, \"***The statement is false. `score` cannot be equal to itself, plus 10***\". That's true in algebra, but in a computer programming context the logic flow works like this:\n",
+ "\n",
+ "1. Evaluate everything to the right of `=`. That means, take the current value in `score` (45) and add 10 to it.\n",
+ "2. Take the result from step 1 and store it in the variable named `score`. This replaces `score`'s original value (45) with the newly calculated value (55).\n",
+ "\n",
+ "It's important to understand that the steps are followed in the order given above. Before we replace `score` with a new value, we use the current value in `score` to calculate an interim result, then place that result back into `score`.\n",
+ "\n",
+ "You will see and use this design pattern often in any programming language you learn, including Python."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### User Input and Output\n",
+ "\n",
+ "We've already seen how Python produces output to the screen using the `print()` function."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Go Navy!\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "How about getting input from the user? User input and output is such a fundamental and common part of most programs that it's worth taking time to make sure you understand it well. A very common way to collect user input is with Python's `input()` function. Here's an example:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "name = input(\"Enter your name: \")\n",
+ "print(name)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "There are several important things happening in those two lines of code:\n",
+ "\n",
+ "1. `input()` is a Python function that takes a string which represents the prompt you want to see on the screen (*Note: a string is a collection of characters. We'll examine strings in more detail in the next notebook*).\n",
+ "2. The `input()` function prints the prompt the screen, then pauses program execution while waiting for the user to type something in. The `input()` function knows the input is complete when the user presses the return key.\n",
+ "3. The input function returns whatever the user types and stores it in the variable `name`.\n",
+ "4. Finally, the `print()` function prints the ***value*** stored in `name` to the screen (it doesn't print the characters `n` `a` `m` `e` to the screen)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Basic Arithmetic Operations\n",
+ "\n",
+ "Like all modern programming languages, Python provides support for basic arithmetic operations. Here are the big four:\n",
+ "\n",
+ "- Addition: `+`\n",
+ "- Subtraction: `-`\n",
+ "- Multiplication: `*`\n",
+ "- Division: `/`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(2 + 2)\n",
+ "print(100 - 4)\n",
+ "print(3 * 9)\n",
+ "print(6 / 5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Numeric Data Types\n",
+ "\n",
+ "Variables hold values that we can retrieve later and use in various ways. The two most common numeric data types are integers and floating point numbers (called *floats*). Let's start with integers which are just whole numbers (no fractional part):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 20\n",
+ "y = 5\n",
+ "z = x + y\n",
+ "print(z)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Integers can be positive or negative."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = -5\n",
+ "y = 3\n",
+ "z = y - x\n",
+ "print(z)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Floats are numbers that have a fractional part (notice what you get when you add a float to an integer)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 3.14159\n",
+ "y = 6\n",
+ "z = x + y\n",
+ "print(z)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Operator Precedence\n",
+ "\n",
+ "Precedence refers to the order in which mathematical operations are performed. The order of operator precedence in Python is as follows:\n",
+ "\n",
+ "1. Exponentiation (`**`)\n",
+ "2. Multiplication (`*`), float division (`/`), [integer division](https://docs.python.org/3.3/reference/expressions.html#binary) (`//`), [modulo](https://docs.python.org/3.3/reference/expressions.html#binary) (`%`)\n",
+ "3. Addition (`+`), subtraction (`-`)\n",
+ "\n",
+ "Different operators within the same line above are applied left to right.\n",
+ "\n",
+ "Examples!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### What does this code print?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 3 * 4 + 6 - 2 / 4 + 3 ** 2\n",
+ "print(x)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### How about now?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 3 * (4 + 6) - 2 / (4 + 3) ** 2\n",
+ "print(x)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Notice how we can change how precedence is enforced with parentheses. Even if a line of code performs as intended without parenthesis, adding them can often make the code easier to follow, and debug if necessary. For example, `x` and `y` evaluate to the same number below, but the expression in `y` makes it unambiguous what the programmer intended."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 3 * 2 + 5 * 4\n",
+ "y = (3 * 2) + (5 * 4)\n",
+ "print(x,y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "Write a program in the code cell below that calculates the area of a circle with a radius of 12"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Write your code below to calculate the area of a circle with a radius of 12\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Additional Resources\n",
+ "\n",
+ "[An Informal Introduction to Python](https://docs.python.org/3/tutorial/introduction.html)\n",
+ "\n",
+ "[Python Resources for Beginners](https://wiki.python.org/moin/BeginnersGuide/Programmers)\n",
+ "\n",
+ "[Python Introduction (w3schools)](https://www.w3schools.com/python/python_intro.asp)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "*MIT License*\n",
+ "\n",
+ "*Copyright 2019-2020 Peter Nardi*\n",
+ "\n",
+ "*Terms of use:*\n",
+ "\n",
+ "*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*\n",
+ "\n",
+ "*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*\n",
+ "\n",
+ "*THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/content/01_operations01.ipynb b/content/01_operations01.ipynb
new file mode 100644
index 0000000..ba8e348
--- /dev/null
+++ b/content/01_operations01.ipynb
@@ -0,0 +1,504 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Introduction to Strings\n",
+ "\n",
+ "Let's begin our exploration of strings with a technical definition:\n",
+ "\n",
+ "*Strings are considered a \"Collection Class\", meaning they are a collection of other data types. A String is an array of [bytes](https://simple.wikipedia.org/wiki/Byte) representing [Unicode](https://en.wikipedia.org/wiki/Unicode) characters. Python does not have a character data type, so a single character is simply a string with a length of 1. Strings are iterable, immutable and ordered. Duplicates are allowed in strings.*\n",
+ "\n",
+ "We'll explore this definition in more detail throughout this notebook.\n",
+ "\n",
+ "*Note: Like any other programming language, there are many ways to approach problems in Python. Two completely different approaches may be equally valid. Keep in mind that as you go through these examples you'll often see multiple ways of doing the same thing. No particular approach is presented here as \"the best\" or \"the only\" way do do things. Find your own unique programming style and embrace it!*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Representing Strings\n",
+ "\n",
+ "Strings are represented with quotation marks. Python is more forgiving than some other programming languages, so you may represent strings with either double-quote marks (`\"`) or single quote marks (`'`). The only rule is that you cannot mix marks within the same string definition.\n",
+ "\n",
+ "Run the code samples below, in particular examine the error message that results when using mixed quotes:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Valid strings"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Welcome to Python\" # Double quotes\n",
+ "print(s1)\n",
+ "s2 = 'Exploring Strings' # Single Quotes\n",
+ "print(s2)\n",
+ "s3 = 'A' # A string with one character is allowed\n",
+ "print(s3)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Invalid string"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Mixing quotes is not allowed'\n",
+ "print(s1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "When first learning a programming language, it's not uncommon to confuse numbers as integers (e.g. `x = 42`), with numbers as strings (e.g. `x = \"42\"`). Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 42\n",
+ "y = 43\n",
+ "print(x)\n",
+ "print(y)\n",
+ "print(x + y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 42\n",
+ "y = \"43\"\n",
+ "print(x)\n",
+ "print(y)\n",
+ "print(x + y) # This line should cause a crash"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = \"42\"\n",
+ "y = \"43\"\n",
+ "print(x)\n",
+ "print(y)\n",
+ "print(x + y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### What happened?\n",
+ "\n",
+ "Sample 3 is interesting. Why doesn't it crash? Doesn't Sample 2 demonstrate that you can't add strings?\n",
+ "\n",
+ "Not exactly. Sample 2 demonstrates that you can't add a string to an integer. Sample 3 demonstrates that you can merge two (or more) strings together using the `+` operator, and the result is a new string that represents the combination of the two. The term for combining strings in this way is *concatenation*.\n",
+ "\n",
+ "Python has so many awesome little tricks that make it such a fun programming language. We certainly won't be able to explore every single one, but I'll try to point them out as we demonstrate new topics. Run the code below to see what I mean :-)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "name = input(\"Enter your first name: \")\n",
+ "print(name * 5)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Definitions\n",
+ "\n",
+ "In the technical definition of a string, we introduced three new terms: *iterable*, *immutable* and *ordered*. Let's examine each of these."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### __*iterable*__\n",
+ "\n",
+ "Iteration (iterable) is just a fancy term for looping again and again. It's a critically important part of any programming language and we'll spend several lessons on this topic throughout the course. For now, let's just think of iteration as performing some operation on every character in a string. To make use of iteration on strings, you need to know how we access individual characters.\n",
+ "\n",
+ "We refer to a character's position in a string as its *index*. The first character in a string is always located at index `0`, and the last character in a string is always at an index that is one less then the number of characters in the string. We access an individual character at a particular index by using bracket notation (`[]`), along with the desired index.\n",
+ "\n",
+ "Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go Navy\"\n",
+ "print(s[0])\n",
+ "print(s[3])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The character in the string `s` at position `0` is `'G'`; and the character at position `3` is `'N'`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go Navy\"\n",
+ "print(s[0])\n",
+ "print(s[1])\n",
+ "print(s[2])\n",
+ "print(s[3])\n",
+ "print(s[4])\n",
+ "print(s[5])\n",
+ "print(s[6])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Sample 2 shows a simple form of iteration to print every character in a string. It's a good start, but we'll explore more sophisticated iteration techniques throughout the course. Also note that a `space` is also considered a character (the character at `s[2]`)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go Navy\"\n",
+ "print(s[0])\n",
+ "print(s[5])\n",
+ "print(s[7])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "The code above should crash when you run it. Remember, for a string of length `n`, individual characters are located at indices in the range from `0` to `n-1`.\n",
+ "\n",
+ "* Which line above caused the crash?\n",
+ "* What error message did you get?\n",
+ "* Change the code above so it prints `o`, `N`, `v`, each on a separate line, without crashing."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### __*immutable*__\n",
+ "\n",
+ "If something is immutable, it means that once it's created, it can't be changed. Mutability can be a confusing topic, so we'll explore with examples.\n",
+ "\n",
+ "Strings are immutable. While you can change the entire value of a string in a variable, you cannot change the value of an individual character *inside* a string variable.\n",
+ "\n",
+ "Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go\"\n",
+ "print(s)\n",
+ "s = \"Navy\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The code above runs fine. The variable `s` starts with a value of `Go`, is printed, then changes to the value `Navy`, and is printed again."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Hot Air\"\n",
+ "print(s)\n",
+ "s[0] = \"N\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The code above crashes. Which line causes the crash and what error did you get? Does that mean we can never change `Hot Air` to `Not Air`? Not really. Advanced string manipulation techniques include __*slicing*__ and __*splitting*__, which we'll cover in future topics. For now, we can use the straightforward technique shown in Sample 3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Hot Air\"\n",
+ "print(s)\n",
+ "s = \"Not Air\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### __*ordered*__\n",
+ "\n",
+ "Strings are ordered, because the programmer controls the order in which the characters are arranged and can be confident that once created, a particular character will always be in the same place within a string. It may sound obvious at this point, but we'll explore **dictionaries** and **sets** later in the course, which are unordered. The comparison will become clearer when we see those advanced data types.\n",
+ "\n",
+ "Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Python is awesome\"\n",
+ "print(s[3])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The character at index `3` will always be `h`, as long as the value of `s` doesn't change."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### A final word about empty strings\n",
+ "\n",
+ "Can we create a string variable without any characters in it? The answer is, yes. It's a very handy and frequently used design pattern.\n",
+ "\n",
+ "Remember this example from the previous notebook that shows a variable (`score`) on both sides of the equal sign?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "score = 45\n",
+ "print(score)\n",
+ "score = score + 10\n",
+ "print(score)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "1. Evaluate everything to the right of `=`. That means, take the current value in `score` (45) and add 10 to it.\n",
+ "2. Take the result from step 1 and store it in the variable named `score`. This replaces `score`'s original value (45) with the newly calculated value (55)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can initialize string variables to be empty strings (`\"\"`) and perform concatenation in a similar fashion:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "fullname = \"\"\n",
+ "firstname = input(\"Enter your first name: \")\n",
+ "fullname = fullname + firstname\n",
+ "lastname = input(\"Enter your last name: \")\n",
+ "fullname = fullname + lastname\n",
+ "print(fullname)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "The code above will print your full name with no spaces between first name and last name. When asked for your first name, you could just add a space to the end of what you type, but try modifying the code above to insert a space between first and last name without making the user have to type it."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Additional Resources\n",
+ "\n",
+ "[Python Strings: w3schools](https://www.w3schools.com/python/python_strings.asp)\n",
+ "\n",
+ "[An Informal Introduction to Python](https://docs.python.org/3/tutorial/introduction.html)\n",
+ "\n",
+ "[Strings and Character Data in Python](https://realpython.com/python-strings/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "*MIT License*\n",
+ "\n",
+ "*Copyright 2019-2020 Peter Nardi*\n",
+ "\n",
+ "*Terms of use:*\n",
+ "\n",
+ "*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*\n",
+ "\n",
+ "*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*\n",
+ "\n",
+ "*THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/content/01_operations02.ipynb b/content/01_operations02.ipynb
new file mode 100644
index 0000000..9d558f0
--- /dev/null
+++ b/content/01_operations02.ipynb
@@ -0,0 +1,247 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# More Strings\n",
+ "\n",
+ "This is not an exhaustive list of all of Python's advanced string processing techniques, but it's a good foundation from which you can explore other resources to learn more."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Printing quotation marks\n",
+ "\n",
+ "We've seen how strings are separated by quotation marks, but what if you want to actually __*print*__ a quotation mark? How would you print this sentence to the screen:\n",
+ "\n",
+ "`USNA's colors are Blue and Gold`\n",
+ "\n",
+ "Does the code below do it?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"USNA's colors are Blue and Gold\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "It does. Maybe that's a clean solution to the problem. Just use double quotes to define the string, and single quotes internal to the string.\n",
+ "\n",
+ "Assume we want to print this:\n",
+ "\n",
+ "`These are \"double quotes\" and these are 'single quotes'`\n",
+ "\n",
+ "Does this code work?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"These are \"double quotes\" and these are 'single quotes'\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "What error message do you get when you run that code?\n",
+ "\n",
+ "There is a way to handle quotation marks and many other special characters that you'll see throughout the course. The term we use is **\"escaping\"** the special character [(more here)](https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals). The escape character for strings is the backslash (`\\`), and we use it like this:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"These are \\\"double quotes\\\" and these are \\'single quotes\\'\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The code looks a little busy, but the more you use the syntax, the more you'll become comfortable with it. Notice that Python doesn't print the backslash character itself. Using a backslash character in a string is the same as telling Python: \"*When you see a backslash character, actually print what comes immediately after it, not the backslash itself.*\"\n",
+ "\n",
+ "So what do you do if you actually want to print a backslash character, like this:\n",
+ "\n",
+ "`Here is a directory path in MS-Windows: c:\\smith\\Documents`\n",
+ "\n",
+ "The definition above still holds; just use two backslashes!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Here is a directory path in MS-Windows: c:\\\\smith\\\\Documents\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Accessing individual characters (revisited)\n",
+ "\n",
+ "In the first notebook on strings we examined how to access individual characters. The example we gave was pretty straightforward because we chose the string to manipulate. What happens if you don't know the string in advance? What if you prompt the user for a string and then need to find specific characters?\n",
+ "\n",
+ "Here's an example of finding the length of a user-entered string and accessing individual characters.\n",
+ "\n",
+ "*NOTE: Don't worry about the use of Python's `format()` function in this example. We'll explore `format()` in more detail in the next notebook.*"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = input(\"Enter a string: \")\n",
+ "length = len(s)\n",
+ "print(\"There are {0:d} characters in your string\".format(length))\n",
+ "print(\"The first character in your string is: \\\"{0:s}\\\"\".format(s[0]))\n",
+ "print(\"The last character in your string is: \\\"{0:s}\\\"\".format(s[length-1]))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "I never explained it, but what do you think Python's `len()` function does in line 5 in the code above? [(hint)](https://docs.python.org/3/library/functions.html)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### String Slicing\n",
+ "\n",
+ "Carving up strings in python is known as *slicing*. While strings are immutable (unchangable), you can still slice parts of them and assemble the parts (concatenate them) in various ways. Here are some syntax rules for various slicing operations (assume we have a string variable called `s`):\n",
+ "\n",
+ "`s[start:end]` From the character at position `start` to the character at position `end`-1.\n",
+ "\n",
+ "`s[start:]` From the character at position `start` to the end of the string.\n",
+ "\n",
+ "`s[:end]` From the beginning of the string to the character at position `end`-1.\n",
+ "\n",
+ "`s[:]` A complete copy of `s`.\n",
+ "\n",
+ "Here are some coding examples of slicing a string:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Here is a string we can use to test\"\n",
+ "print(s[5:13])\n",
+ "s2 = s[6:]\n",
+ "print(s2)\n",
+ "s2 = s[:8]\n",
+ "print(s2)\n",
+ "print(s[:16] + s[27:])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### A roundabout way to mutate a string using slicing\n",
+ "\n",
+ "In the first string notebook, I said that you can't mutate a string (change individual characters). So, for example, how would we insert a new word into the middle of a string?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = input(\"Enter a string: \")\n",
+ "word = input(\"Enter a word to insert in the middle: \")\n",
+ "middle = len(s1) // 2\n",
+ "part1 = s1[:middle] # end = middle - 1\n",
+ "part2 = s1[middle:] # start = middle\n",
+ "print(\"Your new string is: {0:s}\".format(part1 + word + part2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "What's the difference between division using `/` and division using `//`? [(hint)](https://docs.python.org/3/library/stdtypes.html#typesnumeric)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Additional Resources\n",
+ "\n",
+ "[Common string operations](https://docs.python.org/3/library/stdtypes.html#textseq)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "*MIT License*\n",
+ "\n",
+ "*Copyright 2019-2020 Peter Nardi*\n",
+ "\n",
+ "*Terms of use:*\n",
+ "\n",
+ "*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*\n",
+ "\n",
+ "*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*\n",
+ "\n",
+ "*THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/chapters/05_functions/defMain.ipynb b/content/05_defMain00.ipynb
similarity index 100%
rename from chapters/05_functions/defMain.ipynb
rename to content/05_defMain00.ipynb
diff --git a/chapters/06_strings/formatStrings.ipynb b/content/06_strings02.ipynb
similarity index 67%
rename from chapters/06_strings/formatStrings.ipynb
rename to content/06_strings02.ipynb
index 4fdf069..c53eec3 100644
--- a/chapters/06_strings/formatStrings.ipynb
+++ b/content/06_strings02.ipynb
@@ -4,27 +4,39 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Format Strings in Python"
+ "# Formatting Output in Python"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "You learned format strings in Python back in SY201, though their true utility probably didn't become evident until you studied formatted printing in C. Remember this from SY204?\n",
+ "So far, we've just used Python's `print()` function to send output the screen. It's simple and it works well, but what if we want to format the output in a particular way? Consider this example:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "n = 12345\n",
+ "print(n)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "What gets printed when you run the code? What if we wanted this to be printed instead:\n",
"\n",
- "``` C\n",
- "int main(int argc, char *arvg[]) {\n",
- " \n",
- " int i = 10;\n",
- " printf(\"The value of i is %d\",i);\n",
- " \n",
- " return 0;\n",
- " \n",
- "}\n",
- "```\n",
+ "`12,345`\n",
+ "\n",
+ "To answer that question, we first need to understand something called a *format specifier*.\n",
"\n",
- "Here's how it looks in Python:"
+ "A format specifier is a placeholder in Python that says: *Don't actually print the placeholder you see here, but fill it in with something that I'll provide to you later.* We denote format specifiers in Python strings by using curly braces `{}` and a number indicating the position of the placeholder (always start counting from `0`). We follow that with the `format()` command and a comma-separated list of items to fill in the placeholders.\n",
+ "\n",
+ "Here's an example:"
]
},
{
@@ -33,17 +45,23 @@
"metadata": {},
"outputs": [],
"source": [
- "i = 10\n",
- "print(\"The value of i is {0}\".format(i))"
+ "print(\"Go {0}! Beat {1}!\".format(\"Navy\",\"Army\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Formatted printing in Python (like in C) involves using format specifiers (placeholders) inside a string. The format specifiers are positional references that map, one for one, to each item in a comma separated listing of items contained in a `format()` statement. In Object Oriented Programming terms, `format()` is a method that operates on string objects.\n",
+ "Run the code.\n",
+ "\n",
+ "- What gets printed?\n",
+ "- What if you switch the `0` and `1`?\n",
+ "- What if you switch `Navy` and `Army` within the `format()` statement?\n",
+ "- What if you delete `Army` so the line reads: `print(\"Go {0}! Beat {1}!\".format(\"Navy\"))`\n",
"\n",
- "You can add a qualifier to a format specifier to refine how the output is displayed. Available qualifiers are shown below:\n",
+ "To reinforce: format specifiers in Python are positional references that map, one for one, to each item in a comma separated listing of items contained in a `format()` statement. In Object Oriented Programming terms, `format()` is a method that operates on string objects.\n",
+ "\n",
+ "You can add a qualifier to a format specifier to refine how the output is displayed. In the coming examples, we'll see that these qualifiers can be incredibly powerful. Available qualifiers are shown below:\n",
"\n",
"\n",
"\n",
@@ -161,7 +179,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "You can switch the order of format specifiers. Items in the format listing are *zero-based indexed*. For example, if there were two items in a `format()` statement they would be numbered 0 and 1."
+ "Let's revisit our Army / Navy example with qualifiers. The original code worked fine, but we could have also written it like this, using the qualifiers for string data:"
]
},
{
@@ -170,28 +188,33 @@
"metadata": {},
"outputs": [],
"source": [
- "s1 = \"Navy\"\n",
- "s2 = \"Army\"\n",
- "print(\"Go {0}, Beat {1}!\".format(s1,s2))\n",
- "print(\"Go {1}, Beat {0}!\".format(s1,s2))"
+ "print(\"Go {0:s}! Beat {1:s}!\".format(\"Navy\",\"Army\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Aligning strings using qualifiers along with numeric values. In the code below, `{1:>45s}` means: *Reserve 45 spaces for content, and right justify my string within that.* It does not mean: *Output 45 spaces and then append my string.*"
+ "You can switch the order of format specifiers. Just remember that items in the format listing are *zero-based indexed*, meaning we always start counting from `0`. For example, if there were two items in a `format()` statement they would be numbered `0` and `1`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Navy\"\n",
+ "s2 = \"Army\"\n",
+ "print(\"Go {0:s}, Beat {1:s}!\".format(s1,s2))\n",
+ "print(\"Go {1:s}, Beat {0:s}!\".format(s1,s2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "
\n",
- "
\n",
- "
\n",
- "\n",
- "Why does the code below output two lines when there's only one `print()` statement?"
+ "You can align (pad) strings using qualifiers along with numeric values. In the code below, `{1:>45s}` means: *Reserve 45 spaces for content, and right justify my string within that.* It does not mean: *Output 45 spaces and then append my string.*"
]
},
{
@@ -213,6 +236,13 @@
"
\n",
"
\n",
"\n",
+ "Why does the code above output two lines when there's only one `print()` statement? It has to do with the `\\n` at the end of the string assigned to the variable `s1`. Recall that `\\` is the [escape character](https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals) in a string; it indicates that what comes after the `\\` has special meaning. In Python, `\\n` means insert a new line. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
"Run the code below as-is. Then change `1:d` to `1:s`. What happens?"
]
},
@@ -248,7 +278,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Selecting a certain number of decimal places of precision. If no value is specified for the number of decimal places in a floating point number, the default is six. Note that you can perform calculations inside the `format()` statement."
+ "You can use format specifiers to specify a certain number of decimal places of precision. If no value is specified for the number of decimal places in a floating point number, the default is six. Note that you can also perform calculations inside the `format()` statement."
]
},
{
@@ -286,6 +316,17 @@
"Padding with leading zeros. This can be tricky. When padding, the number specified indicates the *maximum* total display length, including any signs and / or decimal points. If the maximum length already exceeds the padding specifier, then no leading zeros are applied. Run the example below and examine the output and the code to understand how padding with zeros works."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "n1 = 4.345\n",
+ "n2 = -3.223456\n",
+ "print(\"n1 = {0:=+08.2f}; n2 = {1:04.3f}\".format(n1,n2))"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -294,7 +335,16 @@
"
\n",
"
\n",
"\n",
- "Why does `n2` get printed with no leading zeros when you run the code? If you change `{1:04.3f}` to `{1:09.3f}` how many leading zeros will get printed with `n2` now?"
+ "Why does `n2` get printed with no leading zeros when you run the code above? If you change `{1:04.3f}` to `{1:09.3f}` how many leading zeros will get printed with `n2` now?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Back to our first example\n",
+ "\n",
+ "We started this notebook with the code below, with the goal of having a thousands separator appear in the output."
]
},
{
@@ -303,16 +353,15 @@
"metadata": {},
"outputs": [],
"source": [
- "n1 = 4.345\n",
- "n2 = -3.223456\n",
- "print(\"n1 = {0:=+08.2f}; n2 = {1:04.3f}\".format(n1,n2))"
+ "n = 12345\n",
+ "print(n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Printing decimal numbers with thousands separators."
+ "Here's how it's done using a format specifier, with a decimal (`d`) qualifier, and a comma indicator:"
]
},
{
@@ -321,7 +370,7 @@
"metadata": {},
"outputs": [],
"source": [
- "n = 123234643534\n",
+ "n = 12345\n",
"print(\"n = {0:,d}\".format(n))"
]
},
@@ -331,9 +380,7 @@
"source": [
"## Additional Resources\n",
"\n",
- "[Python | format() function](https://www.geeksforgeeks.org/python-format-function/)\n",
- "\n",
- "[Using % and .format() for great good!](https://pyformat.info/)"
+ "[Format String Syntax](https://docs.python.org/3/library/string.html#formatstrings)"
]
},
{
@@ -372,7 +419,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.9"
+ "version": "3.8.2"
}
},
"nbformat": 4,
diff --git a/chapters/00_introduction/jupyterIntro.ipynb b/content/99_intro00-Copy1.ipynb
similarity index 94%
rename from chapters/00_introduction/jupyterIntro.ipynb
rename to content/99_intro00-Copy1.ipynb
index 9ee7ecc..c0f5307 100644
--- a/chapters/00_introduction/jupyterIntro.ipynb
+++ b/content/99_intro00-Copy1.ipynb
@@ -19,7 +19,7 @@
"* A cell is selected if you see a blue bar to its left.\n",
"* To minimize a cell, click once on its blue bar. Click the blue bar again to expand.\n",
"* To edit a code cell, click on it.\n",
- "* To run code in a cell, make sure it's selected and press **Cntl-Enter**.\n",
+ "* To run a code cell, make sure it's selected and press **Cntl-Enter**.\n",
" * You can repeatedly run a cell as long as it's highlighted. Each re-run of a cell will start by clearing its output.\n",
"* To clear the output in a code cell: Right-click it; select **Clear Outputs**.\n",
"* To clear the output for all code cells in a notebook, right-click on the window and select **Clear All Outputs**\n",
@@ -31,7 +31,7 @@
"metadata": {},
"source": [
"
\n",
- "
\n",
+ "
\n",
"
\n",
"\n",
"Throughout these notebooks, you'll occasionally see a green check mark like the one shown above. These are knowledge checkpoints intended to test your skills and understanding of the material. They usually involve asking a question before having you run a snippet of code to check your answer.\n",
@@ -65,15 +65,14 @@
"metadata": {},
"outputs": [],
"source": [
- "name = input(\"Enter your first name: \")\n",
- "print(\"Greetings,\",name)"
+ "print(\"This is a Python Program\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Here's another example that demonstrates iteration. Try running it."
+ "Here's another example that demonstrates simple addition. Try running it."
]
},
{
@@ -82,8 +81,7 @@
"metadata": {},
"outputs": [],
"source": [
- "for i in range(10):\n",
- " print(i,2*i)"
+ "print(10 +)"
]
},
{
@@ -175,7 +173,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.9"
+ "version": "3.8.2"
}
},
"nbformat": 4,
diff --git a/chapters/00_introduction/welcome.ipynb b/content/99_intro01-Copy1.ipynb
similarity index 94%
rename from chapters/00_introduction/welcome.ipynb
rename to content/99_intro01-Copy1.ipynb
index 651726d..b80aa72 100644
--- a/chapters/00_introduction/welcome.ipynb
+++ b/content/99_intro01-Copy1.ipynb
@@ -40,9 +40,7 @@
"
\n",
"
\n",
"\n",
- "Do you remember how to run a code cell? Visit the [Jupyter Notebook Intro](00_Jupyter_Notebook_Intro.ipynb) if you need a refresher.\n",
- "\n",
- "To test your knowledge, run the code cell above and observe the output. Then modify the program to print your name, rather than `Hello World`, and run it again."
+ "Do you remember how to run a code cell? Visit the first jupyter notebook if you need a refresher. To test your knowledge, run the code cell above and observe the output. Then modify the program to print your name, rather than `Hello World` and run it again."
]
},
{
@@ -56,7 +54,7 @@
"- Addition: `+`\n",
"- Subtraction: `-`\n",
"- Multiplication: `*`\n",
- "- Division: `\\`"
+ "- Division: `/`"
]
},
{
@@ -163,6 +161,8 @@
"source": [
"## Additional Resources\n",
"\n",
+ "[An Informal Introduction to Python](https://docs.python.org/3/tutorial/introduction.html)\n",
+ "\n",
"[Python Resources for Beginners](https://wiki.python.org/moin/BeginnersGuide/Programmers)\n",
"\n",
"[Python Introduction (w3schools)](https://www.w3schools.com/python/python_intro.asp)"
@@ -204,7 +204,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.9"
+ "version": "3.8.2"
}
},
"nbformat": 4,
diff --git a/content/99_strings00-Copy1.ipynb b/content/99_strings00-Copy1.ipynb
new file mode 100644
index 0000000..cdc1e0c
--- /dev/null
+++ b/content/99_strings00-Copy1.ipynb
@@ -0,0 +1,505 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Introduction to Strings\n",
+ "\n",
+ "Let's begin our exploration of strings with a technical definition:\n",
+ "\n",
+ "*Strings are considered a \"Collection Class\", meaning they are a collection of other data types. A String is an array of [bytes](https://simple.wikipedia.org/wiki/Byte) representing [Unicode](https://en.wikipedia.org/wiki/Unicode) characters. Python does not have a character data type, so a single character is simply a string with a length of 1. Strings are iterable, immutable and ordered. Duplicates are allowed in strings.*\n",
+ "\n",
+ "We'll explore this definition in more detail throughout this notebook.\n",
+ "\n",
+ "*Note: Like any other programming language, there are many ways to approach problems in Python. Two completely different approaches may be equally valid. Keep in mind that as you go through these examples you'll often see multiple ways of doing the same thing. No particular approach is presented here as \"the best\" or \"the only\" way do do things. Find your own unique programming style and embrace it!*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Representing Strings\n",
+ "\n",
+ "Strings are represented with quotation marks. Python is more forgiving than some other programming languages, so you may represent strings with either double-quote marks (`\"`) or single quote marks (`'`). The only rule is that you cannot mix marks within the same string definition.\n",
+ "\n",
+ "Run the code samples below, in particular examine the error message that results when using mixed quotes:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Valid strings"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Welcome to Python\" # Double quotes\n",
+ "print(s1)\n",
+ "s2 = 'Exploring Strings' # Single Quotes\n",
+ "print(s2)\n",
+ "s3 = 'A' # A string with one character is allowed\n",
+ "print(s3)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Invalid string"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Mixing quotes is not allowed'\n",
+ "print(s1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "When first learning a programming language, it's not uncommon to confuse numbers as integers (e.g. `x = 42`), with numbers as strings (e.g. `x = \"42\"`). Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 42\n",
+ "y = 43\n",
+ "print(x)\n",
+ "print(y)\n",
+ "print(x + y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = 42\n",
+ "y = \"43\"\n",
+ "print(x)\n",
+ "print(y)\n",
+ "print(x + y) # This line should cause a crash"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x = \"42\"\n",
+ "y = \"43\"\n",
+ "print(x)\n",
+ "print(y)\n",
+ "print(x + y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### What happened?\n",
+ "\n",
+ "Sample 3 is interesting. Why doesn't it crash? Doesn't Sample 2 demonstrate that you can't add strings?\n",
+ "\n",
+ "Not exactly. Sample 2 demonstrates that you can't add a string to an integer. Sample 3 demonstrates that you can merge two (or more) strings together using the `+` operator, and the result is a new string that represents the combination of the two. The term for combining strings in this way is *concatenation*.\n",
+ "\n",
+ "Python has so many awesome little tricks that make it such a fun programming language. We certainly won't be able to explore every single one, but I'll try to point them out as we demonstrate new topics. Run the code below to see what I mean :-)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "n = input(\"Enter desired number of As: \")\n",
+ "total = int(n)\n",
+ "print(\"A\" * total)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Definitions\n",
+ "\n",
+ "In the technical definition of a string, we introduced three new terms: *iterable*, *immutable* and *ordered*. Let's examine each of these."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### __*iterable*__\n",
+ "\n",
+ "Iteration (iterable) is just a fancy term for looping again and again. It's a critically important part of any programming language and we'll spend several lessons on this topic throughout the course. For now, let's just think of iteration as performing some operation on every character in a string. To make use of interation on strings, you need to know how we access individual characters.\n",
+ "\n",
+ "We refer to a character's position in a string as its *index*. The first character in a string is always located at index `0`, and the last character in a string is always at an index that is one less then the number of characters in the string. We access an individual character at a particular index by using bracket notation (`[]`), along with the desired index.\n",
+ "\n",
+ "Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go Navy\"\n",
+ "print(s[0])\n",
+ "print(s[3])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The character in the string `s` at position `0` is `'G'`; and the character at position `3` is `'N'`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go Navy\"\n",
+ "print(s[0])\n",
+ "print(s[1])\n",
+ "print(s[2])\n",
+ "print(s[3])\n",
+ "print(s[4])\n",
+ "print(s[5])\n",
+ "print(s[6])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Sample 2 shows a simple form of iteration to print every character in a string. It's a good start, but we'll explore more sophisticated iteration techniques throughout the course. Also note that a `space` is also considered a character (the character at `s[2]`)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go Navy\"\n",
+ "print(s[0])\n",
+ "print(s[5])\n",
+ "print(s[7])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "The code above should crash when you run it. Remember, for a string of length `n`, individual characters are located at indices in the range from `0` to `n-1`.\n",
+ "\n",
+ "* Which line above caused the crash?\n",
+ "* What error message did you get?\n",
+ "* Change the code above so it prints `o`, `N`, `v`, each on a separate line, without crashing."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### __*immutable*__\n",
+ "\n",
+ "If something is immutable, it means that once it's created, it can't be changed. Mutability can be a confusing topic, so we'll explore with examples.\n",
+ "\n",
+ "Strings are immutable. While you can change the entire value of a string in a variable, you cannot change the value of an individual character *inside* a string variable.\n",
+ "\n",
+ "Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Go\"\n",
+ "print(s)\n",
+ "s = \"Navy\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The code above runs fine. The variable `s` starts with a value of `Go`, is printed, then changes to the value `Navy`, and is printed again."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Hot Air\"\n",
+ "print(s)\n",
+ "s[0] = \"N\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The code above crashes. Which line causes the crash and what error did you get? Does that mean we can never change `Hot Air` to `Not Air`? Not really. Advanced string manipulation techniques include __*slicing*__ and __*splitting*__, which we'll cover in future topics. For now, we can use the straightforward technique shown in Sample 3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Hot Air\"\n",
+ "print(s)\n",
+ "s = \"Not Air\"\n",
+ "print(s)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### __*ordered*__\n",
+ "\n",
+ "Strings are ordered, because the programmer controls the order in which the characters are arranged and can be confident that once created, a particular character will always be in the same place within a string. It may sound obvious at this point, but we'll explore **dictionaries** and **sets** later in the course, which are unordered. The comparison will become clearer when we see those advanced data types.\n",
+ "\n",
+ "Explore the code samples below:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Sample 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s = \"Python is awesome\"\n",
+ "print(s[3])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The character at index `3` will always be `h`, as long as the value of `s` doesn't change."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### A final word about empty strings\n",
+ "\n",
+ "Can we create a string variable without any characters in it? The answer is, yes. It's a very handy and frequently used design pattern.\n",
+ "\n",
+ "Remember this example from the introduction notebook that shows a variable (`score`) on both sides of the equal sign?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "score = 45\n",
+ "print(score)\n",
+ "score = score + 10\n",
+ "print(score)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "1. Evaluate everything to the right of `=`. That means, take the current value in `score` (45) and add 10 to it.\n",
+ "2. Take the result from step 1 and store it in the variable named `score`. This replaces `score`'s original value (45) with the newly calculated value (55)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can initialize string variables to be empty strings (`\"\"`) and perform concatenation in a similar fashion:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "fullname = \"\"\n",
+ "firstname = input(\"Enter your first name: \")\n",
+ "fullname = fullname + firstname\n",
+ "lastname = input(\"Enter your last name: \")\n",
+ "fullname = fullname + lastname\n",
+ "print(fullname)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "The code above will print your full name with no spaces between first name and last name. When asked for your first name, you could just add a space to the end of what you type, but try modifying the code above to insert a space between first and last name without making the user have to type it."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Additional Resources\n",
+ "\n",
+ "[Python Strings: w3schools](https://www.w3schools.com/python/python_strings.asp)\n",
+ "\n",
+ "[An Informal Introduction to Python](https://docs.python.org/3/tutorial/introduction.html)\n",
+ "\n",
+ "[Strings and Character Data in Python](https://realpython.com/python-strings/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "\n",
+ "*MIT License*\n",
+ "\n",
+ "*Copyright 2019-2020 Peter Nardi*\n",
+ "\n",
+ "*Terms of use:*\n",
+ "\n",
+ "*Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:*\n",
+ "\n",
+ "*The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.*\n",
+ "\n",
+ "*THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/chapters/16_advanced/bigO.ipynb b/content/bigO.ipynb
similarity index 100%
rename from chapters/16_advanced/bigO.ipynb
rename to content/bigO.ipynb
diff --git a/chapters/17_utilities/codeTemplate.ipynb b/content/codeTemplate.ipynb
similarity index 100%
rename from chapters/17_utilities/codeTemplate.ipynb
rename to content/codeTemplate.ipynb
diff --git a/chapters/10_dictionaries/dictionaries.ipynb b/content/dictionaries.ipynb
similarity index 100%
rename from chapters/10_dictionaries/dictionaries.ipynb
rename to content/dictionaries.ipynb
diff --git a/chapters/16_advanced/fibonacci.ipynb b/content/fibonacci.ipynb
similarity index 100%
rename from chapters/16_advanced/fibonacci.ipynb
rename to content/fibonacci.ipynb
diff --git a/chapters/09_crypto/hashing.ipynb b/content/hashing.ipynb
similarity index 98%
rename from chapters/09_crypto/hashing.ipynb
rename to content/hashing.ipynb
index bb17cbd..91f61b3 100644
--- a/chapters/09_crypto/hashing.ipynb
+++ b/content/hashing.ipynb
@@ -140,6 +140,8 @@
"source": [
"## Additional Resources\n",
"\n",
+ "[Secure hashes and message digests](https://docs.python.org/3/library/hashlib.html)\n",
+ "\n",
"[Cryptographic Hash Functions Explained: A Beginner’s Guide](https://komodoplatform.com/cryptographic-hash-function/)"
]
},
@@ -179,7 +181,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.9"
+ "version": "3.8.2"
}
},
"nbformat": 4,
diff --git a/chapters/07_lists/lists.ipynb b/content/lists.ipynb
similarity index 100%
rename from chapters/07_lists/lists.ipynb
rename to content/lists.ipynb
diff --git a/chapters/14_recursion/recursion.ipynb b/content/recursion.ipynb
similarity index 100%
rename from chapters/14_recursion/recursion.ipynb
rename to content/recursion.ipynb
diff --git a/chapters/11_sets/sets.ipynb b/content/sets.ipynb
similarity index 100%
rename from chapters/11_sets/sets.ipynb
rename to content/sets.ipynb
diff --git a/chapters/06_strings/strings.ipynb b/content/strings11.ipynb
similarity index 90%
rename from chapters/06_strings/strings.ipynb
rename to content/strings11.ipynb
index 490be2c..1ffe268 100644
--- a/chapters/06_strings/strings.ipynb
+++ b/content/strings11.ipynb
@@ -4,27 +4,62 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Strings, Lists, Dictionaries and Sets\n",
+ "# Introduction to Strings\n",
"\n",
- "* *Strings* are arrays of bytes representing Unicode characters. Python does not have a character data type, so a single character is simply a string with a length of 1. Strings are **iterable**, **immutable** and **ordered**. Duplicates are allowed in strings.\n",
+ "Let's begin our exploration of strings with a techincal definition:\n",
"\n",
- "* *Lists* are like arrays in other languages. Python lists can be heterogeneous, which makes them very powerful. For example, this is a perfectly legal list in Python:
`[\"Hello\", 0, 3.141]`. Lists are **iterable**, **mutable** and **ordered**. Duplicates are allowed in lists.\n",
+ "*Strings are considered a \"Collection Class\", meaning they are a collection of other data types. A String is an array of [bytes](https://simple.wikipedia.org/wiki/Byte) representing [Unicode](https://en.wikipedia.org/wiki/Unicode) characters. Python does not have a character data type, so a single character is simply a string with a length of 1. Strings are iterable, immutable and ordered. Duplicates are allowed in strings.*\n",
"\n",
- "* *Dictionaries* are collections of key-value pairs. Keys in dictionaries can be any **immutable** type; for example, strings and numbers can always be keys. A Dictionary in Python works in a similar way to a Dictionary in a real world. Dictionaries are **iterable**, **mutable** and **unordered**. Duplicate *keys* are not allowed in dictionaries.\n",
+ "We'll explore this definition in more detail throughout this notebook.\n",
"\n",
- "* *Sets* in Python are equivalent to sets in mathematics. Python sets can be heterogeneous, which makes them very powerful. For example, this is a perfectly legal set in Python:
`{\"Hello\", 0, 3.141}`. Sets are **iterable**, **mutable** and **unordered**. Duplicates are not allowed in sets (this actually makes them really useful, as we'll see later).\n",
+ "*Note: Like any other programming language, there are many ways to approach problems in Python. Two completely different approaches may be equally valid. Keep in mind that as you go through these examples you'll often see multiple ways of doing the same thing. No particular approach is presented here as \"the best\" or \"the only\" way do do things. Find your own unique programming style and embrace it!*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Representing Strings\n",
"\n",
- "Strings, Lists, Dictionaries and Sets are generally termed *Collection Classes*, meaning they are collections of other data types.\n",
+ "Strings are represented with quotation marks. Python is more forgiving than some other programming languages, so you may represent strings with either double-quote marks (`\"`) or single quote marks (`'`). The only rule is that you cannot mix marks within the same string definition.\n",
"\n",
- "*Like any other programming language, there are many ways to approach problems in Python. Two completely different approaches may be equally valid. Keep in mind that as you go through these examples you'll often see multiple ways of doing the same thing. No particular approach is presented here as \"the best\" or \"the only\" way do do things. Find your own unique programming style and embrace it!*"
+ "Run the code samples below, in particular examine the error message that results when using mixed quotes:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "### Strings\n",
- "Here are examples of some common design patterns using strings. Let's start with finding the length of a string and accessing individual characters."
+ "#### Valid strings"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Welcome to Python\"\n",
+ "print(s1)\n",
+ "s2 = 'Exploring Strings'\n",
+ "print(s2)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Invalid String"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s1 = \"Mixing quotes is not allowed'\n",
+ "print(s1)"
]
},
{
@@ -38,6 +73,14 @@
"Why do we access the last character in the string below with `s[length-1]` instead of `s[length]`?"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Strings\n",
+ "Here are examples of some common design patterns using strings. Let's start with finding the length of a string and accessing individual characters."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -653,7 +696,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.9"
+ "version": "3.8.2"
}
},
"nbformat": 4,
diff --git a/chapters/13_exceptions/tryExcept.ipynb b/content/tryExcept.ipynb
similarity index 95%
rename from chapters/13_exceptions/tryExcept.ipynb
rename to content/tryExcept.ipynb
index ca31276..f48af8b 100644
--- a/chapters/13_exceptions/tryExcept.ipynb
+++ b/content/tryExcept.ipynb
@@ -18,7 +18,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "From the Python documentation located at [docs.python.org](https://docs.python.org):"
+ "From the [Python documentation](https://docs.python.org/3/tutorial/errors.html):"
]
},
{
@@ -32,10 +32,6 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "
\n",
- "
\n",
- "
\n",
- "\n",
"What will happen when you run the code below and why?"
]
},
@@ -61,10 +57,6 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "
\n",
- "
\n",
- "
\n",
- "\n",
"Examine and run the code below. Why does `line 3` get executed if you enter the number 8, but it doesn't get executed if you enter the character 'A'?"
]
},
@@ -254,7 +246,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.6.9"
+ "version": "3.8.2"
}
},
"nbformat": 4,
diff --git a/chapters/12_tuples/tuples.ipynb b/content/tuples.ipynb
similarity index 100%
rename from chapters/12_tuples/tuples.ipynb
rename to content/tuples.ipynb
diff --git a/chapters/15_oop/userClasses.ipynb b/content/userClasses.ipynb
similarity index 100%
rename from chapters/15_oop/userClasses.ipynb
rename to content/userClasses.ipynb
diff --git a/images/check.png b/images/00check.png
similarity index 100%
rename from images/check.png
rename to images/00check.png
diff --git a/images/00documentation.png b/images/00documentation.png
new file mode 100644
index 0000000..6055ea4
Binary files /dev/null and b/images/00documentation.png differ
diff --git a/images/00shutdown.png b/images/00shutdown.png
new file mode 100644
index 0000000..3c360da
Binary files /dev/null and b/images/00shutdown.png differ