diff --git a/.gitignore b/.gitignore index 41068f6..3ec89e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# TeachBooks +.teachbooks/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/book/01/In_a_Nutshell/01.ipynb b/book/01/In_a_Nutshell/01.ipynb deleted file mode 100644 index e725a45..0000000 --- a/book/01/In_a_Nutshell/01.ipynb +++ /dev/null @@ -1,907 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 1. Variables, operators and functions." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Excuting a cell in python" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The print() function in Python is used to output or display text or other information on the screen. It can be used to display a string of text, the value of a variable, or the result of a calculation. The text or information that you want to display is passed as an argument inside the parenthesis of the print() function.\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Print () command" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To execute a cell in Python, you can use the run command in Jupyter Notebook or press the \"Run\" button in the toolbar. You can also use the keyboard shortcut **Shift + Enter** to execute the cell. \n", - "\n", - "Lets start by excecuting our first code by printing the words 'Hello world'. Press **Shift+Enter** to run the cell below. You should see the output \"Hello, World!\" displayed below the cell. Notice that we have to write the sentence inside the quotation marks to indicate that the data is of string type. \n", - "\n", - "Alternatively, You can also execute the code by clicking on the Run button in the toolbar or by using the run command in the Jupyter Notebook." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello, world!\n" - ] - } - ], - "source": [ - "print ('Hello, world!')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, try to fill in your name and print the following sentence in the next cell: \n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "My name is _____\n" - ] - } - ], - "source": [ - "print ('My name is _____')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Basic input and out definitions in python" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Value\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python, a **value** is any data that can be stored in a variable. It can be a number (such as an integer or a float), a string (a sequence of characters), a Boolean (True or False), or other types of data. For example" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "x = 5 # x is a variable that holds an integer value of 5\n", - "y = \"Hello World\" # y is a variable that holds a string value of \"Hello World\"\n", - "z = True # z is a variable that holds a Boolean value of True" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Variable " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A **variable** is a container that holds a value, which is like a label or a name given to the value that is stored inside it. You can use variables to store values and then use them later in your code. You can also change the value of a variable at any time. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "x = 5 # x is a variable that holds an integer value of 5\n", - "x = x + 2 # x now holds the value of 7" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### String" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A string is a sequence of characters, enclosed in quotation marks. You can use strings to store text, such as words and sentences. You can also use them to display messages to the user or to create strings that hold specific data, like a name or an address. Strings are a very important data type in python and you will use it very frequently. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Hello World'" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\"Hello World\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### List" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A list in Python is a collection of values stored in a single object, similar to arrays in other programming languages. Lists can contain elements of any type, including numbers, strings, and other objects. \n", - "\n", - "To create a list in Python, you can use square bracket [ ] notation and include the values you want to store in the list, separated by commas.\n", - "\n", - "For a beginner, it's important to remember the following when creating lists in Python:\n", - "\n", - "* Lists start with a square bracket [ ]\n", - "* Values in the list are separated by commas\n", - "* Lists can contain elements of any type, including numbers, strings, and other objects." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3.14, 'Hello', True]\n" - ] - } - ], - "source": [ - "# create a list\n", - "my_list = [1, 2, 3.14, \"Hello\", True]\n", - "\n", - "# print the list\n", - "print(my_list)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Indexing in Python is a way to access specific elements in a list or array. Think of a list as a row of boxes, where each box contains a value. The index is the number assigned to each box [ ] and it allows us to locate a specific value or object. Lists in Python are zero-indexed, meaning that the first element in the list is stored at index 0, the second element is stored at index 1, and so on. For example, we an print any element in out created list by specifying the index releated:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "Hello\n", - "3.14\n" - ] - } - ], - "source": [ - "# access elements by index\n", - "print(my_list[0]) # prints the integer 1\n", - "print(my_list[3]) # prints the string \"Hello\"\n", - "print (my_list[2]) # prints the float 3.14" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## type () of data in python " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python, you can use the built-in type() function to determine the type of an object. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\n" - ] - } - ], - "source": [ - "x = 5\n", - "print(type(x)) # Output: \n", - "\n", - "y = \"hello\"\n", - "print(type(y)) # Output: \n", - "\n", - "z = [1, 2, 3]\n", - "print(type(z)) # Output: " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also check an object's type very simply by:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "int" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "x2 = 5\n", - "type(x2) # Output: int" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "str" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "y2 = 'hello'\n", - "type(y2) # Output: str" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "list" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "z2 = [1, 2, 3]\n", - "type(z2) # Output: list" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Arithmetic Operators\n", - "\n", - "| Math sign | Python sign | name |\n", - "| :-: | :-: |:-:|\n", - "| + | + | addition |\n", - "| - | - | subtraction |\n", - "| * | * | multiplication |\n", - "| / | / | division |\n", - "| ^ | ** | exponentiation |\n", - "| mod | % | modulus |\n", - "| | // | floor division |" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Arithmetic operators: These operators perform mathematical operations, such as addition, subtraction, multiplication, and division. Examples:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7\n", - "3\n", - "10\n", - "2.5\n", - "25\n" - ] - } - ], - "source": [ - "x = 5\n", - "y = 2\n", - "\n", - "print(x + y) # Output: 7 \n", - "print(x - y) # Output: 3\n", - "print(x * y) # Output: 10\n", - "print(x / y) # Output: 2.5\n", - "print(x**y) # output: 25\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Error codes in python" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "When you run a Python script or code in a cell, the code is executed line by line, starting from the first line and moving down the code.\n", - "\n", - "If an error occurs, Python will stop executing the code at the line where the error occurs and will display an error message. The first line of the error will indicating the line number where the error occurred. This is often the most informative as it tells you where in your code the problem is. The last line in the error message will tell you what the problem in this line is." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The code results in a TypeError because you are trying to add a variable of type integer (a) to a variable of type string (b). In python, you can only add two variables of the same type. You can't add an int to a string.\n", - "If you want to concatenate the string and the int you can convert the int to string before adding them together. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is an example:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0hello\n" - ] - } - ], - "source": [ - "a = 0\n", - "b = \"hello\"\n", - "c = str(a) + b\n", - "\n", - "print (c)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or you can use the format() method to insert the value of a into the string b." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "hello 5\n" - ] - } - ], - "source": [ - "a = 5\n", - "b = \"hello {}\"\n", - "c = b.format(a)\n", - "\n", - "print (c)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Or you can use f-strings (formatted string literals) that are available from python 3.6 and above. You can show a nummerical output with any string you want using f-strings. The code you need to type for f-strings: **f ' text {output} '**. The output has to be inside the curly brackets --> { } " - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "hello 5\n" - ] - } - ], - "source": [ - "a = 5\n", - "b = \"hello\"\n", - "c = f\"{b} {a}\"\n", - "\n", - "print (c)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Comparison Operators
In Python, you often want to compare a value with another. For that, you use comparison operators.\n", - "\n", - "| Math sign | Python sign | Meaning |\n", - "| :-: | :-: | :-: |\n", - "| $=$ | $==$ | Equal to |\n", - "| $>$ | $>$ | Greater than |\n", - "| $<$ | $<$ | Less than |\n", - "| $\\geqslant$ | $>=$ | Greater than or equal to |\n", - "| $\\leqslant$ | $<=$ | Less than or equal to |\n", - "| $\\neq$ | $!=$ | Not equal to |" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Comparison operators: These operators compare two values and return a Boolean value (True or False). Examples:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "True\n", - "True\n", - "False\n", - "True\n", - "False\n" - ] - } - ], - "source": [ - "x = 5\n", - "y = 2\n", - "print(x == y) # Output: False\n", - "print(x != y) # Output: True\n", - "print(x > y) # Output: True\n", - "print(x < y) # Output: False\n", - "print(x >= y) # Output: True\n", - "print(x <= y) # Output: False\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Control flow statements in Python" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are several control flow statements in Python that are used to control the flow of execution of a program. The most important ones are:" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**if** statement: The if statement is used to check a certain condition, and if the condition is true, the code within the if block will be executed. If the condition is false, the code within the if block will be skipped. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "x is positive\n" - ] - } - ], - "source": [ - "x = 5\n", - "if x > 0:\n", - " print(\"x is positive\")\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**if-else** statement: The if-else statement is an extension of the if statement, which allows you to specify a block of code to be executed if the condition is true, and a different block of code to be executed if the condition is false. Example:" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "x is non-positive\n" - ] - } - ], - "source": [ - "x = -2\n", - "if x > 0:\n", - " print(\"x is positive\")\n", - "else:\n", - " print(\"x is non-positive\")\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**if-elif-else** statement: The if-elif-else statement is an extension of the if-else statement, which allows you to check multiple conditions and execute different code blocks based on the first condition that is true. This is how you use them: " - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "x is zero\n", - "x2 is negative\n" - ] - } - ], - "source": [ - "x = 0\n", - "if x > 0:\n", - " print(\"x is positive\")\n", - "elif x == 0:\n", - " print(\"x is zero\")\n", - "else:\n", - " print(\"x is negative\")\n", - " \n", - "\n", - "x2 = -2\n", - "if x2 > 0:\n", - " print(\"x2 is positive\")\n", - "elif x2 == 0:\n", - " print(\"x2 is zero\")\n", - "else:\n", - " print(\"x2 is negative\")\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Indexing" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Indexing is a method in Python to access individual elements in a list by their position. This is a fundamental feature of Python's list data structure, allowing you to retrieve specific elements from the list. Elements are stored in a sequential manner and can be accessed using their index (integer value indicating their position)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Functions " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In Python, a function is a block of code that can be reused multiple times throughout a program. Functions are useful for organizing and structuring code, and for breaking down complex tasks into smaller, more manageable pieces. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Below are some examples of common built-in Python functions and what they do:\n", - "\n", - "\n", - "* ``print()`` Prints input to screen\n", - "* ``type()`` Returns the type of the input\n", - "* ``abs()`` Returns the absolute value of the input\n", - "* ``min()`` Returns the minimum value of the input. \n", - " (input could be a list, tuple, etc.)\n", - "* ``max()`` Same as above, but returns the maximum value\n", - "* ``sum()`` Returns the sum of the input \n", - " (input could be a list, tuple, etc.)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is a step-by-step guide on how to create any function in Python:\n", - "\n", - "**Step 1:** Define the function using the def keyword, followed by the function name, and a set of parentheses.\n", - "\n", - "**Step 2:** Define the code block that will be executed when the function is called. This code block should be indented underneath the function definition. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "def greet():\n", - " print(\"Hello, World!\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Step 3:** (Optional) Add parameters to the function, which are values that can be passed into the function when it is called. These parameters are defined within the parentheses of the function definition. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "def greet(name):\n", - " print(\"Hello, \" + name + \"!\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Step 4:** (Optional) Add a return statement to the function, which is used to return a value or an expression from the function. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "def add(x, y):\n", - " return x + y" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Step 5:** Call the function by using the function name, followed by a set of parentheses. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello, John Weller!\n" - ] - } - ], - "source": [ - "greet(\"John Weller\")\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Thus, to create and use the function we write it all in one cell as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello, John!\n", - "Hello, Mary Jane!\n" - ] - } - ], - "source": [ - "def greet(name):\n", - " print(\"Hello, \" + name + \"!\")\n", - "\n", - "greet(\"John\")\n", - "greet(\"Mary Jane\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this example, the function **greet()** is defined with one parameter **name**, the function is called twice, first with \"John\" as an **argument**, then with \"Mary\" as an **argument**, the function will print out a greeting message each time it's called --> the **input** of the created function is the argument and the **output** is the greeting message.\n", - "\n", - "Functions are essential to programming, they allow you to organize, structure and reuse your code in an efficient and readable way." - ] - } - ], - "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.11.2" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/book/02/In_a_Nutshell/01.ipynb b/book/02/In_a_Nutshell/01.ipynb deleted file mode 100644 index bdae527..0000000 --- a/book/02/In_a_Nutshell/01.ipynb +++ /dev/null @@ -1,774 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 2. Modules, conditions, data structures and loops" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2.1 Python Modules" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Math " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Python's **math** module provides a collection of mathematical functions and constants for various numerical operations. These functions are useful for performing mathematical calculations in Python. Here are some commonly used functions from the math module:\n", - "\n", - "* The math.sqrt( ) function returns the square root of a number\n", - "* The math.ceil( ) function returns the smallest integer greater than or equal to a given number\n", - "* The math.floor( ) function returns the largest integer less than or equal to a given number\n", - "* The math.pow( ) function returns the value of the first argument raised to the power of the second argument\n", - "* The math.exp( ) function returns the exponential value of a number\n", - "* The math.log( ) function returns the natural logarithm of a number\n", - "* The math.sin( ) function returns the sine of an angle given in radians\n", - "* The math.cos( ) function returns the cosine of an angle given in radians\n", - "* The math.radians( ) function converts an angle from degrees to radians\n", - "\n", - "*Note: to see what each input a functions can take, press **shift+tab** or **crt+shift+space** within function parentheses.* " - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4.0\n", - "4\n", - "3\n", - "8.0\n", - "2.718281828459045\n", - "2.302585092994046\n", - "1.0\n", - "1.0\n", - "3.141592653589793\n" - ] - } - ], - "source": [ - "import math\n", - "\n", - "result_sqrt = math.sqrt(16 )\n", - "result_ceil = math.ceil(3.2)\n", - "result_floor = math.floor(3.9)\n", - "result_pow = math.pow(2, 3)\n", - "result_exp = math.exp(1)\n", - "result_log = math.log(10)\n", - "result_sin = math.sin(math.pi/2)\n", - "result_cos = math.cos(0)\n", - "result_radians = math.radians(180)\n", - "\n", - "print(result_sqrt) \n", - "print(result_ceil) \n", - "print(result_floor) \n", - "print(result_pow) \n", - "print(result_exp) \n", - "print(result_log) \n", - "print(result_sin) \n", - "print(result_cos) \n", - "print(result_radians) \n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Listing all functions " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A docstring tooltip (like a function explanation box) is like a special helper box that appears when you press a button. It tells you what a function does and how to use it correctly, just like a special box that explains what a magic toy does and how to play with it. The function explanation box helps programmers understand functions better, making programming easier and more enjoyable.There are two very common methods to use this tooltip:" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. Using the help() function: To access the docstring tooltip using the help() function, you can include it in your Python code followed by the name of the function you want to learn more about. When you run the code, the docstring tooltip will be displayed in the console or output window. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Help on built-in function pow in module math:\n", - "\n", - "pow(x, y, /)\n", - " Return x**y (x to the power of y).\n", - "\n" - ] - } - ], - "source": [ - "help (math.pow)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Many popular Python IDEs offer built-in support for the docstring tooltip. Inside the parentheses of a function, you can press **Shift+Tab** or **Ctrl+Shift+Space**, and the tooltip will appear, providing the function's documentation. This feature is available in IDEs like PyCharm, Visual Studio Code, and Jupyter Notebook." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Python third-party modules\n", - "\n", - "Besides built-in modules, there are also modules developed by other people and companies, which can be also used in your code.\n", - "\n", - "These modules are not installed by default in Python, they are usually installed by using the 'pip' or 'conda' package managers and accessed like any other Python module.

This YouTube video explains how to install Python Packages with 'pip' and 'conda'." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### numpy\n", - "\n", - "The numpy module is one of the most popular Python modules for numerical applications. Due to its popularity, developers tend to skip using the whole module name and use a smaller version of it (np). A different name to access a module can be done by using the as keyword, as shown below. The **import numpy as np** statement imports the NumPy module, allowing us to use its functionalities." - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "my_array = np.array([1, 2, 3, 4, 5])\n", - "a = np.array([1, 2, 3])\n", - "b = np.array([4, 5, 6])\n", - "result = a + b" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Matplotlib\n", - "\n", - "Matplotlib is a Python library widely used for creating visualizations and plots. It provides a simple and flexible way to display data in the form of graphs, charts, and other visual representations. It is commonly used in scientific and data analysis applications. \n", - "\n", - "To use Matplotlib, you need to follow these steps:\n", - "\n", - "1. Importing Matplotlib: Start by importing the Matplotlib library in your Python program using the import statement. This makes the Matplotlib functions and classes available for use.\n", - "\n", - "2. Creating a Figure and Axes: Next, create a figure and axes objects. The figure represents the entire image or window where your plot will be displayed. The axes represent the coordinate system within the figure where your plot will be drawn.\n", - "\n", - "3. Plotting Data: Now, use the axes object to plot your data (plt.plot() function is the most commonly used type of plot). You can choose from various plot types like line plots, scatter plots, bar plots, etc., depending on the nature of your data.\n", - "\n", - "4. Customizing the Plot: You can customize the appearance of your plot by adding labels, titles, legends, adjusting colors, and more. This helps in making the plot more informative and visually appealing.\n", - "\n", - "5. Displaying the Plot: Finally, you can display your plot by using the plt.show() function. \n", - "\n", - "Here is a simple example: " - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAHHCAYAAACvJxw8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB40UlEQVR4nO3deXiTVdrH8W/SfV/oTgtlX6TQUqSyKDB2AMUZcBgUXxRhAEcFlYFxYVRQUHFBR0HUEWVxG3DXQUURBFQqe9lBltIW6AKU7nRL8v7xNMFKWwokPVnuz3XlakifJL+EQu6ec5776EwmkwkhhBBCCFEvveoAQgghhBD2TIolIYQQQohGSLEkhBBCCNEIKZaEEEIIIRohxZIQQgghRCOkWBJCCCGEaIQUS0IIIYQQjZBiSQghhBCiEVIsCSGEEEI0QoolIYTDMRqNdOvWjaeffvqS7/vII4+QkpJySfd54YUXaNu2LW5ubiQmJl7yczaHdevWodPpWLduneooQjgdKZaEEE1y5MgR/v73v9O2bVu8vb0JDAykX79+vPLKK5w7d65Zs/z3v/8lOzubKVOmXPJ9p06dys6dO/nyyy+bdPx3333HQw89RL9+/ViyZAnPPPPMJT+nNb322mssXbpUaQYhXI1O9oYTQlzMV199xahRo/Dy8mLs2LF069aNqqoqfvrpJz755BPGjRvHm2++2Wx5EhMTSUlJ4T//+c9l3f/WW28lJyeHDRs2XPTYRx55hBdeeIFz587h6el5Wc9nTd26dSMsLOyCESSj0UhVVRWenp7o9fJ7sBDW5K46gBDCvmVkZDB69Ghat27N2rVriY6Otnxv8uTJHD58mK+++qrZ8uzYsYOdO3fy4osvXvZj3HLLLYwaNYqjR4/Stm3bRo/Nz8/Hx8fHLgqlxuj1ery9vVXHEMIpya8fQohGPf/885SWlvL222/XKZTM2rdvzwMPPGD5c01NDXPmzKFdu3Z4eXkRHx/Pv/71LyorK+vcb+vWrQwZMoSwsDB8fHxo06YNf/vb3y6a5/PPP8fT05PrrrvOctu5c+fo3LkznTt3rjMlWFBQQHR0NH379sVgMFhuT01NBeCLL75o9Ll0Oh1LliyhrKwMnU6HTqdj6dKlHDt2zHK9vvs88cQTlj8/8cQT6HQ6Dh8+zLhx4wgODiYoKIjx48dTXl5+wf3fe+89evfuja+vLyEhIVx33XV89913AMTHx7N3717Wr19vyTNw4ECg4TVLH330EcnJyfj4+BAWFsbtt9/OiRMn6hwzbtw4/P39OXHiBCNGjMDf35/w8HD++c9/1nnfhHBVUiwJIRr1v//9j7Zt29K3b98mHT9x4kRmzpxJz549+fe//82AAQOYO3cuo0ePthyTn5/P4MGDOXbsGI888ggLFixgzJgx/PLLLxd9/I0bN9KtWzc8PDwst/n4+LBs2TIOHz7Mo48+arl98uTJFBUVsXTpUtzc3Cy3BwUF0a5dO37++edGn+vdd9/l2muvxcvLi3fffZd33323TpF2KW655RZKSkqYO3cut9xyC0uXLuXJJ5+sc8yTTz7JHXfcgYeHB7Nnz+bJJ58kLi6OtWvXAvDyyy8TGxtL586dLXl++3p/b+nSpdxyyy24ubkxd+5cJk2axKeffkr//v0pLCysc6zBYGDIkCG0aNGCefPmMWDAAF588cVmnV4Vwm6ZhBCiAUVFRSbANHz48CYdn56ebgJMEydOrHP7P//5TxNgWrt2rclkMpk+++wzE2DasmXLJWeKjY01jRw5st7vzZgxw6TX600bNmwwffTRRybA9PLLL9d77ODBg01dunS56PPdeeedJj8/vzq3ZWRkmADTkiVLLjgeMM2aNcvy51mzZpkA09/+9rc6x918882mFi1aWP586NAhk16vN918880mg8FQ51ij0Wi5ftVVV5kGDBhwwfP+8MMPJsD0ww8/mEwmk6mqqsoUERFh6tatm+ncuXOW41auXGkCTDNnzqzzGgHT7Nmz6zxmUlKSKTk5+YLnEsLVyMiSEKJBxcXFAAQEBDTp+K+//hqAadOm1bl9+vTpAJa1TcHBwQCsXLmS6urqS8p05swZQkJC6v3eE088wVVXXcWdd97Jvffey4ABA7j//vvrPTYkJITTp09f0nNfibvvvrvOn6+99lrOnDljeY8///xzjEYjM2fOvGCBtk6nu+Tn27p1K/n5+dx777111jINGzaMzp0717vOrL6MR48eveTnFsLZSLEkhGhQYGAgACUlJU06PjMzE71eT/v27evcHhUVRXBwMJmZmQAMGDCAkSNH8uSTTxIWFsbw4cNZsmTJBeuaGmJq4CReT09PFi9eTEZGBiUlJSxZsqTBQsNkMl1WEXK5WrVqVefP5oLv7NmzgNaa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Pffcw6BBg3j77bfZvHkzb7zxBhEREbRv395yAa2wat26NY8++ii9evWiQ4cOZGZmXvC406dPR6/X88033zB//nzWrl3baI64uDjuvvtuPv30U6ZPn86iRYts8nqFELYlxZIQwunMmDEDk8nEs88+C0B8fDzz5s3joYce4tixYxcc36FDB7Kysli+fDlHjhxh/vz5fPbZZ3WO+eqrr1i8eDHvv/8+f/zjH3nwwQe58847OXv2bL0Zpk6dyrfffktGRgbbt2/nhx9+oEuXLlZ/rUII25MF3kIIp7J+/Xquv/561q1bR//+/et8b8iQIdTU1PD999+j0+nqfO+hhx5i8eLFVFZWMmzYMK655hqeeOIJCgsLOXXqFAkJCTzwwAPMmDEDgOrqavr06UO7du1YsWLFBQu877vvPr755huOHz9OYGAgQ4cO5d///jctWrRotvdCCGEdUiwJIYQQQjRCpuGEEEIIIRohxZIQQgghRCOkWBJCCCGEaIQUS0IIIYQQjZBiSQghhBCiEVIsCSGEEEI0QoolIYQQQohGSLEkhBBCCNEIKZaEEEIIIRohxZIQQgghRCOkWBJCCCGEaIQUS0IIIYQQjfh/QehBf3amuW0AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "\n", - "x = np.linspace(0, 2 * np.pi, 50)\n", - "y = np.cos(x)\n", - "\n", - "x2 = np.linspace(0, -2 * np.pi, 50)\n", - "y2 = np.cos(x2)\n", - "\n", - "fig, ax = plt.subplots()\n", - "\n", - "ax.plot(x, y)\n", - "ax.plot(x2, y2, linestyle ='--')\n", - "\n", - "ax.set_xlabel('X-axis')\n", - "ax.set_ylabel('Y-axis')\n", - "ax.set_title('Cos (x) function')\n", - "plt.show()\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Loading Python files as modules\n", - "\n", - "Finally, you can also load your own (or somebody else's) Python files as modules. This is quite helpful, as it allows you to keep your code projects well-structured without the need to copy and paste everything.

In order to import another *.py file as a module, you only need to have that file and your Notebook file in the same directory and use the import keyword. More info on this here." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2.2 Conditions and if statements\n", - "\n", - "\n", - "In previous sections, you have acquired essential skills in Python such as variable creation, operator utilization, and code analysis. These skills enable you to accomplish a wide range of tasks. However, there is still a need for increased flexibility. Manually modifying your code to accommodate different data and reverting those changes can be cumbersome. In this section, you will delve into the concept of code control, which allows you to navigate the execution of your code based on specific conditions. To achieve this, you will explore a fundamental programming construct called the if statement. Through this construct, you will gain the ability to selectively process data based on defined conditions, enhancing the adaptability and efficiency of your code.\n", - "\n", - "We have three sections:\n", - "\n", - "* If Statement: The if statement enables us to execute a block of code only if a specified condition is true. It provides a way to make decisions and selectively perform actions based on whether a condition evaluates to true or false.\n", - "\n", - "* Elif Statement: The elif statement allows us to consider multiple conditions one after another and execute different blocks of code based on the first condition that evaluates to true. It provides a means to handle various possibilities and choose the appropriate action based on the situation.\n", - "\n", - "* If-else Statement: The if-else statement combines the if and else statements to perform one action if a condition is true and a different action if the condition is false. It offers a way to provide alternative paths of execution, ensuring that the code responds differently based on whether a condition is met or not.\n", - "\n", - "These conditional statements allow you to make decisions and control the flow of your program based on specific conditions. For example like this: \n" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "x is positive\n", - "x is non-positive\n", - "x is zero\n" - ] - } - ], - "source": [ - "x = 5\n", - "if x > 0:\n", - " print(\"x is positive\")\n", - "\n", - "x = -2\n", - "if x > 0:\n", - " print(\"x is positive\")\n", - "else:\n", - " print(\"x is non-positive\")\n", - "\n", - "x = 0\n", - "if x > 0:\n", - " print(\"x is positive\")\n", - "elif x < 0:\n", - " print(\"x is negative\")\n", - "else:\n", - " print(\"x is zero\")\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 2.3 Data Structures\n", - "\n", - "Welcome to an exciting new adventure in data management! In the previous module, you learned how to create variables, which was just the tip of the iceberg. Now, imagine a scenario where you have numerous variables or want to organize and access them within a single entity. That's where data structures come into play!\n", - "\n", - "Data structures are like superheroes that help us tackle complex data management challenges. They come in various forms, each with its unique purpose and complexity. Today, we'll dive into some of the superheroes of Python's built-in data structures: the mighty list, the versatile dict, and the steadfast tuple. These data structures provide us with powerful tools to store, organize, and manipulate data, enabling us to unleash the true potential of our code. Let's dive in and unlock the secrets of organized data!" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### List\n", - "A list is a powerful data structure in Python that allows you to store and manipulate an ordered collection of items. It's like having a magic box where you can keep multiple things together and change them whenever you want. Let's explore 4 different ways to create and use lists:" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. Creating an empty list:\n", - "You can create an empty list by simply using empty square brackets [ ]. It's like having a blank canvas ready to be filled with items." - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[2, 5, 3]\n" - ] - } - ], - "source": [ - "my_list = [2,5,3]\n", - "\n", - "print (my_list)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Creating an empty list - using the class constructor: You can also use the list class constructor list() to create an empty list. It's another way of preparing your container for future data." - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [], - "source": [ - "my_list = list()\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3. Creating a list from existing data: To create a list with existing data, you can directly enclose the items within square brackets [ ], separating them with commas. It's like assembling your collection of items in one go." - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['apple', 'banana', 'orange', 'kiwi']\n" - ] - } - ], - "source": [ - "fruits = ['apple', 'banana', 'orange', 'kiwi']\n", - "print (fruits)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "4. Creating a list from existing data: You can use the list constructor list( ) with an iterable (such as a string or another list) to create a new list containing the elements of that iterable. It's like transforming one collection into another." - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 2, 3, 4, 5]\n" - ] - } - ], - "source": [ - "numbers = list(range(1, 6)) # Creates a list [1, 2, 3, 4, 5]\n", - "print (numbers)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### tuple\n", - "A tuple is a data structure in Python that allows you to store an ordered collection of items. Unlike lists, tuples are immutable, meaning their elements cannot be modified once they are assigned. Let's explore how to define tuples and create examples:" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. Defining a tuple using ( ) brackets or comma:\n", - "You can define a tuple by enclosing the items within parentheses () or by simply separating them with commas. It's like creating a fixed ensemble of elements." - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1, 2, 3)\n", - "(1, 2, 3)\n" - ] - } - ], - "source": [ - "my_tuple1 = (1, 2, 3)\n", - "my_tuple2 = 1, 2, 3\n", - "\n", - "print (my_tuple1)\n", - "print (my_tuple2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Creating a tuple using the tuple class constructor: You can also use the tuple class constructor tuple() to create a tuple. It accepts an iterable as an argument and generates a tuple with its elements. It's like assembling data into a coordinated ensemble." - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(4, 5, 6)\n", - "(1, 2, 3)\n", - "(3, 5)\n", - "('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')\n" - ] - } - ], - "source": [ - "my_tuple3 = tuple([4, 5, 6])\n", - "\n", - "coordinates = (3, 5) \n", - "days_of_week = tuple(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']) \n", - "\n", - "my_tuple4 = (1, 2, 3)\n", - "print (my_tuple3)\n", - "print (my_tuple4)\n", - "print (coordinates)\n", - "print (days_of_week)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Dict\n", - "A dictionary is a versatile data structure in Python that allows you to store and retrieve data using a key-value pairing. It's like having a real-life dictionary where you can quickly look up information using specific words. Let's explore how to define dictionaries, we will explore 3 examples:" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1. Creating a dictionary using { } brackets: You can create a dictionary by enclosing key-value pairs within curly braces { }, separating each pair with a colon ' : ' It's like building a repository of information with quick access to specific entries." - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'name': 'John', 'age': 25, 'city': 'New York'}\n" - ] - } - ], - "source": [ - "my_dict = {\"name\": \"John\", \"age\": 25, \"city\": \"New York\"}\n", - "\n", - "print (my_dict)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2. Creating an empty dictionary using the class constructor: You can also use the dict class constructor dict( ) to create an empty dictionary. It's like preparing a blank canvas to populate with key-value pairs later." - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "metadata": {}, - "outputs": [], - "source": [ - "my_dict2 = dict()\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3. Creating a non-empty dictionary by specifying pairs of key-value patterns: To create a dictionary with existing data, you can specify pairs of key-value patterns within the curly braces { }. Each key-value pair is separated by a colon : and pairs are separated by commas. It's like defining relationships between different pieces of information." - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'name': 'Alice', 'age': 30, 'city': 'London'}\n" - ] - } - ], - "source": [ - "student_scores = {\"Alice\": 85, \"Bob\": 92, \"Charlie\": 78}\n", - "contacts = {\"John\": \"+123456789\", \"Emily\": \"+987654321\", \"Sam\": \"+345678912\"}\n", - "my_dict3 = dict()\n", - "my_dict3[\"name\"] = \"Alice\"\n", - "my_dict3[\"age\"] = 30\n", - "my_dict3[\"city\"] = \"London\"\n", - "\n", - "print (my_dict3)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above code cell, we have created two dictionaries: student_scores and contacts, by specifying key-value pairs within the { } brackets. Additionally, we have also demonstrated how to create an empty dictionary my_dict3 using the dict( ) constructor and then added key-value pairs to it using the square bracket notation. These examples showcase the flexibility of dictionaries in storing and accessing data through key-value relationships." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.4 Loops " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### for loop \n", - "for Loop: A for loop is used to iterate over a sequence (such as a list, tuple, or string) or any iterable object. It allows you to perform a set of statements repeatedly for each item in the sequence. Here is a simple example of how to use a for loop:" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "apple\n", - "banana\n", - "orange\n" - ] - } - ], - "source": [ - "fruits = [\"apple\", \"banana\", \"orange\"]\n", - "for fruit in fruits:\n", - " print(fruit)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### while loop\n", - "while Loop: A while loop is used to repeatedly execute a block of code as long as a given condition is true. It allows you to keep looping until the condition becomes false. Here is a simple example of how to use a while loop:" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1\n", - "2\n", - "3\n", - "4\n" - ] - } - ], - "source": [ - "count = 0\n", - "while count < 5:\n", - " print(count)\n", - " count += 1\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### break statement\n", - "break Statement: The break statement is used to prematurely exit a loop. When encountered, it terminates the loop and resumes execution at the next statement outside the loop. Here is a simple example of how to use a break statement:" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "apple\n" - ] - } - ], - "source": [ - "fruits = [\"apple\", \"banana\", \"orange\"]\n", - "for fruit in fruits:\n", - " if fruit == \"banana\":\n", - " break\n", - " print(fruit)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### continue statement\n", - "continue Statement: The continue statement is used to skip the remaining code inside a loop for the current iteration and move to the next iteration. Here is a simple example of how to use a continue statement:" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "2\n", - "4\n", - "5\n" - ] - } - ], - "source": [ - "numbers = [1, 2, 3, 4, 5]\n", - "for num in numbers:\n", - " if num == 3:\n", - " continue\n", - " print(num)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Break down of all examples**: In the first example, the for loop iterates over a list of fruits and prints each fruit. The while loop in the second example prints numbers from 0 to 4. The break statement in the third example terminates the loop when the condition is met. Lastly, the continue statement in the fourth example skips printing the number 3 and moves to the next iteration. These loop constructs provide powerful control flow mechanisms to repeat and control the execution of code blocks based on specific conditions." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "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.11.2" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/book/02/Theory/01.ipynb b/book/02/Theory/01.ipynb deleted file mode 100644 index 664a20e..0000000 --- a/book/02/Theory/01.ipynb +++ /dev/null @@ -1,3373 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "# 2. Modules, conditions, data structures and loops" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "fHmKWsUSKuj4", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 2.1 Python Modules\n", - "\n", - "Previously, you have learned how to:

1) initialize variables in Python;
2) perform simple actions with them (eg.: adding numbers together, displaying variables content, etc);
3) work with functions (have your own code in a function to reuse it many times or use a function, which was written by another person).

However, the scope of the last Notebook was limited by your Python knowledge and available functions in standard/vanilla Python (so-called 'built-in' Python functions).\n", - "There are not many Python built-in functions that can be useful for you, such as functions for math, plotting, signal processing, etc. Luckily, there are countless modules/packages written by other people.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "oyr90lgAQGtD", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Python built-in modules\n", - "\n", - "By installing any version of Python, you also automatically install its built-in modules.

One may wonder — why do they provide some functions within built-in modules, but not directly as a built-in function, such as the abs() or print()?

The answers may vary, but, generally, it is to keep your code clean; compact; and, working.

It keeps your code clean and compact as you only load functions that you need. It keeps your code working as it allows you to define your own functions with (almost) any kind of name, and use them easily, without worrying that you might 'break' something if there is a function with the same name that does something completely different." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "67a2hkUyRh_P", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### math\n", - "\n", - "The math module is one of the most popular modules since it contains all implementations of basic math functions ($sin$, $cos$, $exp$, rounding, and other functions — the full list can be found here).

In order to access it, you just have to import it into your code with an import statement. Then using ``print()`` to show that ``math`` is actually a built-in Python module." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "A1WjrfHoHYFV", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "e14b2fc7-6b0b-4f6e-8342-45c3791030b9" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "import math\n", - "print(math) " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "0ssGu7FsTEtz", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "You can now use its functions like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "11FBTZH7TATg", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "41f2699c-47a3-4ed2-f7be-b1f2ea059819" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Square root of 16 is equal to 4\n" - ] - } - ], - "source": [ - "print(f'Square root of 16 is equal to {int(math.sqrt(16))}')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "0EscmfkpTxXv", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "You can also use the constants defined within the module, such as **`math.pi`**:" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "DtwKkug2TiGT", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "60ffed22-e0e0-459b-e1dc-d35edfb5a3ff" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "π is equal to 3.141592653589793\n", - "π is equal to 3.14\n", - "π is equal to 3.1\n", - "π with two decimals is 3.14,with three decimals is 3.142 and with four decimals is 3.1416\n" - ] - } - ], - "source": [ - "print(f'π is equal to {math.pi}')\n", - "print('π is equal to {:.2f}'.format(math.pi)) \n", - "print('π is equal to {:.1f}'.format(math.pi))\n", - "print('π with two decimals is {:.2f},'\n", - " 'with three decimals is {:.3f} and with four decimals is {:.4f}'.\\\n", - " format(math.pi, math.pi, math.pi))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "`````{admonition} Let's break it down\n", - "\n", - "* ``print('π is equal to {:.2f}'.format(math.pi))`` print the variable up to some decimal, (two for example).\n", - "\n", - "* ``print('π is equal to {:.1f}'.format(math.pi))`` change the number 2 on the ':.2f' to print with more (or fewer) decimals.\n", - "\n", - "* The last line show how to print is quickly if you have to print a sentence with many variables in it.\n", - "\n", - "More information on printing best practices here.\n", - "\n", - "`````" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "M8OQGFnGf_S9", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### ``math.pi``\n", - "\n", - "As you can see, both constants and functions of a module are accessed by using: the module's name (in this case math) and a . followed by the name of the constant/function (in this case pi).

We are able to do this since we have loaded all contents of the module by using the import keyword. If we try to use these functions somehow differently — we will get an error:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 201 - }, - "collapsed": true, - "id": "98zHvteQUA3S", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "914a0a33-dfc6-45bc-d4c2-941ec4e666a9" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Square root of 16 is equal to\n", - "4.0\n" - ] - } - ], - "source": [ - "print('Square root of 16 is equal to')\n", - "print(sqrt(16))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "LRTVWDEqhGyk", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "You could, however, directly specify the functionality of the module you want to access. Then, the above cell would work.

This is done by typing: from module_name import necessary_functionality, as shown below:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "By8SDKMXhBKD", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "b277aeda-58a3-4e6d-de0e-038d843d77fe" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Square root of 16 is equal to 4.\n" - ] - } - ], - "source": [ - "from math import sqrt\n", - "\n", - "print(f'Square root of 16 is equal to {int(sqrt(16))}.')" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "pVo16M0whkK7", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "053cee25-dc6b-4604-d69c-1025bbf60e6c" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "π is equal to 3.141592653589793.\n" - ] - } - ], - "source": [ - "from math import pi\n", - "\n", - "print(f'π is equal to {pi}.')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Listing all functions\n", - "\n", - "Sometimes, when you use a module for the first time, you may have no clue about the functions inside of it. In order to unveil all the potential a module has to offer, you can either access the documentation on the corresponding web resource or you can use some Python code.\n", - "\n", - "\n", - "You can listing all contents of a module using ``dir()``. To learn something about, let's say, ``hypot`` thingy you can type the module name - dot -function name, for example ``math.hypot``." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "contents of math: ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']\n", - "math hypot is a \n" - ] - } - ], - "source": [ - "import math\n", - "print('contents of math:', dir(math))\n", - "print('math hypot is a', math.hypot) " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can also use ``?`` or ``??`` to read the documentation about it in Python" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mDocstring:\u001b[0m\n", - "hypot(*coordinates) -> value\n", - "\n", - "Multidimensional Euclidean distance from the origin to a point.\n", - "\n", - "Roughly equivalent to:\n", - " sqrt(sum(x**2 for x in coordinates))\n", - "\n", - "For a two dimensional point (x, y), gives the hypotenuse\n", - "using the Pythagorean theorem: sqrt(x*x + y*y).\n", - "\n", - "For example, the hypotenuse of a 3/4/5 right triangle is:\n", - "\n", - " >>> hypot(3.0, 4.0)\n", - " 5.0\n", - "\u001b[1;31mType:\u001b[0m builtin_function_or_method\n" - ] - } - ], - "source": [ - "math.hypot?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "2SUM0W23oAdC", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Python third-party modules\n", - "\n", - "Besides built-in modules, there are also modules developed by other people and companies, which can be also used in your code.\n", - "\n", - "These modules are not installed by default in Python, they are usually installed by using the 'pip' or 'conda' package managers and accessed like any other Python module.

This YouTube video explains how to install Python Packages with 'pip' and 'conda'.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "_o1yzxJC0NaZ", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### numpy\n", - "\n", - "The numpy module is one of the most popular Python modules for numerical applications. Due to its popularity, developers tend to skip using the whole module name and use a smaller version of it (np). A different name to access a module can be done by using the as keyword, as shown below." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "qWOdG82IhoiX", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "99446932-b303-4d84-912a-e1d4fb90545d" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "\n", - "x = [0. 0.12822827 0.25645654 0.38468481 0.51291309 0.64114136\n", - " 0.76936963 0.8975979 1.02582617 1.15405444 1.28228272 1.41051099\n", - " 1.53873926 1.66696753 1.7951958 1.92342407 2.05165235 2.17988062\n", - " 2.30810889 2.43633716 2.56456543 2.6927937 2.82102197 2.94925025\n", - " 3.07747852 3.20570679 3.33393506 3.46216333 3.5903916 3.71861988\n", - " 3.84684815 3.97507642 4.10330469 4.23153296 4.35976123 4.48798951\n", - " 4.61621778 4.74444605 4.87267432 5.00090259 5.12913086 5.25735913\n", - " 5.38558741 5.51381568 5.64204395 5.77027222 5.89850049 6.02672876\n", - " 6.15495704 6.28318531]\n", - "\n", - "\n", - "y = [ 1. 0.99179001 0.96729486 0.92691676 0.8713187 0.80141362\n", - " 0.71834935 0.6234898 0.51839257 0.40478334 0.28452759 0.1595999\n", - " 0.03205158 -0.09602303 -0.22252093 -0.34536505 -0.46253829 -0.57211666\n", - " -0.67230089 -0.76144596 -0.8380881 -0.90096887 -0.94905575 -0.98155916\n", - " -0.99794539 -0.99794539 -0.98155916 -0.94905575 -0.90096887 -0.8380881\n", - " -0.76144596 -0.67230089 -0.57211666 -0.46253829 -0.34536505 -0.22252093\n", - " -0.09602303 0.03205158 0.1595999 0.28452759 0.40478334 0.51839257\n", - " 0.6234898 0.71834935 0.80141362 0.8713187 0.92691676 0.96729486\n", - " 0.99179001 1. ]\n" - ] - } - ], - "source": [ - "import numpy as np\n", - "print(np)\n", - "x = np.linspace(0, 2 * np.pi, 50)\n", - "y = np.cos(x)\n", - "print('\\n\\nx =', x)\n", - "print('\\n\\ny =', y)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`````{admonition} Let's break it down\n", - "The code uses the ``numpy`` library in Python to perform the following tasks:\n", - "1. It imports the ``numpy`` library.\n", - "2. It prints information about the ``numpy`` package.\n", - "3. It creates an array ``x`` with 50 equally spaced values between $0$ and $2\\pi$.\n", - "4. It calculates the cosine of each element in the array ``x`` and stores the results in the array ``y``.\n", - "5. It prints the arrays ``x`` and ``y``.\n", - "\n", - "In summary, the code imports the ``numpy`` library, creates an array ``x`` with $50$ evenly spaced elements between $0$ and $2\\pi$, calculates the cosine of each element in ``x``, and finally prints the arrays ``x`` and ``y``.\n", - "````` " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "You will learn more about this and other packages in separate Notebooks since these packages are frequently used by the scientific programming community." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "bl_ufrrc2PGB", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### ``matplotlib``\n", - "\n", - "The matplotlib module is used to plot data. It contains a lot of visualization techniques and, for simplicity, it has many submodules within the main module. Thus, in order to access functions, you have to specify the whole path that you want to import.

For example, if the function you need is located within the matplotlib module and pyplot submodule, you need to import matplotlib.pyplot; then, the access command to that function is simply pyplot.your_function().

Below we use the data generated in the previous cell to create a simple plot using the pyplot.plot() function:\n", - "\n", - "In order to import a submodule the parent module must also be specified. It is common to import ``matplotlib.pyplot`` as ``plt``.\n", - "\n", - "The ``plt.plot()`` function takes x-axis values as the first argument and y-axis, or $f(x)$, values as the second argument\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 282 - }, - "collapsed": true, - "id": "COq85MFE06s1", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "67086bf1-4b12-4929-a420-ae9322bbbcce" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "plt.plot(x, y)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "``plt.scatter()`` works in a similar way, but it does not connect the dots." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 282 - }, - "collapsed": true, - "id": "bd01J-Dc8iDJ", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "792ba793-3ff8-4f5a-bcdd-8271082d6c83" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.scatter(x, y)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "qdHLw0oC84pg", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Loading Python files as modules\n", - "\n", - "Finally, you can also load your own (or somebody else's) Python files as modules. This is quite helpful, as it allows you to keep your code projects well-structured without the need to copy and paste everything.

In order to import another *.py file as a module, you only need to have that file and your Notebook file in the same directory and use the import keyword. More info on this here." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "fHmKWsUSKuj4", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 2.2 Conditions and if statements\n", - "\n", - "In previous Sections you have learned how to create variables, alter them with the help of operators and access the code of professional software developers/scientists. With this, you can already do plenty of stuff in Python. However, it still lacks versatility. If you want to apply other processing techniques for other data — you would need to manually rewrite your code and then change it back once the data changes again. Not that handy, right?

In this Section you will learn how to steer the flow of your code — process data differently based on some conditions. For that you will learn a construction called the if statement.\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "oyr90lgAQGtD", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### if keyword\n", - "\n", - "The if statement in Python is similar to how we use it in English. \"If I have apples, I can make an apple pie\" — clearly states that an apple pie will exist under the condition of you having apples. Otherwise, no pie.

\n", - "Well, it is the same in Python:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "QGXlz9tvM56U", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "63cc3e01-7c4c-4829-d4b2-9ae08b587791" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "End of the cell block...\n" - ] - } - ], - "source": [ - "amount_of_apples = 0\n", - "\n", - "if amount_of_apples > 0:\n", - " print(\"You have apples!\\nLet's make a pie!\")\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "qiElV_BSNYgl", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see - nothing is printed besides 'End of the cell block...'.

But we can clearly see that there is another print statement! Why it is not printed? Because we have no apples... thus no pie for you.

Let's acquire some fruit and see whether something will change...\n", - "\n", - "Adding 5 apples to our supply:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "ja5Tz_GLNoUH", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "6bd36f78-2958-4bb6-ffcc-420951b3f8ba" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "You have apples!\n", - "Let's make a pie!\n", - "End of the cell block...\n" - ] - } - ], - "source": [ - "amount_of_apples += 5\n", - "\n", - "if amount_of_apples > 0:\n", - " print(\"You have apples!\\nLet's make a pie!\") \n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "UYZHMFlmNyyA", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now you can see that the same if statement prints text. It happened because our statement amount_of_apples > 0 is now True.

That's how an if statement works — you type the if keyword, a statement and a colon. Beneath it, with an indentation of 4 spaces (1 tab), you place any code you want to run in case that if statement is True. This indentation is the same as described in Notebook 1 when defining a function.

If the result of the conditional expression is False, then the code inside of the if statement block will not run. Here's another example:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "b1eW-x-3QMbZ", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "5d7df045-b19f-432d-e620-30d7cb34f605" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I'm an adult, I have to work right now :(\n", - "End of the cell block...\n" - ] - } - ], - "source": [ - "my_age = 25\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "7dhdkRKERIz_", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Slightly different setting but still the same construction. As you can see in this case, the condition of the if statement is more complicated than the previous one. It combines two smaller conditions by using the keyword and. Only if both conditions are True the final result is True (otherwise it would be False).Thus, the condition can be as long and as complicated as you want it to be, just make sure that it is readable." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "h3uicp2sTA5x", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "

elif keyword


Now, let's add a bit more logic to our last example:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "cZQHBzWcSdn8", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "0fdc9367-527d-4c1c-d4a2-b15d230a0f79" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I'm an adult, I have to work right now :(\n", - "End of the cell block...\n" - ] - } - ], - "source": [ - "my_age = 25\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "_6NOt61ZSufk", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Still the same output, but what if we change our age..." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "QZ-AGXaJSy7j", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "9208a2bb-328b-4fe0-d1fd-65c443c8902f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I can finally retire!\n", - "End of the cell block...\n" - ] - } - ], - "source": [ - "my_age = 66\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\") # msg #1\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\") # msg #2\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "u8RcnX-sTm4G", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "See.. we have a different output. Changing the value of our variable my_age changed the output of the if statement. Furthermore, the elif keyword helped us to add more logic to our code. Now, we have three different output scenarios:
\n", - "- print message #$1$ if my_age is within the $[18, 65]$ range;
\n", - "- print message #$2$ if my_age is bigger than $65$; and,
\n", - "- print none of them if my_age doesn't comply with none of the conditions (as shown below)." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "9r9Mx2gkVyS7", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "4a513321-cca9-4c5e-ee7d-da2157e039d5" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "End of the cell block...\n" - ] - } - ], - "source": [ - "my_age = 15\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\") # msg #1\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\") # msg #2\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "1lfzBWNfVwN0", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "One can also substitute an elif block by a different if block, however it is preferred to use elif instead to \"keep the condition together\" and to reduce code size.
\n", - "\n", - ":::{warning}\n", - "It is important to know that there should be only one if block and any number of elif blocks within it.\n", - ":::\n", - "\n", - "A last example below setting ``my_age = 88`` to run the first ``elif`` block and setting ``my_age = 7 `` to run the second ``elif`` block.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "0krMMx5DYpeO", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "19ac187f-b814-4aa5-ef91-9db6691ded6c" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I can finally retire!\n", - "I'm really really young\n", - "End of the cell block...\n" - ] - } - ], - "source": [ - "my_age = 88\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10:\n", - " print(\"I'm really, really young\")\n", - "\n", - "\n", - "my_age = 7\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10:\n", - " print(\"I'm really really young\")\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "WGUFngFNV6ys", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### else keyword\n", - "\n", - "We can go even further and add an additional scenario to our if statement with the else keyword. It runs the code inside of it only when none of the if and elif conditions are True:" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "ieXD271nW903", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "ff7edbd8-33b5-4b6e-c7e7-657ec1d4e8a0" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I'm just young\n", - "End of the cell block...\n" - ] - } - ], - "source": [ - "my_age = 13\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10:\n", - " print(\"I'm really really young\")\n", - "else:\n", - " print(\"I'm just young\")\n", - "\n", - "print('End of the cell block...')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "5_e10m98XJIn", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "\n", - "On the previous example, since my_age is not between $[18,65]$, nor bigger than $65$, nor smaller than $10$, the else block is run.\n", - "\n", - "Below, a final example setting ``my_age = 27`` to run the ``if`` block, then setting ``my_age = 71 `` to run the first ``elif`` block. To run the second ``elif`` block we set ``my_age = 9 ``. Finally, setting ``my_age = 13 `` to run the ``else`` block." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "Qc9WVQTxX76r", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "e4a5e6aa-6ebc-43c0-f7f2-eab350c66a8f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I'm an adult, I have to work right now :(\n", - "End of the cell block...\n", - "------------------------\n", - "I can finally retire!\n", - "End of the cell block...\n", - "------------------------\n", - "I'm really really young\n", - "End of the cell block...\n", - "------------------------\n", - "I'm just young\n", - "End of the cell block...\n", - "------------------------\n" - ] - } - ], - "source": [ - "my_age = 27\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10:\n", - " print(\"I'm really really young\")\n", - "else:\n", - " print(\"I'm just young\")\n", - "\n", - "print('End of the cell block...')\n", - "print('------------------------')\n", - "\n", - "my_age = 71\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65: # first elif block\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10:\n", - " print(\"I'm really really young\")\n", - "else:\n", - " print(\"I'm just young\")\n", - "\n", - "print('End of the cell block...')\n", - "print('------------------------')\n", - "\n", - "\n", - "my_age = 9\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10: # second elif block\n", - " print(\"I'm really really young\")\n", - "else:\n", - " print(\"I'm just young\")\n", - "\n", - "print('End of the cell block...')\n", - "print('------------------------')\n", - "\n", - "\n", - "my_age = 13\n", - "\n", - "if my_age >= 18 and my_age <= 65:\n", - " print(\"I'm an adult, I have to work right now :(\")\n", - "elif my_age > 65:\n", - " print(\"I can finally retire!\")\n", - "elif my_age < 10:\n", - " print(\"I'm really really young\")\n", - "else: # else block\n", - " print(\"I'm just young\")\n", - "\n", - "print('End of the cell block...')\n", - "print('------------------------')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "xAytN9YkYOtw", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "That's almost everything you have to know about if statements! The last two things are:\n", - "\n", - "1. It goes from top to bottom. When the first condition to be True runs, it skips all conditions after it — as shown below:" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "clMld7oKa0n7", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "5cfedbfb-f653-4d90-abd0-658353746aea" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Condition #3\n" - ] - } - ], - "source": [ - "random_number = 17\n", - "\n", - "if random_number > 35:\n", - " print('Condition #1')\n", - "elif random_number > 25:\n", - " print('Condition #2')\n", - "elif random_number > 15:\n", - " print('Condition #3')\n", - "elif random_number > 5:\n", - " print('Condition #4')\n", - "else:\n", - " print('Condition #5')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "rfwRtedNbVs8", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "2. You can put almost everything inside each condition block and you can define variables within each block:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 242 - }, - "collapsed": true, - "id": "5II4-Zcvbf3j", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "cb2f7c29-2970-48a2-eacc-56d6e3f1a829" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "I am a poor BSc student\n", - "x = 5\n" - ] - }, - { - "ename": "NameError", - "evalue": "name 'b' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[22], line 20\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mI am a poor MSc student\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 19\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mx =\u001b[39m\u001b[39m'\u001b[39m, x)\n\u001b[1;32m---> 20\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mb =\u001b[39m\u001b[39m'\u001b[39m, b)\n", - "\u001b[1;31mNameError\u001b[0m: name 'b' is not defined" - ] - } - ], - "source": [ - "my_income = 150\n", - "my_degree = 'BSc'\n", - "\n", - "if my_degree == 'BSc':\n", - " x = 5\n", - " if my_income > 300:\n", - " b = 2\n", - " print('I am a rich BSc student')\n", - " else:\n", - " print('I am a poor BSc student')\n", - "\n", - "elif my_degree == 'MSc':\n", - "\n", - " if my_income > 300:\n", - " print('I am a rich MSc student')\n", - " else:\n", - " print('I am a poor MSc student')\n", - "\n", - "print('x =', x)\n", - "print('b =', b)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "9nDrNWr2cjMd", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, we can make it as complicated as we want in terms of conditional branching.

Additionally, you can see that only variables within the blocks which run were created, while other variables were not. Thus, we have a NameError that we tried to access a variable (b) that was not defined." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "fHmKWsUSKuj4", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 2.3 Data Structures\n", - "\n", - "In this Section you will tackle a data management problem! In the first module you have learned how to create variables, which is cool. But when you populate a lot of variables, or you want to store & access them within one entity, you need to have a data structure.

There are plenty of them, which differ their use cases and complexity. Today we will tackle some of the standard Python built-in data structures. The most popular of those are: list, dict and tuple." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "BcEOnv2kTT9A", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### list\n", - "\n", - "First, the easiest and the most popular data structure in Python: list (which is similar to a typical array you could have seen in a different programming language).

\n", - "You can create a list in the following ways:\n", - "\n", - "1. Creating an empty list, option 1\n", - "2. Creating an empty list, option 2 - using the class constructor\n", - "3. Creating a list from existing data - option 1\n", - "4. Creating a list from existing data - option 2" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "U8OUPaXESz44", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "ee38751f-5efe-4a85-a9a9-a34efc3bfb02" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Type of my_list1 object \n", - "Contents of my_list1 []\n", - "--------------------\n", - "Type of my_list2 object \n", - "Contents of my_list2 []\n", - "--------------------\n", - "Type of my_list3 object \n", - "Contents of my_list3 [5, 'hello', 37.5]\n", - "--------------------\n", - "Type of my_list3 object \n", - "Contents of list_with_letters ['s', 'a', 'n', 'd', 's', 't', 'o', 'n', 'e']\n", - "--------------------\n" - ] - } - ], - "source": [ - "#1\n", - "empty_list1 = []\n", - "print('Type of my_list1 object', type(empty_list1))\n", - "print('Contents of my_list1', empty_list1)\n", - "print('--------------------')\n", - "\n", - "#2\n", - "empty_list2 = list()\n", - "print('Type of my_list2 object', type(empty_list2))\n", - "print('Contents of my_list2', empty_list2)\n", - "print('--------------------')\n", - "\n", - "#3\n", - "my_var1 = 5\n", - "my_var2 = \"hello\"\n", - "my_var3 = 37.5\n", - "\n", - "my_list = [my_var1, my_var2, my_var3]\n", - "print('Type of my_list3 object', type(my_list))\n", - "print('Contents of my_list3', my_list)\n", - "print('--------------------')\n", - "\n", - "\n", - "#4\n", - "cool_rock = \"sandstone\" # remember that a string is a collection of characters\n", - "\n", - "list_with_letters = list(cool_rock)\n", - "\n", - "print('Type of my_list3 object', type(list_with_letters))\n", - "print('Contents of list_with_letters', list_with_letters)\n", - "print('--------------------')\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "I-9MNCzBUgH9", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, in all three cases we created a list, only the method how we did it was slightly different:\n", - "- the first method uses the bracket notation.\n", - "- the second method uses class constructor approach. \n", - "\n", - "Both methods also apply to the other data structures.\n", - "\n", - "Now, we have a list — what can we do with it?\n", - "\n", - "Well... we can access and modify any element of an existing list. In order to access a list element, square brackets [] are used with the index of the element we want to access inside. Sounds easy, but keep in mind that Python has a zero-based indexing (as mentioned in Section 1.4 in Notebook 1).\n", - "\n", - ":::{note}\n", - "A zero-based indexing means that the first element has index 0 (not 1), the second element has index 1 (not 2) and the n-th element has index n - 1 (not n)!\n", - ":::" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The ``len()` function returns the lengths of an iterable (string, list, array, etc). Since we have 3 elements, thus we can access 0th, 1st, and 2nd elements. \n", - "\n", - "After the element is accessed, it can be used as any variable, the list only provides a convenient storage. Since it is a storage - we can easily alter and swap list elements" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 295 - }, - "collapsed": true, - "id": "CksNFv0AVmLw", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "bbddff89-959c-4065-89a5-04500ceedf91" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n", - "First element of my list: 5\n", - "Last element of my list: 37.5\n", - "Sum of 5 and 37.5 is 42.5\n", - "[12, 'My new element', 37.5]\n" - ] - } - ], - "source": [ - "print(len(my_list))\n", - "print('First element of my list:', my_list[0])\n", - "print('Last element of my list:', my_list[2])\n", - "\n", - "summation = my_list[0] + my_list[2]\n", - "print(f'Sum of {my_list[0]} and {my_list[2]} is {summation}')\n", - "\n", - "\n", - "my_list[0] += 7\n", - "my_list[1] = \"My new element\"\n", - "\n", - "print(my_list)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "we can only access data we have - Python will give us an error for the following" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "ename": "IndexError", - "evalue": "list assignment index out of range", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[4], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m my_list[\u001b[39m10\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m199\u001b[39m\n", - "\u001b[1;31mIndexError\u001b[0m: list assignment index out of range" - ] - } - ], - "source": [ - "my_list[10] = 199" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "zxkLDWef7IM-", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "We can also add new elements to a list, or remove them! Adding is realized with the append method and removal of an element uses the del keyword. We can also store a list inside a list - list inception! Useful for matrices, images etc. " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "Yos0Cl9C7W1H", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "ba48887c-c2ff-4fc6-a231-68543e8bf97a" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[12, 'My new element', 37.5, 'new addition to my variable collection!']\n", - "[12, 'My new element', 37.5, 'new addition to my variable collection!', ['another list', False, (1+2j)]]\n", - "[12, 'My new element', 'new addition to my variable collection!', ['another list', False, (1+2j)]]\n" - ] - } - ], - "source": [ - "my_list.append(\"new addition to my variable collection!\")\n", - "print(my_list)\n", - "\n", - "my_list.append(['another list', False, 1 + 2j])\n", - "print(my_list)\n", - "\n", - "del my_list[2]\n", - "print(my_list)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "WZgLxAbJ8icK", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Lists also have other useful functionalities, as you can see from the official documentation. Since lists are still objects you can try and apply some operations to them as well." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "UEBv_4u09K9T", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "96987502-088b-48d8-d114-2b9967f2de78" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[2, 4, False, 'second list', 0, 222]\n", - "['second list', 0, 222, 'second list', 0, 222, 'second list', 0, 222, 'second list', 0, 222]\n", - "['second list', 0, 222, 5050, 0, 222, 'second list', 0, 222, 'second list', 0, 222]\n" - ] - } - ], - "source": [ - "lst1 = [2, 4, False]\n", - "lst2 = ['second list', 0, 222]\n", - "\n", - "lst1 = lst1 + lst2\n", - "print(lst1)\n", - "\n", - "lst2 = lst2 * 4\n", - "print(lst2)\n", - "\n", - "lst2[3] = 5050\n", - "print(lst2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "SVvYBl6H96du", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, adding lists together concatenates them and multiplying them basically does the same thing (it performs addition several times, just like in real math...).

Additionally, you can also use the in keyword to check the presence of a value inside a list." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "15hwh0COFf-p", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "2b3d16c6-9487-49ea-a6f6-8ffb989ac95c" - }, - "outputs": [], - "source": [ - "print(lst1)\n", - "\n", - "if 222 in lst1:\n", - " print('We found 222 inside lst1')\n", - "else:\n", - " print('Nope, nothing there....')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "NAJZYyQd-fG2", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### tuple\n", - "\n", - "If you understood how list works, then you already understand 95% of tuple. Tuples are just like lists, with some small differences.

1. In order to create a tuple you need to use () brackets, comma or a tuple class constructor.
2. You can change the content of your list, however tuples are immutable (just like strings).\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 313 - }, - "collapsed": true, - "id": "QnEd7YSsE2Ih", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "1a2e1b57-dbff-4c7d-d7c4-8968fecf67a1" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Type of tupl1 \n", - "Content of tupl1 ()\n", - " ()\n" - ] - } - ], - "source": [ - "#1\n", - "tupl1 = tuple() \n", - "print('Type of tupl1', type(tupl1))\n", - "print('Content of tupl1', tupl1)\n", - "#2\n", - "tupl2 = () # option 2 with ()\n", - "print(type(tupl2), tupl2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Creating a non-empty tuple using brackets or # Creating a non-empty tuple using comma. Can we change an element of a tuple?" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "my tuple (26.5, 'Oil', False, 'some additional stuff', 777)\n", - "A comma made tuple (2, 'hi!', 228)\n", - "4th element of my_tuple: some additional stuff\n" - ] - }, - { - "ename": "TypeError", - "evalue": "'tuple' object does not support item assignment", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[8], line 13\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mA comma made tuple\u001b[39m\u001b[39m'\u001b[39m, comma_tuple)\n\u001b[0;32m 12\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m4th element of my_tuple:\u001b[39m\u001b[39m'\u001b[39m, my_tuple[\u001b[39m3\u001b[39m])\n\u001b[1;32m---> 13\u001b[0m my_tuple[\u001b[39m3\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m'\u001b[39m\u001b[39mwill I change?\u001b[39m\u001b[39m'\u001b[39m\n", - "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" - ] - } - ], - "source": [ - "my_var1 = 26.5\n", - "my_var2 = 'Oil'\n", - "my_var3 = False\n", - "\n", - "my_tuple = (my_var1, my_var2, my_var3, 'some additional stuff', 777)\n", - "print('my tuple', my_tuple)\n", - "\n", - "\n", - "comma_tuple = 2, 'hi!', 228\n", - "print('A comma made tuple', comma_tuple)\n", - "\n", - "print('4th element of my_tuple:', my_tuple[3])\n", - "my_tuple[3] = 'will I change?'" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "1RxahCCiHJRl", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Since tuples are immutable, it has no append() method nor any other methods that alter the object they target.\n", - "\n", - "You might think that tuple is a useless class. However, there are some reasons for it to exist:\n", - "\n", - "1.Storing constants & objects which shouldn't be changed.\n", - "2.Saving memory (tuple uses less memory to store the same data than a list). ``.__sizeof__()`` determines the size of a variable in bytes.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "A9cA-BpNIMzd", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "d7100baa-0a2c-4498-b8c0-01d1733e732f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "size of a = 48 bytes\n", - "size of b = 64 bytes\n" - ] - } - ], - "source": [ - "my_name = 'Vasyan'\n", - "my_age = 27\n", - "is_student = True\n", - "\n", - "a = (my_name, my_age, is_student)\n", - "b = [my_name, my_age, is_student]\n", - "\n", - "print('size of a =', a.__sizeof__(), 'bytes') \n", - "print('size of b =', b.__sizeof__(), 'bytes')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "IYyveiZJJOTZ", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### dict\n", - "\n", - "After seeing lists and tuples, you may think:

\"Wow, storing all my variables within another variable is cool and gnarly! But... sometimes it's boring & inconvenient to access my data by using it's position within a tuple/list. Is there a way that I can store my object within a data structure but access it via something meaningful, like a keyword...?\"

Don't worry if you had this exact same thought.. Python had it as well!

Dictionaries are suited especially for that purpose — to each element you want to store, you give it a nickname (i.e., a key) and use that key to access the value you want.\n", - "\n", - "To create an empty dictionary we used ``{}`` or class constructor ``dict()``" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "r5vjDJ8CKaT8", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "46ee6315-d5a5-40a5-8db3-175a681dbf0c" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Type of empty_dict1 \n", - "Content of it -> {}\n", - "Type of empty_dict2 \n", - "Content of it -> {}\n" - ] - } - ], - "source": [ - "empty_dict1 = {}\n", - "print('Type of empty_dict1', type(empty_dict1))\n", - "print('Content of it ->', empty_dict1)\n", - "\n", - "\n", - "empty_dict2 = dict()\n", - "print('Type of empty_dict2', type(empty_dict2))\n", - "print('Content of it ->', empty_dict2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To create a non-empty dictionary we specify pairs of **key:value** pattern" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Content of my_dict>>> {'name': 'Jarno', 'color': 'red', 'year': 2007, 'is cool': True, 6: 'it works', (2, 22): 'that is a strange key'}\n" - ] - } - ], - "source": [ - "my_dict = {\n", - " 'name': 'Jarno',\n", - " 'color': 'red',\n", - " 'year': 2007,\n", - " 'is cool': True,\n", - " 6: 'it works',\n", - " (2, 22): 'that is a strange key'\n", - "}\n", - "\n", - "print('Content of my_dict>>>', my_dict)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "2tQEahKqM9p8", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "In the last example, you can see that only strings, numbers, or tuples were used as keys. Dictionaries can only use immutable data (or numbers) as keys:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 242 - }, - "collapsed": true, - "id": "V38R-AweNbF7", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "6039cc3b-8d72-4f23-986f-e1027265aec5" - }, - "outputs": [ - { - "ename": "TypeError", - "evalue": "unhashable type: 'list'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[14], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m mutable_key_dict \u001b[39m=\u001b[39m {\n\u001b[0;32m 2\u001b[0m \u001b[39m5\u001b[39m: \u001b[39m'\u001b[39m\u001b[39mlets try\u001b[39m\u001b[39m'\u001b[39m,\n\u001b[0;32m 3\u001b[0m \u001b[39mTrue\u001b[39;00m: \u001b[39m'\u001b[39m\u001b[39mI hope it will run perfectly\u001b[39m\u001b[39m'\u001b[39m,\n\u001b[0;32m 4\u001b[0m \u001b[39m6.78\u001b[39m: \u001b[39m'\u001b[39m\u001b[39mheh\u001b[39m\u001b[39m'\u001b[39m,\n\u001b[0;32m 5\u001b[0m [\u001b[39m'\u001b[39m\u001b[39mNo problemo\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39mright?\u001b[39m\u001b[39m'\u001b[39m]: \u001b[39mFalse\u001b[39;00m \n\u001b[0;32m 6\u001b[0m }\n\u001b[0;32m 8\u001b[0m \u001b[39mprint\u001b[39m(mutable_key_dict)\n", - "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'" - ] - } - ], - "source": [ - "mutable_key_dict = {\n", - " 5: 'lets try',\n", - " True: 'I hope it will run perfectly',\n", - " 6.78: 'heh',\n", - " ['No problemo', 'right?']: False \n", - "}\n", - "\n", - "print(mutable_key_dict)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "erVQ8Yy6OFzW", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Alright, now it is time to access the data we have managed to store inside my_dict using keys!\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 313 - }, - "collapsed": true, - "id": "4_s_--xzORQx", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "d2dcabbb-057f-41e2-d54c-07d8ca3aa344" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Some random content of my_dict Jarno that is a strange key\n" - ] - } - ], - "source": [ - "print('Some random content of my_dict', my_dict['name'], my_dict[(2, 22)])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Remember the mutable key dict? Let's make it work by omitting the list item." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Accessing weird dictionary...\n", - "I hope it will run perfectly\n", - "lets try\n", - "heh\n" - ] - } - ], - "source": [ - "mutable_key_dict = {\n", - " 5: 'lets try',\n", - " True: 'I hope it will run perfectly',\n", - " 6.78: 'heh'\n", - "}\n", - "\n", - "\n", - "print('Accessing weird dictionary...')\n", - "print(mutable_key_dict[True])\n", - "print(mutable_key_dict[5])\n", - "print(mutable_key_dict[6.78])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Trying to access something we have and something we don't have" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "My favorite year is 2007\n" - ] - }, - { - "ename": "KeyError", - "evalue": "'song'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[17], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mMy favorite year is\u001b[39m\u001b[39m'\u001b[39m, my_dict[\u001b[39m'\u001b[39m\u001b[39myear\u001b[39m\u001b[39m'\u001b[39m])\n\u001b[1;32m----> 2\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mMy favorite song is\u001b[39m\u001b[39m'\u001b[39m, my_dict[\u001b[39m'\u001b[39;49m\u001b[39msong\u001b[39;49m\u001b[39m'\u001b[39;49m])\n", - "\u001b[1;31mKeyError\u001b[0m: 'song'" - ] - } - ], - "source": [ - "print('My favorite year is', my_dict['year'])\n", - "print('My favorite song is', my_dict['song'])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "mVmNASbEPw27", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - ":::{warning} \n", - "It is best practice to use mainly strings as keys — the other options are weird and are almost never used.\n", - ":::\n", - "\n", - "What's next? Dictionaries are mutable, so let's go ahead and add some additional data and delete old ones." - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "C2Tm8iaXQ4ej", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "62ea0bcc-a09b-474e-dd7b-e2688746ff31" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "my_dict right now {'name': 'Jarno', 'color': 'red', 'year': 2007, 'is cool': True, 6: 'it works', (2, 22): 'that is a strange key'}\n", - "my_dict after some operations {'name': 'Jarno', 'color': 'red', 'is cool': True, 6: 'it works', (2, 22): 'that is a strange key', 'new_element': 'magenta', 'weight': 27.8}\n" - ] - } - ], - "source": [ - "print('my_dict right now', my_dict)\n", - "\n", - "my_dict['new_element'] = 'magenta'\n", - "my_dict['weight'] = 27.8\n", - "del my_dict['year']\n", - "\n", - "print('my_dict after some operations', my_dict)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "J80LstNFSFeN", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "You can also print all keys present in the dictionary using the .keys() method, or check whether a certain key exists in a dictionary, as shown below. More operations can be found here." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "pEYa3nKRUZD1", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "2b850789-9071-414f-ce44-bb23203243a6" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dict_keys(['name', 'color', 'is cool', 6, (2, 22), 'new_element', 'weight'])\n", - "\n", - "my_dict has a ['name'] key: True\n" - ] - } - ], - "source": [ - "print(my_dict.keys())\n", - "print(\"\\nmy_dict has a ['name'] key:\", 'name' in my_dict)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Real life example: \n", - "\n", - "Analyzing satellite metadata

Metadata is a set of data that describes and gives information about other data. For Sentinel-1, the metadata of the satellite is acquired as an .xml file. It is common for Dictionaries to play an important role in classifying this metadata. One could write a function to read and obtain important information from this metadata and store them in a Dictionary. Some examples of keys for the metadata of Sentinel-1 are:\n", - " \n", - "_dict_keys(['azimuthSteeringRate', 'dataDcPolynomial', 'dcAzimuthtime', 'dcT0', 'rangePixelSpacing', 'azimuthPixelSpacing', 'azimuthFmRatePolynomial', 'azimuthFmRateTime', 'azimuthFmRateT0', 'radarFrequency', 'velocity', 'velocityTime', 'linesPerBurst', 'azimuthTimeInterval', 'rangeSamplingRate', 'slantRangeTime', 'samplesPerBurst', 'no_burst'])_\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "XvpRgp7eUsLP", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "The last important thing for this Notebook are slices. Similar to how you can slice a string (shown in Section 1.4, in Notebook 1). This technique allows you to select a subset of data from an iterable (like a list or a tuple)." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "S96Y3-HcXN3P", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "b0d9151f-f476-4ffa-de00-74f85a4b962c" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The first three elements of x: [1, 2, 3]\n", - "[1, 2, 3]\n", - "The last element is 7 or 7 or 7\n", - "[1, 2, 3]\n", - "[1, 2, 3]\n" - ] - } - ], - "source": [ - "x = [1, 2, 3, 4, 5, 6, 7]\n", - "n = len(x) \n", - "\n", - "print('The first three elements of x:', x[0:3])\n", - "print(x[:3])\n", - "print('The last element is', x[6], 'or', x[n - 1], 'or', x[-1])\n", - "print(x[0:-4])\n", - "print(x[0:3:1])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`````{admonition} Let's break it down\n", - "This code demonstrates how to select specific elements from a list in Python using slicing:\n", - "\n", - "1. The list `x` contains numbers from 1 to 7.\n", - "2. `x[0:3]` selects the first three elements of `x`.\n", - "3. `x[:3]` achieves the same result by omitting the starting index.\n", - "4. `x[6]`, `x[n - 1]`, and `x[-1]` all access the last element of `x`.\n", - "5. `x[0:-4]` selects elements from the beginning to the fourth-to-last element.\n", - "6. `x[0:3:1]` selects elements with a step size of 1.\n", - "\n", - "`````" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "d4v9TBKyZJEh", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Thus, the general slicing call is given by iterable[start:end:step]. \n", - "\n", - "Here's another example:\n", - "\n", - "You can select all even numbers using `[::2]` or reverse the list using `[::-1]` or select a middle subset for example `[5:9]`." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "GO8qP2d1ZXkq", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "832458e8-6202-4fa8-8898-6d2a2a1ad423" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Selecting all even numbers [0, 2, 4, 6, 8, 10]\n", - "All odd numbers [1, 3, 5, 7, 9]\n", - "Normal order [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", - "Reversed order [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\n", - "Numbers from 5 to 8: [5, 6, 7, 8]\n" - ] - } - ], - "source": [ - "numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", - "\n", - "print('Selecting all even numbers', numbers[::2])\n", - "print('All odd numbers', numbers[1::2])\n", - "print('Normal order', numbers)\n", - "print('Reversed order', numbers[::-1])\n", - "print('Numbers from 5 to 8:', numbers[5:9])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "fHmKWsUSKuj4", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 2.4 Loops\n", - "\n", - "Let's do another step to automatize things even more! Previous Sections introduced a lot of fundamental concepts, but they still don't unveil the true power of any programming language — loops!

If we want to perform the same procedure multiple times, then we would have to take the same code and copy-paste it. This approach would work, however it would require a lot of manual work and it does not look cool.

This problem is resolved with a loop construction. As the name suggest, this construction allows you to loop (or run) certain piece of code several times at one execution." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "BcEOnv2kTT9A", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### for loop\n", - "\n", - "The first and the most popular looping technique is a for loop. Let's see some examples:\n", - "\n", - "Let's create a list with some stuff in it. In order to iterate (or go through each element of a list) we use a `for` loop.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "fNaiOimubLMF", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "77085dd8-83cc-41d8-b7c1-17fc55dc38eb" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Start of the loop\n", - "In my list I can find: 100\n", - "In my list I can find: marble\n", - "In my list I can find: False\n", - "In my list I can find: 2\n", - "In my list I can find: 2\n", - "In my list I can find: [7, 7, 7]\n", - "In my list I can find: end\n", - "End of the loop\n" - ] - } - ], - "source": [ - "my_list = [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n", - "\n", - "print('Start of the loop')\n", - "for list_item in my_list:\n", - " print('In my list I can find:', list_item)\n", - "print('End of the loop')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "NkKA4qLDb9IM", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "General for loop construction looks like this:

\n", - "for iterator_variable in iterable:\n", - " do something with iterator_variable

\n", - "\n", - "During each iteration the following steps are happening under the hood (or above it):\n", - "1. iterator_variable = iterable[0]iterator_variable is assigned the first value from the iterable.\n", - "2. Then, you use iterator_variable as you wish.\n", - "3. By the end of the 'cycle', the next element from the iterable is selected (iterable[1]), i.e., we return to step 1, but now assigning the second element... and so on.\n", - "4. When there is not a next element (in other words, we have reached the end of the iterable) — it exits and the code under the loop is now executed.\n", - "\n", - "Looks cool, but what if we want to alter the original iterable (not the iterator_variable) within the loop?\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "1hZm9bOuhOiE", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "0b50490d-1d74-41cb-ba84-d4a595a7eede" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Try #1, before: [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n", - "Try #1, after [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n" - ] - } - ], - "source": [ - "x = my_list\n", - "print('Try #1, before:', x)\n", - "\n", - "for item in x:\n", - " item = [5,6,7]\n", - "\n", - "print('Try #1, after', x)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Nothing has changed.... let's try another method. `range()` is used to generate a sequence of numbers more info [here](https://www.w3schools.com/python/ref_func_range.asp).\n", - "\n", - "`range(length_of_x)` will generate numbers from 0 till `length_of_x`, excluding the last one.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "range(0, 7)\n", - "Try #2, before [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n", - "Try #2, after [-1, -1, -1, -1, -1, -1, -1]\n" - ] - } - ], - "source": [ - "length_of_x = len(x)\n", - "\n", - "indices = range(length_of_x)\n", - "\n", - "print(indices)\n", - "print('Try #2, before', my_list)\n", - "\n", - "for id in indices:\n", - " my_list[id] = -1\n", - "\n", - "print('Try #2, after', my_list)\n", - " \n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now we have a method in our arsenal which can not only loop through a list but also access and alter its contents. Also, you can generate new data by using a for loop and by applying some processing to it. Here's an example on how you can automatize your greetings routine!\n", - "\n", - "We create a variable `message` with a general greeting and a list with your friends names. Then an empty list where all greetings will be stored (otherwise you cannot use the `.append` in the for loop below!). \n" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['Ohayo, Mike-kun!', 'Ohayo, Alex-kun!', 'Ohayo, Maria-kun!']\n" - ] - } - ], - "source": [ - "\n", - "message = \"Ohayo\"\n", - "names = [\"Mike\", \"Alex\", \"Maria\"]\n", - "greetings = []\n", - "\n", - "for name in names:\n", - " personalized_greeting = f'{message}, {name}-kun!' \n", - " greetings.append(personalized_greeting) \n", - "\n", - "print(greetings)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "And you can also have loops inside loops!. Let's say that you put down all your expenses per day separately in euros. You can also keep them within one list together.Additionally, you can access also each expense separately! day3 is third array and 2nd expense is second element within that array." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "All my expenses [[15, 100, 9], [200], [10, 12, 15, 5, 1]]\n", - "My second expense on day 3 is 12\n" - ] - } - ], - "source": [ - "day1_expenses = [15, 100, 9]\n", - "day2_expenses = [200]\n", - "day3_expenses = [10, 12, 15, 5, 1]\n", - "\n", - "expenses = [day1_expenses, day2_expenses, day3_expenses]\n", - "print('All my expenses', expenses)\n", - "\n", - "print(f'My second expense on day 3 is {expenses[2][1]}')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's use it in some calculations. The code bellow iterates over the expenses for each day, calculates the total expenses for each day, and then adds them together to obtain the overall total expenses. " - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Option #1: In total I have spent 367 euro!\n" - ] - } - ], - "source": [ - "total_expenses = 0\n", - "\n", - "for i in range(len(expenses)): \n", - " daily_expenses_list = expenses[i]\n", - " daily_expenses = 0\n", - " for j in range(len(daily_expenses_list)): \n", - " daily_expenses += daily_expenses_list[j]\n", - " total_expenses += daily_expenses\n", - " \n", - "print(f'Option #1: In total I have spent {total_expenses} euro!')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`````{admonition} Let's break it down\n", - "This code calculates the total expenses over multiple days using nested loops. Here's an explanation in simpler terms:\n", - "\n", - "1. We start with the variable `total_expenses` set to 0 to keep track of the total expenses.\n", - "2. The code loops over each day's expenses using the outer loop, which runs from 0 to the length of the `expenses` list.\n", - "3. Inside the loop, it accesses the expenses made on the current day by assigning `daily_expenses_list` to the expenses at index `i`.\n", - "4. It initializes `daily_expenses` as 0 to temporarily store the sum of expenses for the current day.\n", - "5. The code enters the inner loop, which iterates over the expenses for the current day using the range of the length of `daily_expenses_list`.\n", - "6. Inside the inner loop, it adds each expense to `daily_expenses` to calculate the total expenses for the current day.\n", - "7. After the inner loop completes, it adds `daily_expenses` to the `total_expenses` variable to accumulate the expenses across all days.\n", - "8. Once the outer loop finishes, it prints the total expenses using an f-string format to display the result.\n", - "`````\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Option #2" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Option #2: In total I have spent 367 euro!\n" - ] - } - ], - "source": [ - "total_expenses = 0\n", - "\n", - "for i in range(len(expenses)):\n", - " for j in range(len(expenses[i])):\n", - " total_expenses += expenses[i][j]\n", - " \n", - "print(f'Option #2: In total I have spent {total_expenses} euro!')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Option #3 - advanced techniques gathered after eternal suffering." - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Option #3: In total I have spent 367 euro!\n" - ] - } - ], - "source": [ - "total_expenses = 0\n", - "total_expenses = sum(map(sum, expenses))\n", - "print(f'Option #3: In total I have spent {total_expenses} euro!')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "TNGZ78d8LOYC", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### while loop\n", - "\n", - "The second popular loop construction is a while loop. The main difference is that it is suited for code structures that must repeat unless a certain logical condition is satisfied. It looks like this:

while logical_condition == True:
do something

And here is a working code example:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "rqsX011pL6p6", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "39bce5bb-bf01-469c-8758-6127efc4e943" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "sum in the beginning of the cycle: 0\n", - "sum in the end of the cycle: 1\n", - "sum in the beginning of the cycle: 1\n", - "sum in the end of the cycle: 2\n", - "sum in the beginning of the cycle: 2\n", - "sum in the end of the cycle: 3\n", - "sum in the beginning of the cycle: 3\n", - "sum in the end of the cycle: 4\n", - "sum in the beginning of the cycle: 4\n", - "sum in the end of the cycle: 5\n" - ] - } - ], - "source": [ - "sum = 0\n", - "\n", - "while sum < 5:\n", - " print('sum in the beginning of the cycle:', sum)\n", - " sum += 1\n", - " print('sum in the end of the cycle:', sum)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "mW02NDD4MJWn", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, this loop was used to increase the value of the sum variable until it reached $5$. The moment it reached $5$ and the loop condition was checked — it returned False and, therefore, the loop stopped.

Additionally, it is worth to mention that the code inside the loop was altering the variable used in the loop condition statement, which allowed it to first run, and then stop. In the case where the code doesn't alter the loop condition, it won't stop (infinite loop), unless another special word is used.

Here's a simple example of an infinite loop, which you may run (by removing the #'s) but in order to stop it — you have to interrupt the Notebook's kernel or restart it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "collapsed": true, - "id": "AmIcH59oNaxU", - "outputId": "e944bfe2-f906-45c9-ef2a-03280956679a" - }, - "outputs": [], - "source": [ - "# a, b = 0, 7\n", - "\n", - "# while a + b < 10:\n", - "# a += 1\n", - "# b -= 1\n", - "# print(f'a:{a};b:{b}')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "ryvB-qKfNxPh", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### break keyword\n", - "\n", - "After meeting and understanding the loop constructions, we can add a bit more control to it. For example, it would be nice to exit a loop earlier than it ends — in order to avoid infinite loops or just in case there is no need to run the loop further. This can be achieved by using the break keyword. The moment this keyword is executed, the code exits from the current loop." - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "hvib4ruNTN6_", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "b0f08946-864e-430a-a8cc-765303a9ac6e" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Before normal loop\n", - "0 iteration and still running...\n", - "1 iteration and still running...\n", - "2 iteration and still running...\n", - "3 iteration and still running...\n", - "4 iteration and still running...\n", - "5 iteration and still running...\n", - "6 iteration and still running...\n", - "After normal loop\n", - "Before interrupted loop\n", - "0 iteration and still running...\n", - "1 iteration and still running...\n", - "2 iteration and still running...\n", - "3 iteration and still running...\n", - "4 iteration and still running...\n", - "Leaving the loop\n", - "After interupted loop\n" - ] - } - ], - "source": [ - "stop_iteration = 4\n", - "\n", - "print('Before normal loop')\n", - "for i in range(7):\n", - " print(f'{i} iteration and still running...')\n", - "print('After normal loop')\n", - "\n", - "print('Before interrupted loop')\n", - "for i in range(7):\n", - " print(f'{i} iteration and still running...')\n", - "\n", - " if i == stop_iteration:\n", - " print('Leaving the loop')\n", - " break\n", - "print('After interupted loop')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "guxGK4uGUXBA", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "The second loop shows how a small intrusion of an if statement and the break keyword can help us with stopping the loop earlier. The same word can be also used in a while loop:" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "tVkdaOP8Ul-W", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "5f391d65-82a2-4408-d74d-af89b84a040b" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Before the loop\n", - "Inside the loop #1\n", - "Inside the loop #2\n", - "Inside the loop #3\n", - "Inside the loop #4\n", - "Inside the loop #5\n", - "Inside the loop #6\n", - "Too many iterations is bad for your health\n", - "After the loop\n" - ] - } - ], - "source": [ - "iteration_number = 0\n", - "\n", - "print('Before the loop')\n", - "while True:\n", - " iteration_number += 1\n", - "\n", - " print(f'Inside the loop #{iteration_number}')\n", - " if iteration_number > 5:\n", - " print('Too many iterations is bad for your health')\n", - " break\n", - "print('After the loop')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "AtRCfdMlWzhn", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### continue keyword\n", - "\n", - "Another possibility to be more flexible when using loops is to use the continue keyword.

This will allow you to skip some iterations (more precisely — the moment the keyword is used it will skip the code underneath it and will start the next iteration from the beginning)." - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "_1q4EB0bXMyk", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "57b11d07-251a-4319-d0ba-1d3ee1685b61" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Begin normal loop\n", - "\n", - "0 iteration and still running...\n", - "Calculating cool function for 0 -> f(0) = 3\n", - "1 iteration and still running...\n", - "Calculating cool function for 1 -> f(1) = 15\n", - "2 iteration and still running...\n", - "Calculating cool function for 2 -> f(2) = 41\n", - "3 iteration and still running...\n", - "Calculating cool function for 3 -> f(3) = 81\n", - "4 iteration and still running...\n", - "Calculating cool function for 4 -> f(4) = 135\n", - "5 iteration and still running...\n", - "Calculating cool function for 5 -> f(5) = 203\n", - "6 iteration and still running...\n", - "Calculating cool function for 6 -> f(6) = 285\n", - "\n", - "End normal loop\n", - "\n", - "-------------------\n", - "Begin altered loop\n", - "\n", - "0 iteration and still running...\n", - "1 iteration and still running...\n", - "Calculating cool function for 1 -> f(1) = 15\n", - "2 iteration and still running...\n", - "3 iteration and still running...\n", - "Calculating cool function for 3 -> f(3) = 81\n", - "4 iteration and still running...\n", - "5 iteration and still running...\n", - "Calculating cool function for 5 -> f(5) = 203\n", - "6 iteration and still running...\n", - "\n", - "End altered loop\n" - ] - } - ], - "source": [ - "def calculate_cool_function(arg):\n", - " res = 7 * arg ** 2 + 5 * arg + 3\n", - " print(f'Calculating cool function for {arg} -> f({arg}) = {res}')\n", - "\n", - "print('Begin normal loop\\n')\n", - "for i in range(7):\n", - " print(f'{i} iteration and still running...')\n", - " calculate_cool_function(i)\n", - "print('\\nEnd normal loop\\n')\n", - "\n", - "print('-------------------')\n", - "\n", - "print('Begin altered loop\\n')\n", - "for i in range(7):\n", - " print(f'{i} iteration and still running...')\n", - "\n", - " # skipping every even iteration\n", - " if i % 2 == 0:\n", - " continue\n", - " \n", - " calculate_cool_function(i)\n", - " \n", - "print('\\nEnd altered loop')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "_30hKsC4a1vy", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, with the help of the continue keyword we managed to skip some of the iterations. Also worth noting that $0$ is divisible by any number, for that reason the calculate_cool_function(i) at i = 0 didn't run." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "lDKimbtECAAz", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## Additional study material\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/modules.html\n", - "* https://realpython.com/python-modules-packages/\n", - "* Think Python (2nd ed.) - Sections 3 and 14 \n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/controlflow.html\n", - "* https://realpython.com/python-conditional-statements/\n", - "* Think Python (2nd ed.) - Section 5\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/datastructures.html\n", - "* https://realpython.com/python-data-structures/\n", - "* Think Python (2nd ed.) - Sections 8, 10, 11, 12\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/controlflow.html\n", - "* https://realpython.com/python-for-loop/\n", - "* Think Python (2nd ed.) - Section 7" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### After this Notebook you should be able to:\n", - "\n", - "- understand the difference between built-in and third-party modules\n", - "- use functions from the **`math`** module\n", - "- find available functions from any module\n", - "- generate an array for the x-axis\n", - "- calculate the **`cos`** or **`sin`** of the x-axis\n", - "- plot such functions\n", - "- understand how to load Python files as modules\n", - "- understand conditions with **`if`**, **`elif`** and, **`else`**\n", - "- understand the differences between **`list`**, **`tuple`**, and **`dict`**\n", - "- slice lists and tuples\n", - "- use **`for`** and **`while`** loops\n", - "- use the **`break`** and **`continue`** keywords inside of loops\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "Python_2_1.ipynb", - "provenance": [] - }, - "kernelspec": { - "display_name": "base", - "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.13" - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} diff --git a/book/03/In_a_Nutshell/01.ipynb b/book/03/In_a_Nutshell/01.ipynb deleted file mode 100644 index 8d5e63c..0000000 --- a/book/03/In_a_Nutshell/01.ipynb +++ /dev/null @@ -1,534 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# 3. Advanced strings and functions, files and debugging." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from math import pi \n", - "import os " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.1 Advanced Strings\n", - "In Python, strings are created using quotes ('' or \"\") and are immutable, while f-strings are formatted strings that allow embedding expressions inside curly braces { } for dynamic value substitution during runtime. Here is a couple of examples for strings:" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Alice 25 engineer\n" - ] - } - ], - "source": [ - "name = \"Alice\"\n", - "age = 25\n", - "profession = \"engineer\"\n", - "\n", - "print (name,age,profession)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here is the same example made as a complete sentence using f-strings. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "My name is Alice, I'm 25 years old, and I work as an engineer.\n" - ] - } - ], - "source": [ - "intro = f\"My name is {name}, I'm {age} years old, and I work as an {profession}.\"\n", - "\n", - "print (intro)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Formatting numbers\n", - "Python's f-strings provide a convenient way to format numbers by using the colon character and specifying the desired format. The following table demonstrates a couple of examples with the number $1$ using f-strings:

\n", - "\n", - "| Code | Result|\n", - "|------|------|\n", - "| 1:.2f | 1.00|\n", - "| 1:.0f| 1|\n", - "| 1:.10f| 1.0000000000 | \n", - "| 1:%| 100.000000%|\n", - "| 1:.1%| 100.0% |\n", - "| 1:e| 1.000000e+00 |" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the example below, the sleep() function from the time module is used to simulate the passage of time and provide a simple demonstration of a progress bar implementation. We define a function simulate_long_running_algorithm() that performs a loop with a sleep of 0.5 seconds between iterations. Within each iteration, the progress of the algorithm is calculated and used to construct a progress bar string. The progress bar consists of a series of equal signs (=) that visually represent the progress, followed by the percentage completion formatted to one decimal defined inside an f-strings." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[====================] 100.0%\n", - "Algorithm complete!\n" - ] - } - ], - "source": [ - "import time\n", - "\n", - "def simulate_long_running_algorithm():\n", - " total_iterations = 10\n", - " for i in range(total_iterations):\n", - " time.sleep(0.5) # Simulating processing time\n", - " progress = (i + 1) / total_iterations\n", - " progress_bar = f\"[{'=' * int(progress * 20):20s}] {progress * 100:.1f}%\"\n", - " print(progress_bar, end='\\r') # Print on the same line\n", - " print(\"\\nAlgorithm complete!\")\n", - "\n", - "simulate_long_running_algorithm()\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Escape characters

\n", - "\n", - "Escape characters in programming are special characters that are used to represent certain non-printable or special characters within strings. They are typically represented by a backslash (' \\ ') followed by a specific character or sequence. We used two escape characters in the previous example, can you identify them?\n", - "\n", - "| Code | Result| Description |\n", - "|------|------|------ |\n", - "| \\\\' | ' | represents the escape sequence for a single quote (').|\n", - "| \\\\\\ | \\\\ | represents the escape sequence for a backslash (' \\ ').|\n", - "| \\\\n | new line| represents the escape sequence for a new line character, which moves the cursor to the beginning of the next line. | \n", - "| \\\\r | carriage return | represents the escape sequence for a carriage return character, which moves the cursor to the beginning of the current line.|\n", - "| \\\\t | tab |represents the escape sequence for a tab character, which adds horizontal spacing. |\n", - "| \\\\b | backspace | represents the escape sequence for a backspace character, which moves the cursor one position back. |" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.2 Advanced Functions\n", - "\n", - "An example of an advanced fuction can be the lambda function. It is an anonymous function in Python that can be defined in a single line using the lambda keyword. It is typically used for simple and concise operations without the need for a formal function definition.\n", - "\n", - "Here's an example that showcases the difference between lambda functions and normal functions:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "12\n", - "12\n" - ] - } - ], - "source": [ - "# Normal function\n", - "def multiply(x, y):\n", - " return x * y\n", - "\n", - "result = multiply(3, 4)\n", - "print(result) # Output: 12\n", - "\n", - "# Lambda function\n", - "multiply_lambda = lambda x, y: x * y\n", - "\n", - "result_lambda = multiply_lambda(3, 4)\n", - "print(result_lambda) # Output: 12\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Both the normal function and the lambda function are used to multiply 3 and 4. The results obtained from both approaches are identical (12). The key difference is that the normal function is defined with the def keyword, whereas the lambda function is defined using the lambda keyword without a formal function name.\n", - "\n", - "lambda functions are particularly useful in scenarios where a small, one-time function is needed without the need for a full function definition and name." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 Working with files\n", - "\n", - "A lot of the work you'll do in Python will have the following structure:\n", - "1. Read data from a file\n", - "2. Perform computations on the data\n", - "3. Visualize the results and/or save the results to a file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### File paths\n", - "File paths on computers work based on a hierarchical structure, often represented as a tree. The root directory serves as the starting point, typically represented by a drive letter (e.g., C: on Windows). From the root directory, you can navigate to other directories using a delimiter character (\\ on Windows or / on Unix-based systems). Each directory can contain files and subdirectories, forming a hierarchical structure.\n", - "\n", - "Absolute paths specify the complete path from the root directory, while relative paths are relative to the current working directory. By understanding and manipulating file paths, you can effectively locate and access files and directories on a computer's file system." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### ``pathlib`` and os modules\n", - "\n", - "The os module in Python provides functions for interacting with the operating system, offering operations related to file management, directory handling, process management, and environment variables. It allows you to perform tasks such as creating, deleting, and modifying files and directories, launching external processes, accessing and modifying environment variables, and writing platform-independent code.\n", - "\n", - "On the other hand, the pathlib module introduced in Python 3.4 offers an object-oriented approach to working with file paths and directories. It provides the Path class, which represents paths as objects, allowing for more intuitive and expressive manipulation of paths compared to the traditional string-based operations in os. With pathlib, you can perform operations like joining paths, checking file existence, accessing file attributes, and creating directories in a more convenient and readable manner.\n", - "\n", - "The table below summuraizes some codes you can use for creating and adjusting your own file paths:" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "| Code | Result | Description |\n", - "|------|--------|-------------|\n", - "| `os.path.join(path, *paths)` | Path string | Joins one or more path components intelligently. It concatenates the arguments using the appropriate path delimiter for the operating system. |\n", - "| `os.path.abspath(path)` | Absolute path string | Returns the absolute path of the specified path. It resolves any symbolic links and references to parent directories. |\n", - "| `os.path.exists(path)` | Boolean | Checks if the specified path exists in the file system. Returns `True` if the path exists, and `False` otherwise. |\n", - "| `os.path.isdir(path)` | Boolean | Checks if the specified path is a directory. Returns `True` if the path is a directory, and `False` otherwise. |\n", - "| `os.path.isfile(path)` | Boolean | Checks if the specified path is a regular file. Returns `True` if the path is a file, and `False` otherwise. |\n", - "| `os.path.splitext(path)` | Tuple (base, ext) | Splits the specified path into its base name and extension. Returns a tuple where the first element is the base name and the second element is the extension (including the dot). |\n", - "| `os.path.basename(path)` | Base name string | Returns the base name (the file or directory name) from the specified path. |\n", - "| `os.path.dirname(path)` | Directory name string | Returns the directory name from the specified path. |\n", - "\n", - "Here are some examples of how to use these codes: " - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Path: folder\\subfolder\\file.txt\n", - "Absolute Path: c:\\Users\\ahmed\\Documents\\GitHub\\learn-python\\book\\03\\In_a_Nutshell\\folder\\subfolder\\file.txt\n", - "Exists: False\n", - "Is Directory: False\n", - "Is File: False\n", - "Base Name: file.txt\n", - "Directory Name: folder\\subfolder\n", - "Extension: .txt\n" - ] - } - ], - "source": [ - "import os\n", - "\n", - "path = os.path.join('folder', 'subfolder', 'file.txt') # Joining path components intelligently using appropriate delimiter.\n", - "absolute_path = os.path.abspath(path) # Getting the absolute path of the specified path.\n", - "exists = os.path.exists(path) # Checking if the specified path exists.\n", - "is_directory = os.path.isdir(path) # Checking if the specified path is a directory.\n", - "is_file = os.path.isfile(path) # Checking if the specified path is a file.\n", - "base_name, extension = os.path.splitext(path) # Splitting the path into base name and extension.\n", - "basename = os.path.basename(path) # Getting the base name (file or directory name) from the path.\n", - "dirname = os.path.dirname(path) # Getting the directory name from the path.\n", - "\n", - "# Printing the information\n", - "print(\"Path:\", path) # Path string\n", - "print(\"Absolute Path:\", absolute_path) # Absolute path string\n", - "print(\"Exists:\", exists) # Boolean indicating if path exists\n", - "print(\"Is Directory:\", is_directory) # Boolean indicating if path is a directory\n", - "print(\"Is File:\", is_file) # Boolean indicating if path is a file\n", - "print(\"Base Name:\", basename) # Base name of the file or directory\n", - "print(\"Directory Name:\", dirname) # Directory name of the path\n", - "print(\"Extension:\", extension) # File extension with the dot\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This code demonstrates the usage of various os.path functions to perform operations on file paths, such as joining paths, obtaining absolute paths, checking existence, identifying directories or files, splitting paths into base names and extensions, and retrieving the base name and directory name from a path. The corresponding outputs are displayed to provide the relevant information." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.4 Debugging \n", - "\n", - "Debugging in Python refers to the process of identifying and resolving errors or issues in a program. It involves analyzing the code execution, tracking down bugs, and correcting them to ensure the program functions as intended. \n", - "\n", - "Python provides several built-in tools and techniques for debugging, including print statements, using a debugger, logging, and exception handling. Debugging allows developers to gain insights into the program's flow, variable values, and identify the root cause of errors, ultimately improving the program's reliability and performance.\n", - "\n", - "### 1. Syntax errors\n", - "\n", - "Syntax errors in Python are mistakes in the structure or grammar of the code that violate the language's syntax rules, resulting in the program failing to execute.\n", - "\n", - "Example with a syntax error:\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "incomplete input (3691034111.py, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[1;36m Cell \u001b[1;32mIn[9], line 1\u001b[1;36m\u001b[0m\n\u001b[1;33m print(\"Hello, World!\"\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m incomplete input\n" - ] - } - ], - "source": [ - "print(\"Hello, World!\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Could you spot and fix the syntax error? The error was missing to close the parenthesis,the solution is shown below: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Hello, World!\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2. Runtime errors\n", - "\n", - "Runtime errors, also known as exceptions, occur during the execution of a program when unexpected conditions or behaviors are encountered, leading to program termination or abnormal behavior.\n", - "\n", - "For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "ename": "IndexError", - "evalue": "list index out of range", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[16], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[39m# Runtime error: accessing an index that is out of range\u001b[39;00m\n\u001b[0;32m 2\u001b[0m numbers \u001b[39m=\u001b[39m [\u001b[39m1\u001b[39m, \u001b[39m2\u001b[39m, \u001b[39m3\u001b[39m]\n\u001b[1;32m----> 3\u001b[0m \u001b[39mprint\u001b[39m(numbers[\u001b[39m3\u001b[39;49m])\n", - "\u001b[1;31mIndexError\u001b[0m: list index out of range" - ] - } - ], - "source": [ - "# Runtime error: accessing an index that is out of range\n", - "numbers = [1, 2, 3]\n", - "print(numbers[3])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Solution: Use a valid index within the range of the list. See the cell below:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "source": [ - "numbers = [1, 2, 3]\n", - "print(numbers[2])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3. Semantic errors\n", - "\n", - "Semantic errors, also known as logic errors, are mistakes in the program's logic or algorithm that lead to undesired or incorrect behavior without causing the program to terminate or throw an error.\n", - "\n", - "For example: " - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7.8\n" - ] - } - ], - "source": [ - "# Semantic error: incorrect calculation of the average\n", - "numbers = [5, 8, 12, 3, 6]\n", - "total = sum(numbers)\n", - "average = total / len(numbers) + 1\n", - "print (average)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Solution: Move the addition after calculating the average. Like this:" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7.0\n" - ] - } - ], - "source": [ - "real_average = (total + 1) / len(numbers)\n", - "print (real_average)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Debugging strategies\n", - "\n", - "\n", - "Debugging strategies are a set of techniques and approaches used to identify and fix errors or issues in code during the software development process, ensuring the program functions correctly and as intended. Some debugging strategies that can be applied by you during your work could include:\n", - "\n", - "1. Using print statements: Inserting print statements at critical points in the code to display the values of variables and track the program's flow.\n", - "2. Utilizing a debugger: Running the code in a debugger, setting breakpoints, and stepping through the code line by line to examine variable values and identify issues.\n", - "3. Logging: Adding log statements to record the program's execution and capture relevant information for analysis.\n", - "4. Exception handling: Wrapping sections of code in try-except blocks to catch and handle specific exceptions, allowing for graceful error handling and troubleshooting.\n", - "5. Code review: Having someone else review the code to spot potential errors or provide fresh insights.\n", - "\n", - "\n", - "By employing these strategies, you can effectively identify and resolve issues in your code, enhancing program functionality and reliability." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "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.11.2" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/book/03/Theory/01.ipynb b/book/03/Theory/01.ipynb deleted file mode 100644 index 4a1ef44..0000000 --- a/book/03/Theory/01.ipynb +++ /dev/null @@ -1,1065 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "# 3. Advanced strings and functions, files and debugging." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is common to have the first cell in a Notebook with all imports needed.\n", - "\n", - "We start to impor `pi` function from the `math` module and `os` module that we will use later.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [], - "source": [ - "from math import pi \n", - "import os " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 3.1 Advanced Strings\n", - "\n", - "Welcome to the third Notebook. In this Notebook we are going to learn some advanced Python. Let's first start with strings. Run the code below and see what it prints out." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This is an F-String\n", - "This is a string\n" - ] - } - ], - "source": [ - "MyFString = f\"This is an F-String\"\n", - "MyString = \"This is a string\"\n", - "print(MyFString)\n", - "print(MyString)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "\n", - "Now let's try inserting some data into our print() function. We'll use the list of integers [1,2,3,4]. " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Data1: 1, Data2: 2, Data3: 3, Data4: 4\n", - "Data1: 1 ,Data2: 2 ,Data3: 3 ,Data4: 4\n" - ] - } - ], - "source": [ - "Data = [1,2,3,4]\n", - "\n", - "MyFString = f\"Data1: {Data[0]}, Data2: {Data[1]}, Data3: {Data[2]}, Data4: {Data[3]}\"\n", - "\n", - "print(MyFString)\n", - "print(\"Data1:\",Data[0],\",Data2:\",Data[1],\",Data3:\",Data[2],\",Data4:\",Data[3])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see from the above code, it is much easier to insert variables in a string by using an f-string (formatted string)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Formatting numbers\n", - "\n", - "Using f-strings makes formatting numbers really easy. Just add a colon character after a number value and specify how you want to format the number. The following table demonstrates a couple of examples with the number $1$:

\n", - "\n", - "| Code | Result|\n", - "|------|------|\n", - "| 1:.2f | 1.00|\n", - "| 1:.0f| 1|\n", - "| 1:.10f| 1.0000000000 | \n", - "| 1:%| 100.000000%|\n", - "| 1:.1%| 100.0% |\n", - "| 1:e| 1.000000e+00 |\n", - "\n", - "As you can see the default number of decimal places is six. Furthermore, the % formatting operator assumes that $1$ is equal to $100$%, which is usual when working with fractions, and the formatting operator e formats using scientific notation." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now let's use our newfound knowledge of strings to make a simple progress bar. During other courses, you'll sometimes have to write algorithms that take a long time to run. In this case, it is useful to have a progress bar. Our example of a progress bar makes use of the sleep() function, from the time module, to simulate elapsed time." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading: 0%\n", - "Loading: 10%\n", - "Loading: 20%\n", - "Loading: 30%\n", - "Loading: 40%\n", - "Loading: 50%\n", - "Loading: 60%\n", - "Loading: 70%\n", - "Loading: 80%\n", - "Loading: 90%\n", - "Loading: 100%\n" - ] - } - ], - "source": [ - "import time\n", - "\n", - "for i in range(11):\n", - " print(f\"Loading: {i*10}%\", )\n", - " time.sleep(0.5) " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "This works! Though it is not that pretty to look at. It would look nicer to not have it print a new line each time. This is where escape characters come in. These characters can do some special things in strings. Below an example of some escape characters:\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "

Escape characters

\n", - "\n", - "| Code | Result|\n", - "|------|------|\n", - "| \\\\' | ' |\n", - "| \\\\\\ | \\\\ |\n", - "| \\\\n | new line| \n", - "| \\\\r | carriage return |\n", - "| \\\\t | tab |\n", - "| \\\\b | backspace |\n", - "\n", - "We can use some of these characters in our code. Let's use the carriage return character to make our progress bar not print out a new line every time. We can do this by adding end=\"\\r\" into our print function. The end keyword specifies a string that gets printed at the end. The string we print at the end here is the carriage return character. This carriage resets the print function to the start of the line; thus making the next print function overwrite the current printed line. Try it and see what happens:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "This is a very important message\n" - ] - } - ], - "source": [ - "print(\"Will I get overwritten?\", end=\"\\r\")\n", - "print(\"This is a very important message\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now let's add this to our progress bar... " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading complete!\n" - ] - } - ], - "source": [ - "import time\n", - "for i in range(11):\n", - " print(f\"Loading: {i*10}%\", end=\"\\r\")\n", - " time.sleep(0.5) \n", - "print(\"Loading complete!\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, it works beautifully!" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 3.2 Advanced Functions\n", - "\n", - "Sometimes you want to use the same code multiple times, so you could embed this code into a function. However, sometimes the code you want to use is so short that putting it into a function feels a bit over the top. This is where lambda functions are useful.

Lambda functions are functions that can take any number of arguments but can only have one expression in their function body. To demonstrate, see the code below. Here we have two functions that do exactly the same, but one is a lambda function and the other one is a normal function. " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The square root of 16 is equal to 4\n", - "The square root of 16 is equal to 4\n" - ] - } - ], - "source": [ - "sqrt_lambda = lambda x : x**0.5\n", - "\n", - "def sqrt(x):\n", - " sqrt = x**0.5\n", - " return sqrt\n", - "\n", - "print(f\"The square root of 16 is equal to {sqrt_lambda(16):.0f}\")\n", - "print(f\"The square root of 16 is equal to {sqrt(16):.0f}\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "
\n", - "As you can see, the lambda version is much more concise. It automatically returns the computed value for you as well." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 3.3 Working with files\n", - "\n", - "A lot of the work you'll do in Python will have the following structure:\n", - "1. Read data from a file\n", - "2. Perform computations on the data\n", - "3. Visualize the results and/or save the results to a file\n", - "\n", - "So far, we have only learned about computations. So let's learn a bit about how to manage files. Actually, opening or saving files is usually done with the help of modules which you will learn in more detail in Notebook 4 and 6. What we'll discuss here is how to manage file paths.\n", - "\n", - "### File paths\n", - "\n", - "To learn how to use files we need to learn how file paths in computers work. If you are tech-savvy and know how file paths work you can skip this part.\n", - "\n", - "File paths in computers work like a tree. They start at the root directory, which is often the C: drive (in Windows). This is the name of the hard drive that stores your Operating System. From the C: drive you can navigate into other directories. This is done using the **``\\``** character, however in other Operating Systems often the / delimiter is used.\n", - "\n", - "If a file is in the folder Users, which is stored in the C: directory, the file path would be C:\\Users. These types of file paths are called absolute paths. This file path is valid for most computers that run Windows, but some other Operating Systems may have different folder setups. This is why it is useful to use relative paths. Relative paths do not start from the root directory. Instead, they start from the directory you are currently in. By default, Jupyter Notebooks are stored in C:\\Users\\CurrentUser (where CurrentUser is your Windows username). To move into a directory using a relative path, for example, to the desktop folder, you would just write .\\Desktop. To move back a directory, using a relative path, you would type ..\n", - "\n", - "`os.listdir()` or `os.listdir('./')` list all the entries in your current directory `os.listdir('../')` list all entries if we go back one level. \n", - "\n", - ":::{note}\n", - "We use the `/` as delimiter, since a `\\` won't work on macOS\n", - ":::" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['01.ipynb']\n", - "['01.ipynb']\n", - "['Exercises', 'In_a_Nutshell', 'Theory']\n" - ] - } - ], - "source": [ - "import os\n", - "\n", - "print(os.listdir())\n", - "print(os.listdir('./'))\n", - "\n", - "print(os.listdir('../'))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - ":::{warning}\n", - "Keep in mind that, in Python, all file paths must be strings!\n", - ":::" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### ``pathlib`` and os modules\n", - "\n", - "These modules are very useful in managing and navigating your file paths. The function path.expanduser('~'), from the os module, allows you to find your root directory, independent of your Operating System. Try the below cell to see it." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "C:\\Users\\mmendozalugo\n" - ] - } - ], - "source": [ - "from pathlib import Path\n", - "import os\n", - "\n", - "root_path = os.path.expanduser('~')\n", - "print(root_path)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "The path shown above is thus the absolute path to your current directory.\n", - "\n", - "This can come in handy when you write a code that needs to create directories in the user's computer to save data files and/or plots. As an example, the code below checks if a directory exists and, if it doesn't, it creates one.\n", - "\n", - "The `os.path.join` is used to concatenate two strings to form a path string with the appropriate delimiter.\n", - "\n", - "The code will check if a directory named `plots` exists in your current directory if not, it will create one." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print('Contents of current directory (before):')\n", - "print(os.listdir(root_path))\n", - "\n", - "imdir = os.path.join(root_path,'plots') \n", - "print(f'\\nimdir = {imdir}')\n", - "\n", - "Path(imdir).mkdir(parents=True, exist_ok=True)\n", - "\n", - "print('\\nContents of current directory (after creating the new directory):')\n", - "print(os.listdir(root_path))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "tags": [ - "remove-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Contents of current directory (before):\n", - "['Exercises', 'In_a_Nutshell', 'Theory']\n", - "imdir = C:\\Users\\mmendozalugo\\plots\n", - "\n", - "Contents of current directory (after creating the new directory):\n", - "['Exercises', 'In_a_Nutshell', 'plots', 'Theory']\n" - ] - } - ], - "source": [ - "root_path = r'C:\\Users\\mmendozalugo\\OneDrive\\PhD\\Work\\Python_MOOC\\PM\\learn-python\\book\\03'\n", - "\n", - "print('Contents of current directory (before):')\n", - "print(os.listdir(root_path))\n", - "\n", - "imdir = os.path.join(root_path,'plots') \n", - "print('imdir = ',r'C:\\Users\\mmendozalugo\\plots')\n", - "\n", - "Path(imdir).mkdir(parents=True, exist_ok=True)\n", - "\n", - "print('\\nContents of current directory (after creating the new directory):')\n", - "print(os.listdir(root_path))\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To delete the folder that was just created we run the code bellow." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "try:\n", - " os.rmdir(imdir)\n", - " print(f'Directory {imdir} has been deleted.')\n", - "except:\n", - " print('You already deleted the folder. :)')" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "tags": [ - "remove-input" - ] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Directory C:\\Users\\mmendozalugo\\plots has been deleted.\n" - ] - } - ], - "source": [ - "print('Directory', r'C:\\Users\\mmendozalugo\\plots','has been deleted.')\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now you are, hopefully, a bit more used to working with file paths. For the next test, we are going to try to open a file. We can use some built-in Python functions to open a *.txt file and print its contents." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 3.4 Debugging\n", - "\n", - "It is very easy (and common) to make mistakes when programming. We call these errors bugs. Finding these bugs in your program and resolving them is what we call debugging.\n", - "\n", - "Errors\n", - "According to Think PythonAppendix A, there are three different types of errors:\n", - "\n", - "### 1. Syntax errors\n", - "\n", - "\"In computer science, the syntax of a computer language is the set of rules that defines the combinations of symbols that are considered to be correctly structured statements or expressions in that language.\"

Therefore, a syntax error is an error that does not obey the rules of the programming language. For example, parenthesis always comes in pairs... so (1+2) is OK, but 1+2) is not. Below another example of a syntax error. As you will see — this error is caught by the interpreter before running the code (hence, the print statements do not result in anything being printed).\n", - "\n", - "For example if I want to raise 2 to the 3rd power applying the wrong syntax, it will cause a syntax error." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (2052218902.py, line 4)", - "output_type": "error", - "traceback": [ - "\u001b[1;36m Cell \u001b[1;32mIn[12], line 4\u001b[1;36m\u001b[0m\n\u001b[1;33m 2***3\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "print('Message before')\n", - "2***3\n", - "print('Message after')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### 2. Runtime errors\n", - "\n", - "\"The second type of error is a runtime error. This type of error does not appear until after the program has started running. These errors are also called exceptions, as they usually indicate that something exceptional (and bad) has happened.\"\n", - "\n", - "Below an example of a small script to express fractions as decimals that will cause a runtime error. The error will appear, since you cannot divide by 0." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "New fraction was added from 1and 6!\n", - " It is equal to 0.167\n", - "New fraction was added from 7and 8!\n", - " It is equal to 0.875\n", - "New fraction was added from 5and -1!\n", - " It is equal to -5.000\n" - ] - }, - { - "ename": "ZeroDivisionError", - "evalue": "division by zero", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[1], line 6\u001b[0m\n\u001b[0;32m 3\u001b[0m fractions \u001b[39m=\u001b[39m []\n\u001b[0;32m 5\u001b[0m \u001b[39mfor\u001b[39;00m i \u001b[39min\u001b[39;00m \u001b[39mrange\u001b[39m(\u001b[39mlen\u001b[39m(numerators)):\n\u001b[1;32m----> 6\u001b[0m fractions\u001b[39m.\u001b[39mappend(numerators[i] \u001b[39m/\u001b[39;49m denominators[i])\n\u001b[0;32m 7\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mNew fraction was added from \u001b[39m\u001b[39m{\u001b[39;00mnumerators[i]\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m \n\u001b[0;32m 8\u001b[0m \u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mand \u001b[39m\u001b[39m{\u001b[39;00mdenominators[i]\u001b[39m}\u001b[39;00m\u001b[39m!\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m It is equal to \u001b[39m\u001b[39m{\u001b[39;00mfractions[i]\u001b[39m:\u001b[39;00m\u001b[39m.3f\u001b[39m\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m)\n", - "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" - ] - } - ], - "source": [ - "numerators = [1, 7, 5, 12, -1]\n", - "denominators = [6, 8, -1, 0, 5]\n", - "fractions = []\n", - "\n", - "for i in range(len(numerators)):\n", - " fractions.append(numerators[i] / denominators[i])\n", - " print(f'New fraction was added from {numerators[i]}' \n", - " f'and {denominators[i]}!\\n It is equal to {fractions[i]:.3f}')\n", - " " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### 3. Semantic errors\n", - "\n", - "According to the Oxford Dictionary, 'semantic' is an adjective relating to meaning. Therefore, a 'semantic error' is an error in the meaning of your code. Your code will still run without giving any error back, but it will not result in what you expected (or desired). For that reason, semantic errors are the hardest to identify. Below an example:\n", - "\n", - "I want to raise 2 to the 3rd power. However, I apply the wrong syntax that does not represent \"pow()\". \n", - "\n", - "No error message is created, because this syntax is used for another function in Python. However, this results in an output I did not expect nor desire." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2 to the 3rd power is 1\n" - ] - } - ], - "source": [ - "power_of_2 = 2^3\n", - "print(f'2 to the 3rd power is {power_of_2}')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Want to learn more about erros? Check the MUDE notebook for more detailed information about errors! MUDEWeek 1.6: Errors - Error Types " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Debugging strategies\n", - "\n", - "There are a few ways to debug a program. A simple one is to debug by tracking your values using print statements. By printing the values of the variables in between, we can find where the program does something unwanted. For example, the code block below:" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The sum of the elements of the list A is 3.\n" - ] - } - ], - "source": [ - "A = [0, 1, 2, 3]\n", - "\n", - "def sumA(my_list):\n", - " \"returns the sum of all the values in a given list\"\n", - " my_sum = 0\n", - " i = 0\n", - " while i < len(A):\n", - " my_sum = A[i]\n", - " i += 1\n", - " return my_sum\n", - "\n", - "print('The sum of the elements of the list A is {}.'.format(sumA(A)))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "We see that our sumA() function outputs $3$, which isn't the sum of the contents of the list $A$. By adding a print(my_sum) inside the loop we can get a clearer understanding of what goes wrong." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "var my_sum[0] = 0\n", - "var my_sum[1] = 1\n", - "var my_sum[2] = 2\n", - "var my_sum[3] = 3\n", - "The sum of the elements of the list A is 3.\n" - ] - } - ], - "source": [ - "def sumA(my_list):\n", - " \"returns the sum of all the values in a given list\"\n", - " my_sum = 0\n", - " i = 0\n", - " while i < len(A):\n", - " my_sum = A[i]\n", - " print('var my_sum[{}] = {}'.format(i,my_sum))\n", - " i += 1\n", - " return my_sum\n", - "\n", - "print('The sum of the elements of the list A is {}.'.format(sumA(A)))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "It looks like the function is just stating the values of the list $A$, but not adding them... so we must have forgotten to add something. Below the fixed version of that function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [], - "source": [ - "def sumA_fixed(my_list):\n", - " \"returns the sum of all the values in a given list\"\n", - " my_sum = 0\n", - " i = 0\n", - " while i < len(A):\n", - " my_sum += A[i]\n", - " print('var my_sum[{}] = {}'.format(i,my_sum))\n", - " i += 1\n", - " return my_sum\n", - "\n", - "print('The sum of the elements of the list A is {}.'.format(sumA_fixed(A)))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "print is simple and direct, and ideal for small scripts or quick troubleshooting, helping you quickly observe the state of your program. However, it is insufficient for more complex or systematic debugging needs. There are more debugging tools as Traceback, Raising Errors, Handling Errors, and Assertations. You can know more debugging tools by checking MUDEThe Python Traceback, The Python Traceback, Raising Errors, Handling Errors and Assertations." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## Additional study material\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/inputoutput.html\n", - "* https://realpython.com/python-f-strings/\n", - "* Official Python Documentation - https://docs.python.org/3/reference/expressions.html\n", - "* https://realpython.com/python-lambda/\n", - "* Official Python Documentation - https://docs.python.org/3/library/filesys.html\n", - "* https://realpython.com/working-with-files-in-python/\n", - "* Think Python (2nd ed.) - Section 14 \n", - "* Official Python Documentation - https://docs.python.org/3/library/debug.html\n", - "* Think Python (2nd ed.) - Appendix A and all (sub-)sections\n", - "* MUDE - Week 1.6: Errors" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "After this Notebook you should be able to:\n", - "\n", - "- print a variable, formatting it in an appropriate manner\n", - "- know the existence of escape characters\n", - "- know how to use lambda functions\n", - "- understand how file paths work\n", - "- create and delete new directories \n", - "- know the three different types of errors\n", - "- have a plan when debugging your code" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "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.13" - }, - "latex_envs": { - "LaTeX_envs_menu_present": true, - "autoclose": false, - "autocomplete": true, - "bibliofile": "biblio.bib", - "cite_by": "apalike", - "current_citInitial": 1, - "eqLabelWithNumbers": true, - "eqNumInitial": 1, - "hotkeys": { - "equation": "Ctrl-E", - "itemize": "Ctrl-I" - }, - "labels_anchors": false, - "latex_user_defs": false, - "report_style_numbering": false, - "user_envs_cfg": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/book/Python_Toolbox.md b/book/Python_Toolbox.md index 1154aeb..93b438f 100644 --- a/book/Python_Toolbox.md +++ b/book/Python_Toolbox.md @@ -1,41 +1,7 @@ -(toolbox)= # Python Toolbox -This page describes several ways to write and execute Python code, some of which don't require any installation on your computer and work entirely in a web browser! These approaches are described in the sections below, and are based on the tools IPython and Jupyter Notebooks. +% This page is a placeholder to ensure that links from previous years don't break. +% This works as long as `only_build_toc_files: false` (default) -**IPython** is an interactive Python interpreter that adds features that are useful for engineering, such as command history or inline display of figures. As you will see below, you can enter multiple lines of text and evaluate them at once; this is often referred to as a *cell* of code. In a nutshell, if you string many of these cells together into a single digital document, you more or less end up with a **Jupyter Notebook**; this leverages the power of IPython by allowing you to type, run and save the cells in any order, as well as type formatted text in between. Together, these two tools make up our toolbox for this course, and, as you will see, both of them can run in your internet browser, so there is no need to install special software! - -## Interactive Pages - -This course is powered by a special software (the [Sphinx-Thebe](https://github.com/executablebooks/sphinx-thebe) that allows you to run Python code in your browser and gives you an experience that is more or less identical the the "standard" Jupyter Notebook experience you would have on your own computer if you installed the dedicated software. You can access this tool by clicking on the rocket icon ({fa}`rocket`) at the top right of a page where this is enabled. - -(calculator)= -## IPython: Your Primary Python Calculator - -Below is an example of an IPython interpreter embedded in this webpage, which we refer to as our **Python Calculator**. Note that the square brackets with numbers (e.g, `[1]: ...`) are a feature of IPython that keeps track of the cells you have run: the first (pre-loaded) command is a print statement that executes once the interpreter is ready for use. You can try entering code yourself (for example, type `x=2`) and executing it using `Shift+Enter`. You just defined a variable! Note that typing `Enter` in the interpreter adds extra lines, it does not execute the cell. Try entering multiple lines, for example, `3*x`, `Enter` and `print(x)`, then execute. Can you tell what happened? - - - -The simple exercise above should be all you need to get started with this course. Throughout this course we encourage you to the Python Calculator in a new browser tab, which will allow you to read the exercise and run code side by side. You can test it here in a new tab. When the console is critical for completing the exercises in a certain chapter, a drop-down note will be added that includes a special link inside, just like this: - -`````{admonition} Open the Python Calculator for this page -:class: tip, dropdown -Click this link and wait until the message "You may begin!" is printed to start evaluating code. More information about this tool can be found [here](calculator). - -Remember that most pages in this course can also be run interactively using the {fa}rocket icon above (read more about it [here](toolbox)). -````` - -All exercises in this course can be completed using only the Python Calculator. We hope you find it to be a simple but useful way to practice and learn the Python programming language. - -```{note} -A special instance of the Python Calculator is set up for each page which pre-loads a few packages needed to complete the exercise. Make sure you use link that is on the page of the exercises you are working on. -``` - -## Anaconda: Python on Your Computer - -If you want to explore Python programming and Jupyter ecosystems beyond the exercises covered in this course, it might be worthwhile to install a Python distribution on your own computer. The most common and easiest way to do this is with [Anaconda](https://www.anaconda.com/download). Installation instructions are not included in this course, but you can find plenty of website of videos that cover this, as well as using the Anaconda Navigator to open a Jupyter Lab or Jupyter Notebook environment. Most of the pages in this online textbook can be downloaded in the form of a Jupyter Notebook file (a file ending with `.ipynb`): open it via one of the Jupyter environments and you are ready to go! \ No newline at end of file +```{include} ./toolbox.md +``` \ No newline at end of file diff --git a/book/Python_intro.md b/book/Python_intro.md index 20af2fa..3d88009 100644 --- a/book/Python_intro.md +++ b/book/Python_intro.md @@ -1,60 +1,7 @@ -# Introduction to Programming and Python +# Programming and Python -## Why do you need Python? - -Python is a computer programming language that is widely used in both academia and industries related to Civil Engineering, Environmental Engineering and Applied Earth Sciences. Being skilled in Python will help you on multiple occasions, including in your master courses. - -## What can computers do for us? -As an engineer or scientist, you will deal with units of information which are called data. The most important tasks that a computer can do for us are: - -1. Reading data -2. Processing data -3. Visualizing data - -These are tasks that require many repetitions and high precision. - -_1. Reading data_ -Reading data means the computer acquires data from a source and places it into its volatile memory for processing. Volatile memory keeps the data stored until the power supply is interrupted. The way data is stored in a computer determines how the computer will be able to use it. - -_2. Processing data_ -Data processing is the manipulation of the stored data in a system. After processing data by performing transformations, calculations, and more, you get an output; results. - -_3. Visualizing data_ -We map data (original or found) to graphic elements to communicate clearly and efficiently the information contained in the data. A graphic element is an element of a chart, such as a line or a point in the chart. - -## What is programming? - -Programming is giving your computer a list of instructions for computations in a language it can understand. In your case, this language is Python. A computation is a series of arithmetical ("math") and non-arithmetical ("non-math") steps that transform input to output (result). -There are five different kinds of instructions for computations you use. By ordering and combining them, the computer can achieve results that fulfill the three tasks described earlier. The five kinds of instructions are: - -input: - Insert data from a file, the network, other devices, or simply by typing it in. - -output: - Display data on the screen, save them in a file, send it over the network, etc. - -math: - Perform basic mathematical operations like addition and multiplication. - -conditional execution: - Check for certain conditions before further instruction. - -repetition: - Perform instructions repeatedly, usually with some variation. - - -## Introduction to Python - -The features of Python are what make it so popular. From the definition available on the corresponding Wiki page: "Python is an interpreted high-level general-purpose programming language. Its design philosophy emphasizes code readability with its use of significant indentation. Its language constructs, as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.". Quite a simple, yet concise description due to the meaning hidden behind each buzzword: - -
    -
  • Interpreted means that there is an interpreter, a software tool, which reads and performs instructions written in Python. If your laptop, phone, or refrigerator has the interpreter, it can run most of the Python scripts! -
  • High-level means that the programming language operates with abstract and more easily understandable concepts. In other words, you don't have to write or understand, code related to the hardware part of your machine (like binary code or assembly). -
  • General-purpose means that the amount of Python application fields are endless. You can write Python scripts to manage and automate some primitive tasks for yourself, you can use it for data science, create your own machine / deep learning project, write your personal web application or even develop a game. -
  • Programming language means a set of specific predefined semantics, instructions, and syntax rules, which are used for writing necessary instructions. It is strictly defined, meaning that 99.99% of all errors in the code are made by the coder, not by the computer. -
- -Python scripts run with the help of a Python interpreter, but they can be written by using different software tools. Just like as you write your essay (you can type it in Word, Google Docs, Overleaf, or even on plain paper) you can write your Python code with different editors. You could use the default notepad, notepad++, find a proper website with an inbuilt code editor & interpreter (IDEone, for example), or use specialized Python code editors (Spyder, PyCharm, Visual Studio, etc). In all cases you will produce a set of instructions, which are stored in a file with the *.py extension and the interpreter will run it completely (from top to bottom). - -For this course we will use a slightly different approach to developing a Python script: IPython and Jupyter Notebooks. Think of these as two freely-available tools that add extra functionality to the basic Python programming language. As an example, imagine the camera built into your phone: on it's own it can take pictures, but there are many apps that add filters or sharing via social media that make the impact of your photos much more powerful. This is exactly what IPython and Jupyter Notebooks do for Python, and why they are such important tools in the toolbox of modern engineers. The next Chapter will introduce you to your Python Toolbox for this course! +% This page is a placeholder to ensure that links from previous years don't break. +% This works as long as `only_build_toc_files: false` (default) +```{include} ./python.md +``` \ No newline at end of file diff --git a/book/_config.yml b/book/_config.yml index 7ccc258..52d9415 100644 --- a/book/_config.yml +++ b/book/_config.yml @@ -35,6 +35,7 @@ html: use_issues_button: true use_repository_button: true use_edit_page_button: true + use_multitoc_numbering: false # announcement: "⚠️ This is not the final version of the book! The new version will be ready by July 1.⚠️" extra_navbar: |
diff --git a/book/_toc.yml b/book/_toc.yml index bc82162..88748de 100644 --- a/book/_toc.yml +++ b/book/_toc.yml @@ -5,23 +5,44 @@ format: jb-book root: introduction.md parts: - caption: Introduction + numbered: false chapters: - file: intro.md title: Course Overview - - file: Python_intro.md + - file: python.md title: Programming and Python - - file: Python_Toolbox.md + - file: toolbox.md - caption: Course Contents + numbered: true chapters: - - file: 01/Theory/01.ipynb + - file: basics.md + title: Beyond the Basics sections: - - file: 01/Exercises/01.ipynb - - file: 02/Theory/01.ipynb + - file: basics/hello.ipynb + title: Your First Script + - file: basics/variables.ipynb + title: Variables + - file: basics/operators.ipynb + - file: basics/functions.ipynb + - file: basics/Exercises/01.ipynb + - file: flow.md + title: Flow sections: - - file: 02/Exercises/01.ipynb - - file: 03/Theory/01.ipynb + - file: flow/conditions.ipynb + title: "Conditions: `if`" + - file: flow/structures.ipynb + - file: flow/loops.ipynb + - file: flow/Exercises/01.ipynb + - file: beyond.md + title: Beyond the Basics sections: - - file: 03/Exercises/01.ipynb + - file: beyond/strings.ipynb + title: Strings + - file: beyond/functions.ipynb + title: Functions + - file: beyond/files.ipynb + title: Files + - file: beyond/Exercises/01.ipynb - file: 04/Theory/01.ipynb sections: - file: 04/Exercises/01.ipynb @@ -46,13 +67,33 @@ parts: - file: 09/handling_errors.ipynb - file: 09/asserts.ipynb - caption: End of course survey + numbered: false chapters: - file: End-of-course-survey.md - caption: In a Nutshell + numbered: 2 chapters: - - file: 01/In_a_Nutshell/01.ipynb - - file: 02/In_a_Nutshell/01.ipynb - - file: 03/In_a_Nutshell/01.ipynb + - file: basics/nutshell.md + title: Basics + sections: + - file: basics/nutshell/hello.ipynb + - file: basics/nutshell/variables.ipynb + - file: basics/nutshell/operators.ipynb + - file: basics/nutshell/functions.ipynb + - file: flow/nutshell.md + title: Flow + sections: + - file: flow/nutshell/conditions.ipynb + - file: flow/nutshell/structures.ipynb + - file: beyond/nutshell.md + title: Beyond the Basics + sections: + - file: beyond/nutshell/strings.ipynb + title: Strings + - file: beyond/nutshell/functions.ipynb + title: Functions + - file: beyond/nutshell/files.ipynb + title: Files - file: 04/In_a_Nutshell/01.ipynb - file: 05/In_a_Nutshell/01.ipynb - file: 06/In_a_Nutshell/01.ipynb diff --git a/book/basics.md b/book/basics.md new file mode 100644 index 0000000..6bfb436 --- /dev/null +++ b/book/basics.md @@ -0,0 +1,6 @@ +# Basics + +This chapter is all about getting some of the basics under your belt! + +% a short overview for this chapter + diff --git a/book/01/Exercises/01.ipynb b/book/basics/Exercises/01.ipynb similarity index 84% rename from book/01/Exercises/01.ipynb rename to book/basics/Exercises/01.ipynb index b6a14d2..3b3f700 100644 --- a/book/01/Exercises/01.ipynb +++ b/book/basics/Exercises/01.ipynb @@ -47,23 +47,6 @@ "#questions = [[q] for q in questions]" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "Pq9kETciS3VO", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## Exercise 1.2.2\n", - "\n", - "\n" - ] - }, { "cell_type": "code", "execution_count": null, @@ -79,23 +62,6 @@ "# display_quiz(questions[0])" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "cc546f8c", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## Exercise 1.2.3\n", - "\n", - "" - ] - }, { "cell_type": "code", "execution_count": null, @@ -122,7 +88,9 @@ } }, "source": [ - "## (Fixing) Exercise 1.2.4\n", + "\n", + "\n", + "## (Fixing) Exercise\n", "In the following exercise you will be using a piece of code, which was written by other people. It can contain concepts you haven't encountered yet but you need to practice with using code you don't understand completely. This is because you want to be able to use programs written by other people. Just like with calculators — if you add two numbers you get the result you expect to get. But you don't know exactly how that piece of plastics with electronic components performs that calculation.\n", "\n", "In order to approach the problem, start from the point of error. If your error cannot be solved there, work your way backwards through the code. Only try to understand the parts that are necessary to fix your problem, and avoid changing parts you know that work.\n", @@ -200,7 +168,8 @@ } }, "source": [ - "## (Searching) Exercise 1.2.5\n", + "\n", + "## (Searching) Exercise\n", "There are also other data types in Python, which were not mentioned in this part (in case they are not as useful or will be introduced later). For instance, Complex is one of them. The sad truth is that every software developer Googles a lot. It's not because she/he is lazy or incompetent. It is because programming languages are constantly updated and some tools are limited to a narrow field of applications. It is impractical to learn everything at once, therefore every coder has learned how to look up the functionality their task requires. Therefore, it is crucial for you to learn how to Google as well. Complex type is used in Python to represent complex numbers. If you haven't heard about them — a complex number is a number, which has a real and an imaginary part. For example, $x = 17 + 5i$. Here, $x$ is a complex number with a real part of $17$ and an imaginary part of $5$.\n", "\n", "Your task is to create a variable my_complex_number of Complex type and assign a $3 + 2i$ value to it. For that you will have to Google a bit. Try to look for something like \"Python complex variables\". Python is very popular and you will be able to find everything you need. Make sure to filter the information you need — not everything you will find will be useful for this simple exercise.\n" @@ -241,7 +210,8 @@ } }, "source": [ - "## Exercise 1.3.1\n", + "\n", + "## Exercise\n", "\n", "Given that we have a rectangle with a height of $3$ cm, width of $5$ cm and a cutout circle of radius $0.6$ cm, as shown below. \n", "\n", @@ -307,29 +277,6 @@ "#display_quiz(questions[4]+questions[5])" ] }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "rax0w6q5S3WF", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## Exercise 1.3.2\n" - ] - }, - { - "cell_type": "markdown", - "id": "0b0d21d9", - "metadata": {}, - "source": [ - "" - ] - }, { "cell_type": "code", "execution_count": null, diff --git a/book/01/Exercises/01.json b/book/basics/Exercises/01.json similarity index 100% rename from book/01/Exercises/01.json rename to book/basics/Exercises/01.json diff --git a/book/01/Exercises/01.png b/book/basics/Exercises/01.png similarity index 100% rename from book/01/Exercises/01.png rename to book/basics/Exercises/01.png diff --git a/book/basics/functions.ipynb b/book/basics/functions.ipynb new file mode 100644 index 0000000..1937843 --- /dev/null +++ b/book/basics/functions.ipynb @@ -0,0 +1,617 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "116647f2", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Functions\n", + "\n", + "A function is a collection of code that is assigned to a specific name. You have already seen some built-in Python functions, such as print(). Using functions is useful because it allows you to run the same code again without having to type it a second time.\n", + "\n", + "Below are some examples of common built-in Python functions and what they do:\n", + "\n", + "\n", + "* ``print()``: Prints input to screen\n", + "* ``type()``: Returns the type of the input\n", + "* ``abs()``: Returns the absolute value of the input\n", + "* ``min()``: Returns the minimum value of the input. (input could be a list, tuple, etc.)\n", + "* ``max()``: Same as above, but returns the maximum value\n", + "* ``sum()``: Returns the sum of the input (input could be a list, tuple, etc.)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "But the story doesn't end at built-in functions. You can also write your own functions!\n", + "\n", + "### How to write a function\n", + "\n", + "To write a function, you must first define it. This is done by using the def statement. Then, you name the function and add, in the parentheses, which variables this function takes as an input, followed by a colon. The colon tells Python you are going to define the function body next (the part of the function that actually does the computation). As shown below:

\n", + "\n", + "
def function_name(input1, input2,...):
function_body
...
...
\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "242bb5c2", + "metadata": {}, + "source": [ + "\n", + "The calculate_circle_area(r) function below defines pi as a variable and then computes the area of a circle, which is stored in the variable area. Finally, it uses the return statement to output the area back to you. Once you have defined the function, you can then call it by typing the function name, and the inputs in the parenthesis. For example, calling: print(\"Hello World!\"), prints the string \"Hello World!\".\n", + "\n", + "Indentation
\n", + "\n", + "It is worth noting that the function body should be indented. This is how Python sees what piece of code is inside another code. An indented line of code is a line that starts with whitespace. You can do this by using the tab key on your keyboard." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "::: {note}\n", + "Inputs of functions are more often called arguments.\n", + ":::" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### indentation of code within functions\n", + "\n", + "Let's say you'd want to compute the area of a circle, but you don't want to calculate $\\pi r^2$ the entire time. Then you can write a couple lines of code to do it for you, and wrap it up into a function, like the one below:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [], + "source": [ + "def calculate_circle_area(r):\n", + " pi = 3.141592653589793\n", + " area = pi*(r**2)\n", + " return area" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "This function is called calculate_circle_area(r), and takes the value r as an argument." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Functions can have multiple arguments, for example:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Area of my rectangle is 24 cm^2\n" + ] + } + ], + "source": [ + "def calculate_rectangle_area(a, b):\n", + " area = a * b\n", + " return area\n", + "\n", + "print('Area of my rectangle is', calculate_rectangle_area(4, 6), 'cm^2')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "In the cell above, the **`calculate_rectangle_area(a, b)`** function takes $2$ arguments, $a$ and $b$. \n", + "\n", + "The built-in function **`print()`** takes $3$ arguments:
\n", + "the string 'Area of my rectangle is', the output of calculate_rectangle_area(a, b), and another string 'cm^2'.\n", + "\n", + "There are better ways to use the built-in print() function when writing long sentences that have variables in between. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Area of my rectangle is 24 cm^2 and the area of my circle is 50.26548245743669 cm^2\n" + ] + } + ], + "source": [ + "print('Area of my rectangle is {} cm^2 and the area of my circle is {} cm^2'. \\\n", + " format(calculate_rectangle_area(4,6), calculate_circle_area(4)))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "If a line in your code extends the width of your page, you can use a **\\\\** at the point where you want to break the line, as shown above.\n", + "\n", + "Note that the variables (separated by commas) called inside the .format() will appear, in order, where the { } are located.\n", + "\n", + "Furthermore, you can also format how you want the numbers to appear, as shown below:" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Area of my rectangle is 24.00000 cm^2 and the area of my circle is 50.27 cm^2\n" + ] + } + ], + "source": [ + "print('Area of my rectangle is {:.5f} cm^2 and the area of my circle is {:.2f} cm^2'. \\\n", + " format(calculate_rectangle_area(4,6), calculate_circle_area(4)))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Where the :.5f states that you want to print that variable with $5$ decimal numbers. Similarly, :.2f rounds the number to $2$ decimal numbers. More information on this in Section 3.1, in Notebook 3." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### Documenting functions\n", + "We have now successfully created a function that computes the area of a circle and the area of a rectangle. You could send this code to fellow students, but maybe they wouldn't know how to use them. This is where a docstring comes in handy. This is a string specified in the beginning of the function body which states information about the function. A lot of built-in Python functions also have docstrings, which is really useful when you're trying to understand how to use a function." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Add a description to the calculate_circle_area(r) function below, as a docstring.
" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": false, + "solution": false + } + }, + "outputs": [], + "source": [ + "def calculate_circle_area(r):\n", + " '''This function calculate the area of a circle with radius r '''\n", + " pi_circle = 3.141592653589793\n", + " area = pi_circle*(r**2)\n", + " return area" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, nothing happened. But, if we now call the function like this:\n", + "```\n", + "calculate_circle_area?\n", + "```\n", + "or:\n", + "```\n", + "help(calculate_circle_area)\n", + "```\n", + "we should see the description (docstring) of the function. Try yourself below:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function calculate_circle_area in module __main__:\n", + "\n", + "calculate_circle_area(r)\n", + " This function calculate the area of a circle with radius r\n", + "\n" + ] + } + ], + "source": [ + "help(calculate_circle_area)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now this isn't of much use when you work on your own code, unless you are very forgetful or have to write large programs.\n", + "But if you work using other people's code, this is really useful, as it helps you figure out how to use each function." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "#### When to write or use a function?\n", + "\n", + "You can use functions in your code when you have a specific piece of code that you need to use multiple times (e.g.: plotting something).

Often you will find you want to use an output from a function later on. To do this, you can assign a function to a variable. Let's say I want to use the area of a circle in a later calculation. Then you can store it in a variable like this:\n", + "\n", + "We stored the area of a circle that has a radius 4 in the variable ``Circle_Area``" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [], + "source": [ + "Circle_Area = calculate_circle_area(4)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Nothing happens, but the value of calculate_circle_area(4) is now stored in the variable Circle_Area. See below:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "50.26548245743669\n" + ] + } + ], + "source": [ + "print(Circle_Area)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "We can see that the value was indeed stored.\n", + "\n", + "::: {warning}\n", + "Variables that are defined inside a function body can NOT be called from outside of the function. These variables are called local variables.\n", + ":::" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Take the variable **`pi_circle`** that we defined in the function **`calculate_circle_area()`**. If we try to print it:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'pi_circle' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[52], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(pi_circle)\n", + "\u001b[1;31mNameError\u001b[0m: name 'pi_circle' is not defined" + ] + } + ], + "source": [ + "print(pi_circle)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "See, it doesn't work!\n", + "The error you get: NameError: name 'pi_circle' is not defined, means that you tried to call a variable that does not exist." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "93d877b3", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "## Additional study material:\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/tutorial/introduction.html\n", + "* https://realpython.com/python-variables/\n", + "* Think Python (2nd ed.) - Section 2\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/library/operator.html\n", + "* https://realpython.com/python-operators-expressions/\n", + "* Think Python (2nd ed.) - Sections 2 and 5\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/tutorial/controlflow.html#defining-functions\n", + "* https://realpython.com/defining-your-own-python-function/\n", + "* Think Python (2nd ed.) - Sections 3, 6 and 16" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### After this Notebook you should be able to:\n", + "\n", + "- understand why you need to learn Python\n", + "- create and re-assign new variables\n", + "- determine the type of a variable using `type()`\n", + "- slice strings\n", + "- perform simple math using arithmetic operators\n", + "- compare two or more variables\n", + "- check if a value, or element, exists in an object\n", + "- define a function, including its docstring" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "merged.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.11.5" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/book/basics/hello.ipynb b/book/basics/hello.ipynb new file mode 100644 index 0000000..f488772 --- /dev/null +++ b/book/basics/hello.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "c0279304", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "## Your First Python Script\n", + "\n", + "So, it is time for your first Python script. It is located beneath.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "3d1f70cf", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "ee5c28c1-473e-4c2d-9a33-b15b51fffc5f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello world!\n" + ] + } + ], + "source": [ + "# My First Python Script\n", + "message = 'Hello world!'\n", + "print(message)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "7a16f396", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "\n", + "`````{admonition} Let's break it down\n", + "\n", + "First line: # My First Python Script is a comment, which is used just to explain and/or put useful information about the code next to it. If you need to create a comment — just type a # symbol and write your text after it. The interpreter does nothing with it — the comments are there just as useful information for you or another reader.\n", + "\n", + "Second line: message = 'Hello world!' creates a variable called message and assigns the text literal (string) Hello world! to it, by using the operator = (equal sign). Variables are used to store all data you use in your code.\n", + "\n", + "Third line: print(message) calls the functionprint() and passes the variable message to it. A function is just a set of encapsulated code, which is tailored to perform a certain action. This specific function outputs the content of everything you pass to it. Since the variable message had a small line of text in it, the function print() outputs that message.\n", + "\n", + "This script is quite primitive and simple but it represents the main idea of programming in Python. You have data (which is stored in variables) and you perform an operation on it: by using the inbuilt print() function. In addition, you could create your own functions. \n", + "\n", + "`````" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "merged.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.11.5" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/book/basics/nutshell.md b/book/basics/nutshell.md new file mode 100644 index 0000000..62853e5 --- /dev/null +++ b/book/basics/nutshell.md @@ -0,0 +1,3 @@ +# Basics: in a Nutshell + +Nutshell. \ No newline at end of file diff --git a/book/basics/nutshell/functions.ipynb b/book/basics/nutshell/functions.ipynb new file mode 100644 index 0000000..1481425 --- /dev/null +++ b/book/basics/nutshell/functions.ipynb @@ -0,0 +1,182 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Functions " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In Python, a function is a block of code that can be reused multiple times throughout a program. Functions are useful for organizing and structuring code, and for breaking down complex tasks into smaller, more manageable pieces. " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below are some examples of common built-in Python functions and what they do:\n", + "\n", + "\n", + "* ``print()`` Prints input to screen\n", + "* ``type()`` Returns the type of the input\n", + "* ``abs()`` Returns the absolute value of the input\n", + "* ``min()`` Returns the minimum value of the input. \n", + " (input could be a list, tuple, etc.)\n", + "* ``max()`` Same as above, but returns the maximum value\n", + "* ``sum()`` Returns the sum of the input \n", + " (input could be a list, tuple, etc.)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is a step-by-step guide on how to create any function in Python:\n", + "\n", + "**Step 1:** Define the function using the def keyword, followed by the function name, and a set of parentheses.\n", + "\n", + "**Step 2:** Define the code block that will be executed when the function is called. This code block should be indented underneath the function definition. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "def greet():\n", + " print(\"Hello, World!\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Step 3:** (Optional) Add parameters to the function, which are values that can be passed into the function when it is called. These parameters are defined within the parentheses of the function definition. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "def greet(name):\n", + " print(\"Hello, \" + name + \"!\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Step 4:** (Optional) Add a return statement to the function, which is used to return a value or an expression from the function. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "def add(x, y):\n", + " return x + y" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Step 5:** Call the function by using the function name, followed by a set of parentheses. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, John Weller!\n" + ] + } + ], + "source": [ + "greet(\"John Weller\")\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Thus, to create and use the function we write it all in one cell as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, John!\n", + "Hello, Mary Jane!\n" + ] + } + ], + "source": [ + "def greet(name):\n", + " print(\"Hello, \" + name + \"!\")\n", + "\n", + "greet(\"John\")\n", + "greet(\"Mary Jane\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, the function **greet()** is defined with one parameter **name**, the function is called twice, first with \"John\" as an **argument**, then with \"Mary\" as an **argument**, the function will print out a greeting message each time it's called --> the **input** of the created function is the argument and the **output** is the greeting message.\n", + "\n", + "Functions are essential to programming, they allow you to organize, structure and reuse your code in an efficient and readable way." + ] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/basics/nutshell/hello.ipynb b/book/basics/nutshell/hello.ipynb new file mode 100644 index 0000000..c9f3dc5 --- /dev/null +++ b/book/basics/nutshell/hello.ipynb @@ -0,0 +1,117 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Your First Python Script\n", + "\n", + "```{tip}\n", + "This is an \"In a Nutshell\" page. For additional explanation, see the full page {doc}`here <../hello>`.\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Excuting a cell in python" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The print() function in Python is used to output or display text or other information on the screen. It can be used to display a string of text, the value of a variable, or the result of a calculation. The text or information that you want to display is passed as an argument inside the parenthesis of the print() function.\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Print () command" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To execute a cell in Python, you can use the run command in Jupyter Notebook or press the \"Run\" button in the toolbar. You can also use the keyboard shortcut **Shift + Enter** to execute the cell. \n", + "\n", + "Lets start by excecuting our first code by printing the words 'Hello world'. Press **Shift+Enter** to run the cell below. You should see the output \"Hello, World!\" displayed below the cell. Notice that we have to write the sentence inside the quotation marks to indicate that the data is of string type. \n", + "\n", + "Alternatively, You can also execute the code by clicking on the Run button in the toolbar or by using the run command in the Jupyter Notebook." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, world!\n" + ] + } + ], + "source": [ + "print ('Hello, world!')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, try to fill in your name and print the following sentence in the next cell: \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "My name is _____\n" + ] + } + ], + "source": [ + "print ('My name is _____')" + ] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/basics/nutshell/operators.ipynb b/book/basics/nutshell/operators.ipynb new file mode 100644 index 0000000..dc96c89 --- /dev/null +++ b/book/basics/nutshell/operators.ipynb @@ -0,0 +1,387 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Operators \n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Arithmetic Operators\n", + "\n", + "| Math sign | Python sign | name |\n", + "| :-: | :-: |:-:|\n", + "| + | + | addition |\n", + "| - | - | subtraction |\n", + "| * | * | multiplication |\n", + "| / | / | division |\n", + "| ^ | ** | exponentiation |\n", + "| mod | % | modulus |\n", + "| | // | floor division |" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Arithmetic operators: These operators perform mathematical operations, such as addition, subtraction, multiplication, and division. Examples:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7\n", + "3\n", + "10\n", + "2.5\n", + "25\n" + ] + } + ], + "source": [ + "x = 5\n", + "y = 2\n", + "\n", + "print(x + y) # Output: 7 \n", + "print(x - y) # Output: 3\n", + "print(x * y) # Output: 10\n", + "print(x / y) # Output: 2.5\n", + "print(x**y) # output: 25\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Error codes in python" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When you run a Python script or code in a cell, the code is executed line by line, starting from the first line and moving down the code.\n", + "\n", + "If an error occurs, Python will stop executing the code at the line where the error occurs and will display an error message. The first line of the error will indicating the line number where the error occurred. This is often the most informative as it tells you where in your code the problem is. The last line in the error message will tell you what the problem in this line is." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The code results in a TypeError because you are trying to add a variable of type integer (a) to a variable of type string (b). In python, you can only add two variables of the same type. You can't add an int to a string.\n", + "If you want to concatenate the string and the int you can convert the int to string before adding them together. " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0hello\n" + ] + } + ], + "source": [ + "a = 0\n", + "b = \"hello\"\n", + "c = str(a) + b\n", + "\n", + "print (c)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or you can use the format() method to insert the value of a into the string b." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello 5\n" + ] + } + ], + "source": [ + "a = 5\n", + "b = \"hello {}\"\n", + "c = b.format(a)\n", + "\n", + "print (c)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or you can use f-strings (formatted string literals) that are available from python 3.6 and above. You can show a nummerical output with any string you want using f-strings. The code you need to type for f-strings: **f ' text {output} '**. The output has to be inside the curly brackets --> { } " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello 5\n" + ] + } + ], + "source": [ + "a = 5\n", + "b = \"hello\"\n", + "c = f\"{b} {a}\"\n", + "\n", + "print (c)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison Operators
\n", + "\n", + "In Python, you often want to compare a value with another. For that, you use comparison operators.\n", + "\n", + "| Math sign | Python sign | Meaning |\n", + "| :-: | :-: | :-: |\n", + "| $=$ | $==$ | Equal to |\n", + "| $>$ | $>$ | Greater than |\n", + "| $<$ | $<$ | Less than |\n", + "| $\\geqslant$ | $>=$ | Greater than or equal to |\n", + "| $\\leqslant$ | $<=$ | Less than or equal to |\n", + "| $\\neq$ | $!=$ | Not equal to |" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Comparison operators: These operators compare two values and return a Boolean value (True or False). Examples:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "True\n", + "True\n", + "False\n", + "True\n", + "False\n" + ] + } + ], + "source": [ + "x = 5\n", + "y = 2\n", + "print(x == y) # Output: False\n", + "print(x != y) # Output: True\n", + "print(x > y) # Output: True\n", + "print(x < y) # Output: False\n", + "print(x >= y) # Output: True\n", + "print(x <= y) # Output: False\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Control flow statements in Python" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are several control flow statements in Python that are used to control the flow of execution of a program. The most important ones are:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**if** statement: The if statement is used to check a certain condition, and if the condition is true, the code within the if block will be executed. If the condition is false, the code within the if block will be skipped. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x is positive\n" + ] + } + ], + "source": [ + "x = 5\n", + "if x > 0:\n", + " print(\"x is positive\")\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**if-else** statement: The if-else statement is an extension of the if statement, which allows you to specify a block of code to be executed if the condition is true, and a different block of code to be executed if the condition is false. Example:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x is non-positive\n" + ] + } + ], + "source": [ + "x = -2\n", + "if x > 0:\n", + " print(\"x is positive\")\n", + "else:\n", + " print(\"x is non-positive\")\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**if-elif-else** statement: The if-elif-else statement is an extension of the if-else statement, which allows you to check multiple conditions and execute different code blocks based on the first condition that is true. This is how you use them: " + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x is zero\n", + "x2 is negative\n" + ] + } + ], + "source": [ + "x = 0\n", + "if x > 0:\n", + " print(\"x is positive\")\n", + "elif x == 0:\n", + " print(\"x is zero\")\n", + "else:\n", + " print(\"x is negative\")\n", + " \n", + "\n", + "x2 = -2\n", + "if x2 > 0:\n", + " print(\"x2 is positive\")\n", + "elif x2 == 0:\n", + " print(\"x2 is zero\")\n", + "else:\n", + " print(\"x2 is negative\")\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Indexing" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Indexing is a method in Python to access individual elements in a list by their position. This is a fundamental feature of Python's list data structure, allowing you to retrieve specific elements from the list. Elements are stored in a sequential manner and can be accessed using their index (integer value indicating their position)." + ] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/basics/nutshell/variables.ipynb b/book/basics/nutshell/variables.ipynb new file mode 100644 index 0000000..191c455 --- /dev/null +++ b/book/basics/nutshell/variables.ipynb @@ -0,0 +1,310 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Python Variables" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Value\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In Python, a **value** is any data that can be stored in a variable. It can be a number (such as an integer or a float), a string (a sequence of characters), a Boolean (True or False), or other types of data. For example" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "x = 5 # x is a variable that holds an integer value of 5\n", + "y = \"Hello World\" # y is a variable that holds a string value of \"Hello World\"\n", + "z = True # z is a variable that holds a Boolean value of True" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Variable " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A **variable** is a container that holds a value, which is like a label or a name given to the value that is stored inside it. You can use variables to store values and then use them later in your code. You can also change the value of a variable at any time. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "x = 5 # x is a variable that holds an integer value of 5\n", + "x = x + 2 # x now holds the value of 7" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### String" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A string is a sequence of characters, enclosed in quotation marks. You can use strings to store text, such as words and sentences. You can also use them to display messages to the user or to create strings that hold specific data, like a name or an address. Strings are a very important data type in python and you will use it very frequently. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Hello World'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"Hello World\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### List" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A list in Python is a collection of values stored in a single object, similar to arrays in other programming languages. Lists can contain elements of any type, including numbers, strings, and other objects. \n", + "\n", + "To create a list in Python, you can use square bracket [ ] notation and include the values you want to store in the list, separated by commas.\n", + "\n", + "For a beginner, it's important to remember the following when creating lists in Python:\n", + "\n", + "* Lists start with a square bracket [ ]\n", + "* Values in the list are separated by commas\n", + "* Lists can contain elements of any type, including numbers, strings, and other objects." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3.14, 'Hello', True]\n" + ] + } + ], + "source": [ + "# create a list\n", + "my_list = [1, 2, 3.14, \"Hello\", True]\n", + "\n", + "# print the list\n", + "print(my_list)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Indexing in Python is a way to access specific elements in a list or array. Think of a list as a row of boxes, where each box contains a value. The index is the number assigned to each box [ ] and it allows us to locate a specific value or object. Lists in Python are zero-indexed, meaning that the first element in the list is stored at index 0, the second element is stored at index 1, and so on. For example, we an print any element in out created list by specifying the index releated:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "Hello\n", + "3.14\n" + ] + } + ], + "source": [ + "# access elements by index\n", + "print(my_list[0]) # prints the integer 1\n", + "print(my_list[3]) # prints the string \"Hello\"\n", + "print (my_list[2]) # prints the float 3.14" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## type () of data in python " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In Python, you can use the built-in type() function to determine the type of an object. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\n" + ] + } + ], + "source": [ + "x = 5\n", + "print(type(x)) # Output: \n", + "\n", + "y = \"hello\"\n", + "print(type(y)) # Output: \n", + "\n", + "z = [1, 2, 3]\n", + "print(type(z)) # Output: " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also check an object's type very simply by:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "int" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x2 = 5\n", + "type(x2) # Output: int" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "str" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y2 = 'hello'\n", + "type(y2) # Output: str" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "list" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "z2 = [1, 2, 3]\n", + "type(z2) # Output: list" + ] + } + ], + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/basics/operators.ipynb b/book/basics/operators.ipynb new file mode 100644 index 0000000..b20b03d --- /dev/null +++ b/book/basics/operators.ipynb @@ -0,0 +1,603 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "Tpeh8gLqS3V4", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Operators\n", + "\n", + "Python operators are used to perform operations on variables and values. They are symbols that represent a form of computation; think of addition or multiplication. The value to which this computation is applied to is called the 'operand'. Most of the common operators you will recognize from mathematics." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "1yHso5KtS3WC", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "

Arithmetic Operators

\n", + "\n", + "| Math sign | Python sign | name |\n", + "| :-: | :-: |:-:|\n", + "| + | + | addition |\n", + "| - | - | subtraction |\n", + "| * | * | multiplication |\n", + "| / | / | division |\n", + "| ^ | ** | exponentiation |\n", + "| mod | % | modulus |\n", + "| | // | floor division |\n", + "\n", + "\n", + "
Most of the mathematical symbols stay the same when transforming a piece of mathematics to Python. Note that the exponentiation sign is a double multiplication sign!

\n", + "The last two operators, modulus and floor division, can be defined as the following:
\n", + "- modulus: return the remainder of a division
\n", + "- floor division: returns the integer/whole part of the division\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "Ijx03oCKS3WD", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now we will provide some small examples\n", + "\n", + "a. multiply 4 by 3 and then add 2\n", + "\n", + "b. 2 to the power of 4 plus 1\n", + "\n", + "c. take the modulus of 352 over 23\n", + "\n", + "d. the floor division of 352 over 23\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "wOPRR9oLS3WD", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "d888e6de-7185-453a-a33e-dc2f38817e9f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "14\n" + ] + } + ], + "source": [ + "a = 2 + 4 * 3\n", + "print(a)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "V50AuE4US3WD", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "d7518f7e-535f-4ea2-a233-06e71de779be" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "17\n" + ] + } + ], + "source": [ + "b = 2**4 + 1\n", + "print(b)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "a674y2ZoS3WE", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "2b8bfe90-f5db-40b7-beac-119d63142e3f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7\n" + ] + } + ], + "source": [ + "c = 352 % 23\n", + "print(c)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Explanation: $352 = 15 \\times 23 + 7$, therefore the **modulus operator** returns the value $7$." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "15\n" + ] + } + ], + "source": [ + "d = 352 // 23\n", + "print(d)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Explanation: $352 = 15 \\times 23 + 7$, therefore the **floor division operator** returns the value $15$." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "w3HQ3fRHS3WE", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Besides making sure that you use the right operators when writing mathematical functions, it is also important that you pay attention to the order of operators. When not done right, this can cause huge changes in the outcome. Therefore, when writing out large equations it is easier to use parentheses or split it into multiple variables. e.g.:\n", + "\n", + "$$y = x\\tan\\theta - \\frac{1}{2v_0^2}\\frac{g x^2}{\\cos^2\\theta} + y_0$$\n", + "\n", + "You could split this equation into four distinct variables:\n", + "\n", + "1. var_1 $ = x\\tan\\theta$\n", + "2. var_2 $= \\frac{1}{2v_0^2}$\n", + "3. var_3 $= \\frac{g x^2}{\\cos^2\\theta}$\n", + "4. var_4 $= y_0$\n", + "\n", + "And then re-write it as ``y = var_1 - (var_2 * var_3) + var_4``" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "With parenthesis before = 18\n", + "With parenthesis after = 14\n" + ] + } + ], + "source": [ + "parenthesis_before = (2 + 4) * 3\n", + "print('With parenthesis before =',parenthesis_before)\n", + "parenthesis_after = 2 + (4 * 3)\n", + "print('With parenthesis after =',parenthesis_after)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "6vVTBKf2S3WF", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### Comparison Operators\n", + "\n", + "In Python, you often want to compare a value with another. For that, you use comparison operators.\n", + "\n", + "| Math sign | Python sign | Meaning |\n", + "| :-: | :-: | :-: |\n", + "| $=$ | ``==`` | Equal to |\n", + "| $>$ | ``>`` | Greater than |\n", + "| $>$ | ``<`` | Less than |\n", + "| $\\geqslant$ | ``>=`` | Greater than or equal to |\n", + "| $\\leqslant$ | ``<=`` | Less than or equal to |\n", + "| $\\neq$ | ``!=`` | Not equal to |" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "tYgJkAjkS3WF", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "#### Checking if a value corresponds to the set conditions\n", + "\n", + "Check if the the variable **`num`** satisfies the set condition." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "cwI6HOvCS3WF", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "8b6f1e68-f812-4758-b66c-8c1ece6e9885" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "num = 6\n", + "print(num > 2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "rahfXQevS3WG", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "If the value does not satisfy the condition the system will return False" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true, + "id": "n3-STHSWS3WG", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "6796f022-fc31-4a4c-cb2e-9242d0be0761" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], + "source": [ + "print(num > 7)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "k1fHyoR_S3WH", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "\n", + "### Logical & Identity Operators\n", + " \n", + " |sign|description|\n", + " |:-:|:-:|\n", + " |and|returns True if both statements are true|\n", + " |or|return True if at least 1 statements is true|\n", + " |not|reverse of the results; returns False if the statement is True|\n", + " |is|returns True if both variables are the same object|\n", + " |is not|returns True if both variables are not the same object|\n", + " |in|returns True if a sequence with the specified value is present in the object|\n", + " |in not|returns True if a sequence with the specified value is not present in the object|" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "z-vMNiI9S3WH", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "#### and statement\n", + "\n", + "By using the and statement you can set multiple conditions for the system to return. This can be seen as setting a boundary condition for a mathematical function." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": true, + "id": "C2nBS6w6S3WH", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "5ec763aa-a8d9-4a76-9442-c7d98a084b0e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "num = 5\n", + "print(num > 4 and num < 8)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "jFLv4WxVS3WH", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "#### checking if a value appears in an object\n", + "\n", + "Suppose we have a string \"sandstone\", we can check if a value is present within the string through the following lines of code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "y3hzxJlPS3WH", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "847bb1bc-e366-4e2d-e18a-7e08b54826b8" + }, + "outputs": [], + "source": [ + "rock_type = \"sandstone\"\n", + "print(\"sand\" in rock_type)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### is and == operators\n", + "\n", + "The is operator deserves a little more explanation since it can be easily confused with the == operator. The is statement does not compare the value of a variable but simply checks if two variables are the same object. On the other hand, == checks if the values of different variables are the same. In the underneath piece of code this is shown quite clearly. Although the values of the variables are the same, their type is not. Therefore, when compared using the is operator, it returns False." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " False\n", + "True\n" + ] + } + ], + "source": [ + "x = 2.0\n", + "y = 2\n", + "\n", + "print(type(x),type(y),x is y)\n", + "print(x == y)" + ] + }, + { + "cell_type": "markdown", + "id": "ccb91cbe", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\n", + "**Exercise**\n", + "\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "4eab3963", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "merged.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.11.5" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/book/01/Theory/01.ipynb b/book/basics/variables.ipynb similarity index 51% rename from book/01/Theory/01.ipynb rename to book/basics/variables.ipynb index c9fa375..5175a86 100644 --- a/book/01/Theory/01.ipynb +++ b/book/basics/variables.ipynb @@ -3,95 +3,7 @@ { "attachments": {}, "cell_type": "markdown", - "metadata": { - "id": "7vcVhbkFS81g", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "# 1. Variables, operators and functions. \n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "c0279304", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 1.1 First Python Script\n", - "\n", - "So, it is time for your first Python script. It is located beneath.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "3d1f70cf", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "ee5c28c1-473e-4c2d-9a33-b15b51fffc5f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello world!\n" - ] - } - ], - "source": [ - "# My First Python Script\n", - "message = 'Hello world!'\n", - "print(message)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "7a16f396", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "\n", - "`````{admonition} Let's break it down\n", - "\n", - "First line: # My First Python Script is a comment, which is used just to explain and/or put useful information about the code next to it. If you need to create a comment — just type a # symbol and write your text after it. The interpreter does nothing with it — the comments are there just as useful information for you or another reader.\n", - "\n", - "Second line: message = 'Hello world!' creates a variable called message and assigns the text literal (string) Hello world! to it, by using the operator = (equal sign). Variables are used to store all data you use in your code.\n", - "\n", - "Third line: print(message) calls the functionprint() and passes the variable message to it. A function is just a set of encapsulated code, which is tailored to perform a certain action. This specific function outputs the content of everything you pass to it. Since the variable message had a small line of text in it, the function print() outputs that message.\n", - "\n", - "This script is quite primitive and simple but it represents the main idea of programming in Python. You have data (which is stored in variables) and you perform an operation on it: by using the inbuilt print() function. In addition, you could create your own functions. \n", - "\n", - "`````" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", + "id": "d3bda27b", "metadata": { "id": "TcDyxZ7AS3Uz", "nbgrader": { @@ -101,7 +13,7 @@ } }, "source": [ - "## 1.2 Python Variables \n", + "# Python Variables \n", "\n", "One of the most powerful features of a programming language is the ability to create and manipulate\n", "variables. A variable is a labeled storage that refers to a value. They are usually used in a way to make the code more readable, allowing reusability of your code.

As it was mentioned previously, Python is a high-level programming language. For that, it uses concepts of Class and Object. In short, a Class is a defined model or a data structure, it describes how the data of that class can be described and how it can be manipulated, and an Object or Instance is its realization. In other words, think about your favorite meal: the recipe is the Class of your meal and when you decide to use the recipe and cook it — you create an Object of that Class. Variables are the way how objects are stored and processed.\n", @@ -123,6 +35,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "c96c7d6f", "metadata": { "id": "OLzFLmBnS3Uz", "nbgrader": { @@ -149,6 +62,7 @@ { "cell_type": "code", "execution_count": 2, + "id": "c92cf9b5", "metadata": { "collapsed": true, "id": "-oXjFB0TS3U0", @@ -166,6 +80,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "91acc4a0", "metadata": { "id": "loj_CSZ3S3U0", "nbgrader": { @@ -183,6 +98,7 @@ { "cell_type": "code", "execution_count": 3, + "id": "fbe8892d", "metadata": { "collapsed": true, "id": "-NydcpOmS3U0", @@ -212,6 +128,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "b46805d5", "metadata": { "id": "xPQ0wjwUS3U0", "nbgrader": { @@ -227,6 +144,7 @@ { "cell_type": "code", "execution_count": 2, + "id": "06b56dc7", "metadata": { "collapsed": true, "id": "q-fGZ0wMS3U0", @@ -253,6 +171,7 @@ { "cell_type": "code", "execution_count": 5, + "id": "bf1cbb92", "metadata": { "collapsed": true, "id": "d-6rzYcpS3U1", @@ -279,6 +198,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "69fb82fe", "metadata": { "id": "8CcorXSqS3U1", "nbgrader": { @@ -294,6 +214,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "8dd533b3", "metadata": { "id": "uqCmRVkbS3U1", "nbgrader": { @@ -309,6 +230,7 @@ { "cell_type": "code", "execution_count": 6, + "id": "e4eec9a4", "metadata": { "collapsed": true, "id": "QMktLeFOS3U2", @@ -338,6 +260,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "776cfb16", "metadata": { "id": "AjrlLAw7S3U2", "nbgrader": { @@ -353,6 +276,7 @@ { "cell_type": "code", "execution_count": 7, + "id": "30cae5d5", "metadata": { "collapsed": true, "id": "ho172OFAS3U2", @@ -370,6 +294,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "28a452f0", "metadata": { "id": "de87302a", "nbgrader": { @@ -388,6 +313,7 @@ { "cell_type": "code", "execution_count": 8, + "id": "48acc61b", "metadata": { "collapsed": true, "id": "tzz54psQS3U4", @@ -414,6 +340,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "b41ec95a", "metadata": { "id": "df4c695a", "nbgrader": { @@ -429,6 +356,7 @@ { "cell_type": "code", "execution_count": 9, + "id": "6808ada8", "metadata": { "collapsed": true, "id": "Sv2xzyhVS3U9", @@ -455,6 +383,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "925da5d8", "metadata": { "id": "gH1ebT4sS3VB", "nbgrader": { @@ -487,6 +416,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "abb0b8b6", "metadata": { "id": "87e243a7", "nbgrader": { @@ -502,6 +432,7 @@ { "cell_type": "code", "execution_count": 10, + "id": "5eb87d24", "metadata": { "collapsed": true, "id": "-DASPgHDS3VC", @@ -531,6 +462,7 @@ { "cell_type": "code", "execution_count": 11, + "id": "3d72cc72", "metadata": { "collapsed": true, "id": "151cff3a", @@ -561,6 +493,7 @@ { "cell_type": "code", "execution_count": 12, + "id": "20f7701a", "metadata": { "collapsed": true, "nbgrader": { @@ -588,6 +521,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "86ea9877", "metadata": { "nbgrader": { "grade": false, @@ -602,6 +536,7 @@ { "cell_type": "code", "execution_count": 13, + "id": "062d504b", "metadata": { "collapsed": true, "id": "ced9ae02", @@ -631,6 +566,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "2e0f2a7c", "metadata": { "id": "cbabd161", "nbgrader": { @@ -646,6 +582,7 @@ { "cell_type": "code", "execution_count": 14, + "id": "299ad533", "metadata": { "collapsed": true, "id": "6e138f75", @@ -684,6 +621,7 @@ { "cell_type": "code", "execution_count": 15, + "id": "f45bd312", "metadata": { "collapsed": true, "id": "4036bc6d", @@ -713,6 +651,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "0d9382ab", "metadata": { "id": "b358494d", "nbgrader": { @@ -728,6 +667,7 @@ { "cell_type": "code", "execution_count": 16, + "id": "5b5a621d", "metadata": { "collapsed": true, "id": "493e9703", @@ -757,6 +697,7 @@ { "cell_type": "code", "execution_count": 17, + "id": "31337e0d", "metadata": { "collapsed": true, "id": "9509e9ae", @@ -786,6 +727,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "f9e009e9", "metadata": { "id": "d378e554", "nbgrader": { @@ -801,6 +743,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "e68a979c", "metadata": { "id": "52be9a23", "nbgrader": { @@ -820,6 +763,7 @@ { "cell_type": "code", "execution_count": 18, + "id": "8996a258", "metadata": { "collapsed": true, "id": "00bd0987", @@ -849,6 +793,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "22086a55", "metadata": { "id": "7cc759c9", "nbgrader": { @@ -864,6 +809,7 @@ { "cell_type": "code", "execution_count": 19, + "id": "77741bfa", "metadata": { "collapsed": true, "id": "6f9dbc4a", @@ -893,6 +839,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "9223b088", "metadata": { "id": "27920277", "nbgrader": { @@ -908,6 +855,7 @@ { "cell_type": "code", "execution_count": 20, + "id": "4a4d5c55", "metadata": { "collapsed": true, "id": "11579009", @@ -938,6 +886,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "e2cd7ec3", "metadata": { "id": "5777fe12", "nbgrader": { @@ -953,6 +902,7 @@ { "cell_type": "code", "execution_count": 21, + "id": "07d03148", "metadata": { "collapsed": true, "id": "5a8eab89", @@ -982,6 +932,7 @@ { "cell_type": "code", "execution_count": 22, + "id": "0d7db87f", "metadata": { "collapsed": true, "id": "a2164ca2", @@ -1011,6 +962,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "1b859b5e", "metadata": { "id": "88633538", "nbgrader": { @@ -1032,6 +984,7 @@ { "cell_type": "code", "execution_count": 23, + "id": "cf2144a1", "metadata": { "collapsed": true, "id": "c65d21c0", @@ -1061,6 +1014,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "0a6fdb49", "metadata": { "id": "ac154077", "nbgrader": { @@ -1076,6 +1030,7 @@ { "cell_type": "code", "execution_count": 25, + "id": "3773b5db", "metadata": { "collapsed": true, "nbgrader": { @@ -1103,6 +1058,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "95ad1554", "metadata": { "id": "b5eea88c", "nbgrader": { @@ -1118,9 +1074,40 @@ "::: " ] }, + { + "cell_type": "markdown", + "id": "dcbb6e49", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\n", + "**Exercise**\n", + "\n", + "\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "8cf0a611", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\n", + "**Exercise**\n", + "\n", + "\n", + "\n", + "
" + ] + }, { "attachments": {}, "cell_type": "markdown", + "id": "fd31c2ab", "metadata": { "nbgrader": { "grade": false, @@ -1137,6 +1124,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "e091e555", "metadata": { "nbgrader": { "grade": false, @@ -1158,6 +1146,7 @@ { "cell_type": "code", "execution_count": 26, + "id": "16b74e70", "metadata": { "collapsed": true, "nbgrader": { @@ -1186,6 +1175,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "26d6b482", "metadata": { "nbgrader": { "grade": false, @@ -1200,6 +1190,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "58d5a940", "metadata": { "nbgrader": { "grade": false, @@ -1219,6 +1210,7 @@ { "cell_type": "code", "execution_count": 27, + "id": "aba28f0a", "metadata": { "collapsed": true, "nbgrader": { @@ -1248,6 +1240,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "840f08d9", "metadata": { "nbgrader": { "grade": false, @@ -1262,6 +1255,7 @@ { "cell_type": "code", "execution_count": 28, + "id": "8bff7ddd", "metadata": { "collapsed": true, "nbgrader": { @@ -1290,6 +1284,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "3aa8df9b", "metadata": { "nbgrader": { "grade": false, @@ -1304,6 +1299,7 @@ { "cell_type": "code", "execution_count": 29, + "id": "e4ad06cb", "metadata": { "collapsed": true, "nbgrader": { @@ -1331,6 +1327,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "be585912", "metadata": { "nbgrader": { "grade": false, @@ -1347,6 +1344,7 @@ { "cell_type": "code", "execution_count": 30, + "id": "8a21987c", "metadata": { "collapsed": true, "nbgrader": { @@ -1374,6 +1372,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "4dc22754", "metadata": { "nbgrader": { "grade": false, @@ -1388,6 +1387,7 @@ { "cell_type": "code", "execution_count": 31, + "id": "f3ad92dc", "metadata": { "collapsed": true, "nbgrader": { @@ -1415,6 +1415,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "68a02c78", "metadata": { "nbgrader": { "grade": false, @@ -1429,6 +1430,7 @@ { "attachments": {}, "cell_type": "markdown", + "id": "6a14cb55", "metadata": { "nbgrader": { "grade": false, @@ -1446,1108 +1448,6 @@ "Searching exercises are exercises that purposefully incorporate subjects that were not covered yet, in an attempt to encourage you to try and solve issues you haven't learned about yet.\n", ":::" ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "Tpeh8gLqS3V4", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 1.3 Python Operators\n", - "\n", - "Python operators are used to perform operations on variables and values. They are symbols that represent a form of computation; think of addition or multiplication. The value to which this computation is applied to is called the 'operand'. Most of the common operators you will recognize from mathematics." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "1yHso5KtS3WC", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "

Arithmetic Operators

\n", - "\n", - "| Math sign | Python sign | name |\n", - "| :-: | :-: |:-:|\n", - "| + | + | addition |\n", - "| - | - | subtraction |\n", - "| * | * | multiplication |\n", - "| / | / | division |\n", - "| ^ | ** | exponentiation |\n", - "| mod | % | modulus |\n", - "| | // | floor division |\n", - "\n", - "\n", - "
Most of the mathematical symbols stay the same when transforming a piece of mathematics to Python. Note that the exponentiation sign is a double multiplication sign!

\n", - "The last two operators, modulus and floor division, can be defined as the following:
\n", - "- modulus: return the remainder of a division
\n", - "- floor division: returns the integer/whole part of the division\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "Ijx03oCKS3WD", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now we will provide some small examples\n", - "\n", - "a. multiply 4 by 3 and then add 2\n", - "\n", - "b. 2 to the power of 4 plus 1\n", - "\n", - "c. take the modulus of 352 over 23\n", - "\n", - "d. the floor division of 352 over 23\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "wOPRR9oLS3WD", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "d888e6de-7185-453a-a33e-dc2f38817e9f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "14\n" - ] - } - ], - "source": [ - "a = 2 + 4 * 3\n", - "print(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "V50AuE4US3WD", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "d7518f7e-535f-4ea2-a233-06e71de779be" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "17\n" - ] - } - ], - "source": [ - "b = 2**4 + 1\n", - "print(b)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "a674y2ZoS3WE", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "2b8bfe90-f5db-40b7-beac-119d63142e3f" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7\n" - ] - } - ], - "source": [ - "c = 352 % 23\n", - "print(c)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Explanation: $352 = 15 \\times 23 + 7$, therefore the **modulus operator** returns the value $7$." - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "15\n" - ] - } - ], - "source": [ - "d = 352 // 23\n", - "print(d)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Explanation: $352 = 15 \\times 23 + 7$, therefore the **floor division operator** returns the value $15$." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "w3HQ3fRHS3WE", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Besides making sure that you use the right operators when writing mathematical functions, it is also important that you pay attention to the order of operators. When not done right, this can cause huge changes in the outcome. Therefore, when writing out large equations it is easier to use parentheses or split it into multiple variables. e.g.:\n", - "\n", - "$$y = x\\tan\\theta - \\frac{1}{2v_0^2}\\frac{g x^2}{\\cos^2\\theta} + y_0$$\n", - "\n", - "You could split this equation into four distinct variables:\n", - "\n", - "1. var_1 $ = x\\tan\\theta$\n", - "2. var_2 $= \\frac{1}{2v_0^2}$\n", - "3. var_3 $= \\frac{g x^2}{\\cos^2\\theta}$\n", - "4. var_4 $= y_0$\n", - "\n", - "And then re-write it as ``y = var_1 - (var_2 * var_3) + var_4``" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "With parenthesis before = 18\n", - "With parenthesis after = 14\n" - ] - } - ], - "source": [ - "parenthesis_before = (2 + 4) * 3\n", - "print('With parenthesis before =',parenthesis_before)\n", - "parenthesis_after = 2 + (4 * 3)\n", - "print('With parenthesis after =',parenthesis_after)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "6vVTBKf2S3WF", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Comparison Operators\n", - "\n", - "In Python, you often want to compare a value with another. For that, you use comparison operators.\n", - "\n", - "| Math sign | Python sign | Meaning |\n", - "| :-: | :-: | :-: |\n", - "| $=$ | ``==`` | Equal to |\n", - "| $>$ | ``>`` | Greater than |\n", - "| $>$ | ``<`` | Less than |\n", - "| $\\geqslant$ | ``>=`` | Greater than or equal to |\n", - "| $\\leqslant$ | ``<=`` | Less than or equal to |\n", - "| $\\neq$ | ``!=`` | Not equal to |" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "tYgJkAjkS3WF", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "#### Checking if a value corresponds to the set conditions\n", - "\n", - "Check if the the variable **`num`** satisfies the set condition." - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "collapsed": true, - "id": "cwI6HOvCS3WF", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "8b6f1e68-f812-4758-b66c-8c1ece6e9885" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "num = 6\n", - "print(num > 2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "rahfXQevS3WG", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "If the value does not satisfy the condition the system will return False" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "collapsed": true, - "id": "n3-STHSWS3WG", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "6796f022-fc31-4a4c-cb2e-9242d0be0761" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n" - ] - } - ], - "source": [ - "print(num > 7)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "k1fHyoR_S3WH", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "\n", - "### Logical & Identity Operators\n", - " \n", - " |sign|description|\n", - " |:-:|:-:|\n", - " |and|returns True if both statements are true|\n", - " |or|return True if at least 1 statements is true|\n", - " |not|reverse of the results; returns False if the statement is True|\n", - " |is|returns True if both variables are the same object|\n", - " |is not|returns True if both variables are not the same object|\n", - " |in|returns True if a sequence with the specified value is present in the object|\n", - " |in not|returns True if a sequence with the specified value is not present in the object|" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "z-vMNiI9S3WH", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "#### and statement\n", - "\n", - "By using the and statement you can set multiple conditions for the system to return. This can be seen as setting a boundary condition for a mathematical function." - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": true, - "id": "C2nBS6w6S3WH", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "5ec763aa-a8d9-4a76-9442-c7d98a084b0e" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True\n" - ] - } - ], - "source": [ - "num = 5\n", - "print(num > 4 and num < 8)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "jFLv4WxVS3WH", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "#### checking if a value appears in an object\n", - "\n", - "Suppose we have a string \"sandstone\", we can check if a value is present within the string through the following lines of code." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true, - "id": "y3hzxJlPS3WH", - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - }, - "outputId": "847bb1bc-e366-4e2d-e18a-7e08b54826b8" - }, - "outputs": [], - "source": [ - "rock_type = \"sandstone\"\n", - "print(\"sand\" in rock_type)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### is and == operators\n", - "\n", - "The is operator deserves a little more explanation since it can be easily confused with the == operator. The is statement does not compare the value of a variable but simply checks if two variables are the same object. On the other hand, == checks if the values of different variables are the same. In the underneath piece of code this is shown quite clearly. Although the values of the variables are the same, their type is not. Therefore, when compared using the is operator, it returns False." - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " False\n", - "True\n" - ] - } - ], - "source": [ - "x = 2.0\n", - "y = 2\n", - "\n", - "print(type(x),type(y),x is y)\n", - "print(x == y)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## 1.4 Python Functions\n", - "\n", - "A function is a collection of code that is assigned to a specific name. You have already seen some built-in Python functions, such as print(). Using functions is useful because it allows you to run the same code again without having to type it a second time.\n", - "\n", - "Below are some examples of common built-in Python functions and what they do:\n", - "\n", - "\n", - "* ``print()``: Prints input to screen\n", - "* ``type()``: Returns the type of the input\n", - "* ``abs()``: Returns the absolute value of the input\n", - "* ``min()``: Returns the minimum value of the input. (input could be a list, tuple, etc.)\n", - "* ``max()``: Same as above, but returns the maximum value\n", - "* ``sum()``: Returns the sum of the input (input could be a list, tuple, etc.)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "But the story doesn't end at built-in functions. You can also write your own functions!\n", - "\n", - "### How to write a function\n", - "\n", - "To write a function, you must first define it. This is done by using the def statement. Then, you name the function and add, in the parentheses, which variables this function takes as an input, followed by a colon. The colon tells Python you are going to define the function body next (the part of the function that actually does the computation). As shown below:

\n", - "\n", - "
def function_name(input1, input2,...):
function_body
...
...
\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "242bb5c2", - "metadata": {}, - "source": [ - "\n", - "The calculate_circle_area(r) function below defines pi as a variable and then computes the area of a circle, which is stored in the variable area. Finally, it uses the return statement to output the area back to you. Once you have defined the function, you can then call it by typing the function name, and the inputs in the parenthesis. For example, calling: print(\"Hello World!\"), prints the string \"Hello World!\".\n", - "\n", - "Indentation
\n", - "\n", - "It is worth noting that the function body should be indented. This is how Python sees what piece of code is inside another code. An indented line of code is a line that starts with whitespace. You can do this by using the tab key on your keyboard." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "::: {note}\n", - "Inputs of functions are more often called arguments.\n", - ":::" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### indentation of code within functions\n", - "\n", - "Let's say you'd want to compute the area of a circle, but you don't want to calculate $\\pi r^2$ the entire time. Then you can write a couple lines of code to do it for you, and wrap it up into a function, like the one below:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [], - "source": [ - "def calculate_circle_area(r):\n", - " pi = 3.141592653589793\n", - " area = pi*(r**2)\n", - " return area" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "This function is called calculate_circle_area(r), and takes the value r as an argument." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Functions can have multiple arguments, for example:" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Area of my rectangle is 24 cm^2\n" - ] - } - ], - "source": [ - "def calculate_rectangle_area(a, b):\n", - " area = a * b\n", - " return area\n", - "\n", - "print('Area of my rectangle is', calculate_rectangle_area(4, 6), 'cm^2')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "In the cell above, the **`calculate_rectangle_area(a, b)`** function takes $2$ arguments, $a$ and $b$. \n", - "\n", - "The built-in function **`print()`** takes $3$ arguments:
\n", - "the string 'Area of my rectangle is', the output of calculate_rectangle_area(a, b), and another string 'cm^2'.\n", - "\n", - "There are better ways to use the built-in print() function when writing long sentences that have variables in between. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Area of my rectangle is 24 cm^2 and the area of my circle is 50.26548245743669 cm^2\n" - ] - } - ], - "source": [ - "print('Area of my rectangle is {} cm^2 and the area of my circle is {} cm^2'. \\\n", - " format(calculate_rectangle_area(4,6), calculate_circle_area(4)))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "If a line in your code extends the width of your page, you can use a **\\\\** at the point where you want to break the line, as shown above.\n", - "\n", - "Note that the variables (separated by commas) called inside the .format() will appear, in order, where the { } are located.\n", - "\n", - "Furthermore, you can also format how you want the numbers to appear, as shown below:" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Area of my rectangle is 24.00000 cm^2 and the area of my circle is 50.27 cm^2\n" - ] - } - ], - "source": [ - "print('Area of my rectangle is {:.5f} cm^2 and the area of my circle is {:.2f} cm^2'. \\\n", - " format(calculate_rectangle_area(4,6), calculate_circle_area(4)))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Where the :.5f states that you want to print that variable with $5$ decimal numbers. Similarly, :.2f rounds the number to $2$ decimal numbers. More information on this in Section 3.1, in Notebook 3." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### Documenting functions\n", - "We have now successfully created a function that computes the area of a circle and the area of a rectangle. You could send this code to fellow students, but maybe they wouldn't know how to use them. This is where a docstring comes in handy. This is a string specified in the beginning of the function body which states information about the function. A lot of built-in Python functions also have docstrings, which is really useful when you're trying to understand how to use a function." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Add a description to the calculate_circle_area(r) function below, as a docstring.
" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": false, - "solution": false - } - }, - "outputs": [], - "source": [ - "def calculate_circle_area(r):\n", - " '''This function calculate the area of a circle with radius r '''\n", - " pi_circle = 3.141592653589793\n", - " area = pi_circle*(r**2)\n", - " return area" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "As you can see, nothing happened. But, if we now call the function like this:\n", - "```\n", - "calculate_circle_area?\n", - "```\n", - "or:\n", - "```\n", - "help(calculate_circle_area)\n", - "```\n", - "we should see the description (docstring) of the function. Try yourself below:" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Help on function calculate_circle_area in module __main__:\n", - "\n", - "calculate_circle_area(r)\n", - " This function calculate the area of a circle with radius r\n", - "\n" - ] - } - ], - "source": [ - "help(calculate_circle_area)\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Now this isn't of much use when you work on your own code, unless you are very forgetful or have to write large programs.\n", - "But if you work using other people's code, this is really useful, as it helps you figure out how to use each function." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "#### When to write or use a function?\n", - "\n", - "You can use functions in your code when you have a specific piece of code that you need to use multiple times (e.g.: plotting something).

Often you will find you want to use an output from a function later on. To do this, you can assign a function to a variable. Let's say I want to use the area of a circle in a later calculation. Then you can store it in a variable like this:\n", - "\n", - "We stored the area of a circle that has a radius 4 in the variable ``Circle_Area``" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [], - "source": [ - "Circle_Area = calculate_circle_area(4)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Nothing happens, but the value of calculate_circle_area(4) is now stored in the variable Circle_Area. See below:" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "50.26548245743669\n" - ] - } - ], - "source": [ - "print(Circle_Area)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "We can see that the value was indeed stored.\n", - "\n", - "::: {warning}\n", - "Variables that are defined inside a function body can NOT be called from outside of the function. These variables are called local variables.\n", - ":::" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "Take the variable **`pi_circle`** that we defined in the function **`calculate_circle_area()`**. If we try to print it:" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": { - "collapsed": true, - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'pi_circle' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[52], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mprint\u001b[39m(pi_circle)\n", - "\u001b[1;31mNameError\u001b[0m: name 'pi_circle' is not defined" - ] - } - ], - "source": [ - "print(pi_circle)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "See, it doesn't work!\n", - "The error you get: NameError: name 'pi_circle' is not defined, means that you tried to call a variable that does not exist." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "## Additional study material:\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/introduction.html\n", - "* https://realpython.com/python-variables/\n", - "* Think Python (2nd ed.) - Section 2\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/library/operator.html\n", - "* https://realpython.com/python-operators-expressions/\n", - "* Think Python (2nd ed.) - Sections 2 and 5\n", - "\n", - "* Official Python Documentation - https://docs.python.org/3/tutorial/controlflow.html#defining-functions\n", - "* https://realpython.com/defining-your-own-python-function/\n", - "* Think Python (2nd ed.) - Sections 3, 6 and 16" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "nbgrader": { - "grade": false, - "locked": true, - "solution": false - } - }, - "source": [ - "### After this Notebook you should be able to:\n", - "\n", - "- understand why you need to learn Python\n", - "- create and re-assign new variables\n", - "- determine the type of a variable using `type()`\n", - "- slice strings\n", - "- perform simple math using arithmetic operators\n", - "- compare two or more variables\n", - "- check if a value, or element, exists in an object\n", - "- define a function, including its docstring" - ] } ], "metadata": { diff --git a/book/beyond.md b/book/beyond.md new file mode 100644 index 0000000..0e8304f --- /dev/null +++ b/book/beyond.md @@ -0,0 +1,6 @@ +# Beyond the Basics + +This chapter extends some of the topics we have covered in previous chapters, for example: strings, functions, while adding a new topic about working with files. + +% a short overview for this chapter + diff --git a/book/03/Exercises/01.ipynb b/book/beyond/Exercises/01.ipynb similarity index 100% rename from book/03/Exercises/01.ipynb rename to book/beyond/Exercises/01.ipynb diff --git a/book/beyond/files.ipynb b/book/beyond/files.ipynb new file mode 100644 index 0000000..779bad2 --- /dev/null +++ b/book/beyond/files.ipynb @@ -0,0 +1,321 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Beyond the Basics: Working with Files\n", + "\n", + "A lot of the work you'll do in Python will have the following structure:\n", + "1. Read data from a file\n", + "2. Perform computations on the data\n", + "3. Visualize the results and/or save the results to a file\n", + "\n", + "So far, we have only learned about computations. So let's learn a bit about how to manage files. Actually, opening or saving files is usually done with the help of modules which you will learn in more detail in Notebook 4 and 6. What we'll discuss here is how to manage file paths.\n", + "\n", + "### File paths\n", + "\n", + "To learn how to use files we need to learn how file paths in computers work. If you are tech-savvy and know how file paths work you can skip this part.\n", + "\n", + "File paths in computers work like a tree. They start at the root directory, which is often the C: drive (in Windows). This is the name of the hard drive that stores your Operating System. From the C: drive you can navigate into other directories. This is done using the **``\\``** character, however in other Operating Systems often the / delimiter is used.\n", + "\n", + "If a file is in the folder Users, which is stored in the C: directory, the file path would be C:\\Users. These types of file paths are called absolute paths. This file path is valid for most computers that run Windows, but some other Operating Systems may have different folder setups. This is why it is useful to use relative paths. Relative paths do not start from the root directory. Instead, they start from the directory you are currently in. By default, Jupyter Notebooks are stored in C:\\Users\\CurrentUser (where CurrentUser is your Windows username). To move into a directory using a relative path, for example, to the desktop folder, you would just write .\\Desktop. To move back a directory, using a relative path, you would type ..\n", + "\n", + "`os.listdir()` or `os.listdir('./')` list all the entries in your current directory `os.listdir('../')` list all entries if we go back one level. \n", + "\n", + ":::{note}\n", + "We use the `/` as delimiter, since a `\\` won't work on macOS\n", + ":::" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['01.ipynb']\n", + "['01.ipynb']\n", + "['Exercises', 'In_a_Nutshell', 'Theory']\n" + ] + } + ], + "source": [ + "import os\n", + "\n", + "print(os.listdir())\n", + "print(os.listdir('./'))\n", + "\n", + "print(os.listdir('../'))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + ":::{warning}\n", + "Keep in mind that, in Python, all file paths must be strings!\n", + ":::" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### ``pathlib`` and os modules\n", + "\n", + "These modules are very useful in managing and navigating your file paths. The function path.expanduser('~'), from the os module, allows you to find your root directory, independent of your Operating System. Try the below cell to see it." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "C:\\Users\\mmendozalugo\n" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "import os\n", + "\n", + "root_path = os.path.expanduser('~')\n", + "print(root_path)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "The path shown above is thus the absolute path to your current directory.\n", + "\n", + "This can come in handy when you write a code that needs to create directories in the user's computer to save data files and/or plots. As an example, the code below checks if a directory exists and, if it doesn't, it creates one.\n", + "\n", + "The `os.path.join` is used to concatenate two strings to form a path string with the appropriate delimiter.\n", + "\n", + "The code will check if a directory named `plots` exists in your current directory if not, it will create one." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print('Contents of current directory (before):')\n", + "print(os.listdir(root_path))\n", + "\n", + "imdir = os.path.join(root_path,'plots') \n", + "print(f'\\nimdir = {imdir}')\n", + "\n", + "Path(imdir).mkdir(parents=True, exist_ok=True)\n", + "\n", + "print('\\nContents of current directory (after creating the new directory):')\n", + "print(os.listdir(root_path))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "tags": [ + "remove-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Contents of current directory (before):\n", + "['Exercises', 'In_a_Nutshell', 'Theory']\n", + "imdir = C:\\Users\\mmendozalugo\\plots\n", + "\n", + "Contents of current directory (after creating the new directory):\n", + "['Exercises', 'In_a_Nutshell', 'plots', 'Theory']\n" + ] + } + ], + "source": [ + "root_path = r'C:\\Users\\mmendozalugo\\OneDrive\\PhD\\Work\\Python_MOOC\\PM\\learn-python\\book\\03'\n", + "\n", + "print('Contents of current directory (before):')\n", + "print(os.listdir(root_path))\n", + "\n", + "imdir = os.path.join(root_path,'plots') \n", + "print('imdir = ',r'C:\\Users\\mmendozalugo\\plots')\n", + "\n", + "Path(imdir).mkdir(parents=True, exist_ok=True)\n", + "\n", + "print('\\nContents of current directory (after creating the new directory):')\n", + "print(os.listdir(root_path))\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To delete the folder that was just created we run the code bellow." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " os.rmdir(imdir)\n", + " print(f'Directory {imdir} has been deleted.')\n", + "except:\n", + " print('You already deleted the folder. :)')" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "tags": [ + "remove-input" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Directory C:\\Users\\mmendozalugo\\plots has been deleted.\n" + ] + } + ], + "source": [ + "print('Directory', r'C:\\Users\\mmendozalugo\\plots','has been deleted.')\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now you are, hopefully, a bit more used to working with file paths. For the next test, we are going to try to open a file. We can use some built-in Python functions to open a *.txt file and print its contents." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Additional study material\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/tutorial/inputoutput.html\n", + "* https://realpython.com/python-f-strings/\n", + "* Official Python Documentation - https://docs.python.org/3/reference/expressions.html\n", + "* https://realpython.com/python-lambda/\n", + "* Official Python Documentation - https://docs.python.org/3/library/filesys.html\n", + "* https://realpython.com/working-with-files-in-python/\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "After this Notebook you should be able to:\n", + "\n", + "- print a variable, formatting it in an appropriate manner\n", + "- know the existence of escape characters\n", + "- know how to use lambda functions\n", + "- understand how file paths work\n", + "- create and delete new directories \n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/beyond/functions.ipynb b/book/beyond/functions.ipynb new file mode 100644 index 0000000..85ed334 --- /dev/null +++ b/book/beyond/functions.ipynb @@ -0,0 +1,106 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Beyond the Basics: Functions\n", + "\n", + "Sometimes you want to use the same code multiple times, so you could embed this code into a function. However, sometimes the code you want to use is so short that putting it into a function feels a bit over the top. This is where lambda functions are useful.

Lambda functions are functions that can take any number of arguments but can only have one expression in their function body. To demonstrate, see the code below. Here we have two functions that do exactly the same, but one is a lambda function and the other one is a normal function. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The square root of 16 is equal to 4\n", + "The square root of 16 is equal to 4\n" + ] + } + ], + "source": [ + "sqrt_lambda = lambda x : x**0.5\n", + "\n", + "def sqrt(x):\n", + " sqrt = x**0.5\n", + " return sqrt\n", + "\n", + "print(f\"The square root of 16 is equal to {sqrt_lambda(16):.0f}\")\n", + "print(f\"The square root of 16 is equal to {sqrt(16):.0f}\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "
\n", + "As you can see, the lambda version is much more concise. It automatically returns the computed value for you as well." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/beyond/nutshell.md b/book/beyond/nutshell.md new file mode 100644 index 0000000..faeb78a --- /dev/null +++ b/book/beyond/nutshell.md @@ -0,0 +1,3 @@ +# Advanced Techniques: in a Nutshell + +Nutshell. \ No newline at end of file diff --git a/book/beyond/nutshell/files.ipynb b/book/beyond/nutshell/files.ipynb new file mode 100644 index 0000000..9066e50 --- /dev/null +++ b/book/beyond/nutshell/files.ipynb @@ -0,0 +1,134 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Beyond the Basics: Working with Files\n", + "\n", + "A lot of the work you'll do in Python will have the following structure:\n", + "1. Read data from a file\n", + "2. Perform computations on the data\n", + "3. Visualize the results and/or save the results to a file" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### File paths\n", + "File paths on computers work based on a hierarchical structure, often represented as a tree. The root directory serves as the starting point, typically represented by a drive letter (e.g., C: on Windows). From the root directory, you can navigate to other directories using a delimiter character (\\ on Windows or / on Unix-based systems). Each directory can contain files and subdirectories, forming a hierarchical structure.\n", + "\n", + "Absolute paths specify the complete path from the root directory, while relative paths are relative to the current working directory. By understanding and manipulating file paths, you can effectively locate and access files and directories on a computer's file system." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ``pathlib`` and os modules\n", + "\n", + "The os module in Python provides functions for interacting with the operating system, offering operations related to file management, directory handling, process management, and environment variables. It allows you to perform tasks such as creating, deleting, and modifying files and directories, launching external processes, accessing and modifying environment variables, and writing platform-independent code.\n", + "\n", + "On the other hand, the pathlib module introduced in Python 3.4 offers an object-oriented approach to working with file paths and directories. It provides the Path class, which represents paths as objects, allowing for more intuitive and expressive manipulation of paths compared to the traditional string-based operations in os. With pathlib, you can perform operations like joining paths, checking file existence, accessing file attributes, and creating directories in a more convenient and readable manner.\n", + "\n", + "The table below summuraizes some codes you can use for creating and adjusting your own file paths:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| Code | Result | Description |\n", + "|------|--------|-------------|\n", + "| `os.path.join(path, *paths)` | Path string | Joins one or more path components intelligently. It concatenates the arguments using the appropriate path delimiter for the operating system. |\n", + "| `os.path.abspath(path)` | Absolute path string | Returns the absolute path of the specified path. It resolves any symbolic links and references to parent directories. |\n", + "| `os.path.exists(path)` | Boolean | Checks if the specified path exists in the file system. Returns `True` if the path exists, and `False` otherwise. |\n", + "| `os.path.isdir(path)` | Boolean | Checks if the specified path is a directory. Returns `True` if the path is a directory, and `False` otherwise. |\n", + "| `os.path.isfile(path)` | Boolean | Checks if the specified path is a regular file. Returns `True` if the path is a file, and `False` otherwise. |\n", + "| `os.path.splitext(path)` | Tuple (base, ext) | Splits the specified path into its base name and extension. Returns a tuple where the first element is the base name and the second element is the extension (including the dot). |\n", + "| `os.path.basename(path)` | Base name string | Returns the base name (the file or directory name) from the specified path. |\n", + "| `os.path.dirname(path)` | Directory name string | Returns the directory name from the specified path. |\n", + "\n", + "Here are some examples of how to use these codes: " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Path: folder\\subfolder\\file.txt\n", + "Absolute Path: c:\\Users\\ahmed\\Documents\\GitHub\\learn-python\\book\\03\\In_a_Nutshell\\folder\\subfolder\\file.txt\n", + "Exists: False\n", + "Is Directory: False\n", + "Is File: False\n", + "Base Name: file.txt\n", + "Directory Name: folder\\subfolder\n", + "Extension: .txt\n" + ] + } + ], + "source": [ + "import os\n", + "\n", + "path = os.path.join('folder', 'subfolder', 'file.txt') # Joining path components intelligently using appropriate delimiter.\n", + "absolute_path = os.path.abspath(path) # Getting the absolute path of the specified path.\n", + "exists = os.path.exists(path) # Checking if the specified path exists.\n", + "is_directory = os.path.isdir(path) # Checking if the specified path is a directory.\n", + "is_file = os.path.isfile(path) # Checking if the specified path is a file.\n", + "base_name, extension = os.path.splitext(path) # Splitting the path into base name and extension.\n", + "basename = os.path.basename(path) # Getting the base name (file or directory name) from the path.\n", + "dirname = os.path.dirname(path) # Getting the directory name from the path.\n", + "\n", + "# Printing the information\n", + "print(\"Path:\", path) # Path string\n", + "print(\"Absolute Path:\", absolute_path) # Absolute path string\n", + "print(\"Exists:\", exists) # Boolean indicating if path exists\n", + "print(\"Is Directory:\", is_directory) # Boolean indicating if path is a directory\n", + "print(\"Is File:\", is_file) # Boolean indicating if path is a file\n", + "print(\"Base Name:\", basename) # Base name of the file or directory\n", + "print(\"Directory Name:\", dirname) # Directory name of the path\n", + "print(\"Extension:\", extension) # File extension with the dot\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This code demonstrates the usage of various os.path functions to perform operations on file paths, such as joining paths, obtaining absolute paths, checking existence, identifying directories or files, splitting paths into base names and extensions, and retrieving the base name and directory name from a path. The corresponding outputs are displayed to provide the relevant information." + ] + } + ], + "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.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/beyond/nutshell/functions.ipynb b/book/beyond/nutshell/functions.ipynb new file mode 100644 index 0000000..f126b2d --- /dev/null +++ b/book/beyond/nutshell/functions.ipynb @@ -0,0 +1,87 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Beyond the Basics: Functions\n", + "\n", + "An example of an advanced fuction can be the lambda function. It is an anonymous function in Python that can be defined in a single line using the lambda keyword. It is typically used for simple and concise operations without the need for a formal function definition.\n", + "\n", + "Here's an example that showcases the difference between lambda functions and normal functions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from math import pi \n", + "import os " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n", + "12\n" + ] + } + ], + "source": [ + "# Normal function\n", + "def multiply(x, y):\n", + " return x * y\n", + "\n", + "result = multiply(3, 4)\n", + "print(result) # Output: 12\n", + "\n", + "# Lambda function\n", + "multiply_lambda = lambda x, y: x * y\n", + "\n", + "result_lambda = multiply_lambda(3, 4)\n", + "print(result_lambda) # Output: 12\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both the normal function and the lambda function are used to multiply 3 and 4. The results obtained from both approaches are identical (12). The key difference is that the normal function is defined with the def keyword, whereas the lambda function is defined using the lambda keyword without a formal function name.\n", + "\n", + "lambda functions are particularly useful in scenarios where a small, one-time function is needed without the need for a full function definition and name." + ] + } + ], + "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.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/beyond/nutshell/strings.ipynb b/book/beyond/nutshell/strings.ipynb new file mode 100644 index 0000000..467e354 --- /dev/null +++ b/book/beyond/nutshell/strings.ipynb @@ -0,0 +1,167 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Beyond the Basics: Strings\n", + "In Python, strings are created using quotes ('' or \"\") and are immutable, while f-strings are formatted strings that allow embedding expressions inside curly braces { } for dynamic value substitution during runtime. Here is a couple of examples for strings:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from math import pi \n", + "import os " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Alice 25 engineer\n" + ] + } + ], + "source": [ + "name = \"Alice\"\n", + "age = 25\n", + "profession = \"engineer\"\n", + "\n", + "print (name,age,profession)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is the same example made as a complete sentence using f-strings. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "My name is Alice, I'm 25 years old, and I work as an engineer.\n" + ] + } + ], + "source": [ + "intro = f\"My name is {name}, I'm {age} years old, and I work as an {profession}.\"\n", + "\n", + "print (intro)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Formatting numbers\n", + "Python's f-strings provide a convenient way to format numbers by using the colon character and specifying the desired format. The following table demonstrates a couple of examples with the number $1$ using f-strings:

\n", + "\n", + "| Code | Result|\n", + "|------|------|\n", + "| 1:.2f | 1.00|\n", + "| 1:.0f| 1|\n", + "| 1:.10f| 1.0000000000 | \n", + "| 1:%| 100.000000%|\n", + "| 1:.1%| 100.0% |\n", + "| 1:e| 1.000000e+00 |" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the example below, the sleep() function from the time module is used to simulate the passage of time and provide a simple demonstration of a progress bar implementation. We define a function simulate_long_running_algorithm() that performs a loop with a sleep of 0.5 seconds between iterations. Within each iteration, the progress of the algorithm is calculated and used to construct a progress bar string. The progress bar consists of a series of equal signs (=) that visually represent the progress, followed by the percentage completion formatted to one decimal defined inside an f-strings." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[====================] 100.0%\n", + "Algorithm complete!\n" + ] + } + ], + "source": [ + "import time\n", + "\n", + "def simulate_long_running_algorithm():\n", + " total_iterations = 10\n", + " for i in range(total_iterations):\n", + " time.sleep(0.5) # Simulating processing time\n", + " progress = (i + 1) / total_iterations\n", + " progress_bar = f\"[{'=' * int(progress * 20):20s}] {progress * 100:.1f}%\"\n", + " print(progress_bar, end='\\r') # Print on the same line\n", + " print(\"\\nAlgorithm complete!\")\n", + "\n", + "simulate_long_running_algorithm()\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Escape characters

\n", + "\n", + "Escape characters in programming are special characters that are used to represent certain non-printable or special characters within strings. They are typically represented by a backslash (' \\ ') followed by a specific character or sequence. We used two escape characters in the previous example, can you identify them?\n", + "\n", + "| Code | Result| Description |\n", + "|------|------|------ |\n", + "| \\\\' | ' | represents the escape sequence for a single quote (').|\n", + "| \\\\\\ | \\\\ | represents the escape sequence for a backslash (' \\ ').|\n", + "| \\\\n | new line| represents the escape sequence for a new line character, which moves the cursor to the beginning of the next line. | \n", + "| \\\\r | carriage return | represents the escape sequence for a carriage return character, which moves the cursor to the beginning of the current line.|\n", + "| \\\\t | tab |represents the escape sequence for a tab character, which adds horizontal spacing. |\n", + "| \\\\b | backspace | represents the escape sequence for a backspace character, which moves the cursor one position back. |" + ] + } + ], + "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.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/beyond/strings.ipynb b/book/beyond/strings.ipynb new file mode 100644 index 0000000..2bba6e1 --- /dev/null +++ b/book/beyond/strings.ipynb @@ -0,0 +1,355 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Beyond the Basics: Strings\n", + "\n", + "Welcome to the third Notebook. In this Notebook we are going to learn some advanced Python. Let's first start with strings. Run the code below and see what it prints out." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from math import pi \n", + "import os " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This is an F-String\n", + "This is a string\n" + ] + } + ], + "source": [ + "MyFString = f\"This is an F-String\"\n", + "MyString = \"This is a string\"\n", + "print(MyFString)\n", + "print(MyString)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "\n", + "Now let's try inserting some data into our print() function. We'll use the list of integers [1,2,3,4]. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data1: 1, Data2: 2, Data3: 3, Data4: 4\n", + "Data1: 1 ,Data2: 2 ,Data3: 3 ,Data4: 4\n" + ] + } + ], + "source": [ + "Data = [1,2,3,4]\n", + "\n", + "MyFString = f\"Data1: {Data[0]}, Data2: {Data[1]}, Data3: {Data[2]}, Data4: {Data[3]}\"\n", + "\n", + "print(MyFString)\n", + "print(\"Data1:\",Data[0],\",Data2:\",Data[1],\",Data3:\",Data[2],\",Data4:\",Data[3])" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see from the above code, it is much easier to insert variables in a string by using an f-string (formatted string)." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### Formatting numbers\n", + "\n", + "Using f-strings makes formatting numbers really easy. Just add a colon character after a number value and specify how you want to format the number. The following table demonstrates a couple of examples with the number $1$:

\n", + "\n", + "| Code | Result|\n", + "|------|------|\n", + "| 1:.2f | 1.00|\n", + "| 1:.0f| 1|\n", + "| 1:.10f| 1.0000000000 | \n", + "| 1:%| 100.000000%|\n", + "| 1:.1%| 100.0% |\n", + "| 1:e| 1.000000e+00 |\n", + "\n", + "As you can see the default number of decimal places is six. Furthermore, the % formatting operator assumes that $1$ is equal to $100$%, which is usual when working with fractions, and the formatting operator e formats using scientific notation." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now let's use our newfound knowledge of strings to make a simple progress bar. During other courses, you'll sometimes have to write algorithms that take a long time to run. In this case, it is useful to have a progress bar. Our example of a progress bar makes use of the sleep() function, from the time module, to simulate elapsed time." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading: 0%\n", + "Loading: 10%\n", + "Loading: 20%\n", + "Loading: 30%\n", + "Loading: 40%\n", + "Loading: 50%\n", + "Loading: 60%\n", + "Loading: 70%\n", + "Loading: 80%\n", + "Loading: 90%\n", + "Loading: 100%\n" + ] + } + ], + "source": [ + "import time\n", + "\n", + "for i in range(11):\n", + " print(f\"Loading: {i*10}%\", )\n", + " time.sleep(0.5) " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "This works! Though it is not that pretty to look at. It would look nicer to not have it print a new line each time. This is where escape characters come in. These characters can do some special things in strings. Below an example of some escape characters:\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "

Escape characters

\n", + "\n", + "| Code | Result|\n", + "|------|------|\n", + "| \\\\' | ' |\n", + "| \\\\\\ | \\\\ |\n", + "| \\\\n | new line| \n", + "| \\\\r | carriage return |\n", + "| \\\\t | tab |\n", + "| \\\\b | backspace |\n", + "\n", + "We can use some of these characters in our code. Let's use the carriage return character to make our progress bar not print out a new line every time. We can do this by adding end=\"\\r\" into our print function. The end keyword specifies a string that gets printed at the end. The string we print at the end here is the carriage return character. This carriage resets the print function to the start of the line; thus making the next print function overwrite the current printed line. Try it and see what happens:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This is a very important message\n" + ] + } + ], + "source": [ + "print(\"Will I get overwritten?\", end=\"\\r\")\n", + "print(\"This is a very important message\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now let's add this to our progress bar... " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading complete!\n" + ] + } + ], + "source": [ + "import time\n", + "for i in range(11):\n", + " print(f\"Loading: {i*10}%\", end=\"\\r\")\n", + " time.sleep(0.5) \n", + "print(\"Loading complete!\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, it works beautifully!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/flow.md b/book/flow.md new file mode 100644 index 0000000..f55b3ab --- /dev/null +++ b/book/flow.md @@ -0,0 +1,6 @@ +# Flow + +This chapter is all about ... + +% a short overview for this chapter + diff --git a/book/02/Exercises/01.ipynb b/book/flow/Exercises/01.ipynb similarity index 100% rename from book/02/Exercises/01.ipynb rename to book/flow/Exercises/01.ipynb diff --git a/book/02/Exercises/01.json b/book/flow/Exercises/01.json similarity index 100% rename from book/02/Exercises/01.json rename to book/flow/Exercises/01.json diff --git a/book/flow/conditions.ipynb b/book/flow/conditions.ipynb new file mode 100644 index 0000000..881eb18 --- /dev/null +++ b/book/flow/conditions.ipynb @@ -0,0 +1,767 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "fHmKWsUSKuj4", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Conditions and if statements\n", + "\n", + "In previous Sections you have learned how to create variables, alter them with the help of operators and access the code of professional software developers/scientists. With this, you can already do plenty of stuff in Python. However, it still lacks versatility. If you want to apply other processing techniques for other data — you would need to manually rewrite your code and then change it back once the data changes again. Not that handy, right?

In this Section you will learn how to steer the flow of your code — process data differently based on some conditions. For that you will learn a construction called the if statement.\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "oyr90lgAQGtD", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "## if keyword\n", + "\n", + "The if statement in Python is similar to how we use it in English. \"If I have apples, I can make an apple pie\" — clearly states that an apple pie will exist under the condition of you having apples. Otherwise, no pie.

\n", + "Well, it is the same in Python:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "QGXlz9tvM56U", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "63cc3e01-7c4c-4829-d4b2-9ae08b587791" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "End of the cell block...\n" + ] + } + ], + "source": [ + "amount_of_apples = 0\n", + "\n", + "if amount_of_apples > 0:\n", + " print(\"You have apples!\\nLet's make a pie!\")\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "qiElV_BSNYgl", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see - nothing is printed besides 'End of the cell block...'.

But we can clearly see that there is another print statement! Why it is not printed? Because we have no apples... thus no pie for you.

Let's acquire some fruit and see whether something will change...\n", + "\n", + "Adding 5 apples to our supply:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "ja5Tz_GLNoUH", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "6bd36f78-2958-4bb6-ffcc-420951b3f8ba" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You have apples!\n", + "Let's make a pie!\n", + "End of the cell block...\n" + ] + } + ], + "source": [ + "amount_of_apples += 5\n", + "\n", + "if amount_of_apples > 0:\n", + " print(\"You have apples!\\nLet's make a pie!\") \n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "UYZHMFlmNyyA", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now you can see that the same if statement prints text. It happened because our statement amount_of_apples > 0 is now True.

That's how an if statement works — you type the if keyword, a statement and a colon. Beneath it, with an indentation of 4 spaces (1 tab), you place any code you want to run in case that if statement is True. This indentation is the same as described in Notebook 1 when defining a function.

If the result of the conditional expression is False, then the code inside of the if statement block will not run. Here's another example:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "b1eW-x-3QMbZ", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "5d7df045-b19f-432d-e620-30d7cb34f605" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I'm an adult, I have to work right now :(\n", + "End of the cell block...\n" + ] + } + ], + "source": [ + "my_age = 25\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "7dhdkRKERIz_", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Slightly different setting but still the same construction. As you can see in this case, the condition of the if statement is more complicated than the previous one. It combines two smaller conditions by using the keyword and. Only if both conditions are True the final result is True (otherwise it would be False).Thus, the condition can be as long and as complicated as you want it to be, just make sure that it is readable." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "h3uicp2sTA5x", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "

elif keyword


Now, let's add a bit more logic to our last example:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "cZQHBzWcSdn8", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "0fdc9367-527d-4c1c-d4a2-b15d230a0f79" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I'm an adult, I have to work right now :(\n", + "End of the cell block...\n" + ] + } + ], + "source": [ + "my_age = 25\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "_6NOt61ZSufk", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Still the same output, but what if we change our age..." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "QZ-AGXaJSy7j", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "9208a2bb-328b-4fe0-d1fd-65c443c8902f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I can finally retire!\n", + "End of the cell block...\n" + ] + } + ], + "source": [ + "my_age = 66\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\") # msg #1\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\") # msg #2\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "u8RcnX-sTm4G", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "See.. we have a different output. Changing the value of our variable my_age changed the output of the if statement. Furthermore, the elif keyword helped us to add more logic to our code. Now, we have three different output scenarios:
\n", + "- print message #$1$ if my_age is within the $[18, 65]$ range;
\n", + "- print message #$2$ if my_age is bigger than $65$; and,
\n", + "- print none of them if my_age doesn't comply with none of the conditions (as shown below)." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "9r9Mx2gkVyS7", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "4a513321-cca9-4c5e-ee7d-da2157e039d5" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "End of the cell block...\n" + ] + } + ], + "source": [ + "my_age = 15\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\") # msg #1\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\") # msg #2\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "1lfzBWNfVwN0", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "One can also substitute an elif block by a different if block, however it is preferred to use elif instead to \"keep the condition together\" and to reduce code size.
\n", + "\n", + ":::{warning}\n", + "It is important to know that there should be only one if block and any number of elif blocks within it.\n", + ":::\n", + "\n", + "A last example below setting ``my_age = 88`` to run the first ``elif`` block and setting ``my_age = 7 `` to run the second ``elif`` block.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "0krMMx5DYpeO", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "19ac187f-b814-4aa5-ef91-9db6691ded6c" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I can finally retire!\n", + "I'm really really young\n", + "End of the cell block...\n" + ] + } + ], + "source": [ + "my_age = 88\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10:\n", + " print(\"I'm really, really young\")\n", + "\n", + "\n", + "my_age = 7\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10:\n", + " print(\"I'm really really young\")\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "WGUFngFNV6ys", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "## else keyword\n", + "\n", + "We can go even further and add an additional scenario to our if statement with the else keyword. It runs the code inside of it only when none of the if and elif conditions are True:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "ieXD271nW903", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "ff7edbd8-33b5-4b6e-c7e7-657ec1d4e8a0" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I'm just young\n", + "End of the cell block...\n" + ] + } + ], + "source": [ + "my_age = 13\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10:\n", + " print(\"I'm really really young\")\n", + "else:\n", + " print(\"I'm just young\")\n", + "\n", + "print('End of the cell block...')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "5_e10m98XJIn", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "\n", + "On the previous example, since my_age is not between $[18,65]$, nor bigger than $65$, nor smaller than $10$, the else block is run.\n", + "\n", + "Below, a final example setting ``my_age = 27`` to run the ``if`` block, then setting ``my_age = 71 `` to run the first ``elif`` block. To run the second ``elif`` block we set ``my_age = 9 ``. Finally, setting ``my_age = 13 `` to run the ``else`` block." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "Qc9WVQTxX76r", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "e4a5e6aa-6ebc-43c0-f7f2-eab350c66a8f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I'm an adult, I have to work right now :(\n", + "End of the cell block...\n", + "------------------------\n", + "I can finally retire!\n", + "End of the cell block...\n", + "------------------------\n", + "I'm really really young\n", + "End of the cell block...\n", + "------------------------\n", + "I'm just young\n", + "End of the cell block...\n", + "------------------------\n" + ] + } + ], + "source": [ + "my_age = 27\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10:\n", + " print(\"I'm really really young\")\n", + "else:\n", + " print(\"I'm just young\")\n", + "\n", + "print('End of the cell block...')\n", + "print('------------------------')\n", + "\n", + "my_age = 71\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65: # first elif block\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10:\n", + " print(\"I'm really really young\")\n", + "else:\n", + " print(\"I'm just young\")\n", + "\n", + "print('End of the cell block...')\n", + "print('------------------------')\n", + "\n", + "\n", + "my_age = 9\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10: # second elif block\n", + " print(\"I'm really really young\")\n", + "else:\n", + " print(\"I'm just young\")\n", + "\n", + "print('End of the cell block...')\n", + "print('------------------------')\n", + "\n", + "\n", + "my_age = 13\n", + "\n", + "if my_age >= 18 and my_age <= 65:\n", + " print(\"I'm an adult, I have to work right now :(\")\n", + "elif my_age > 65:\n", + " print(\"I can finally retire!\")\n", + "elif my_age < 10:\n", + " print(\"I'm really really young\")\n", + "else: # else block\n", + " print(\"I'm just young\")\n", + "\n", + "print('End of the cell block...')\n", + "print('------------------------')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "xAytN9YkYOtw", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "That's almost everything you have to know about if statements! The last two things are:\n", + "\n", + "1. It goes from top to bottom. When the first condition to be True runs, it skips all conditions after it — as shown below:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "clMld7oKa0n7", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "5cfedbfb-f653-4d90-abd0-658353746aea" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Condition #3\n" + ] + } + ], + "source": [ + "random_number = 17\n", + "\n", + "if random_number > 35:\n", + " print('Condition #1')\n", + "elif random_number > 25:\n", + " print('Condition #2')\n", + "elif random_number > 15:\n", + " print('Condition #3')\n", + "elif random_number > 5:\n", + " print('Condition #4')\n", + "else:\n", + " print('Condition #5')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "rfwRtedNbVs8", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "2. You can put almost everything inside each condition block and you can define variables within each block:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 242 + }, + "collapsed": true, + "id": "5II4-Zcvbf3j", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "cb2f7c29-2970-48a2-eacc-56d6e3f1a829" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I am a poor BSc student\n", + "x = 5\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'b' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[22], line 20\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mI am a poor MSc student\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m 19\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mx =\u001b[39m\u001b[39m'\u001b[39m, x)\n\u001b[1;32m---> 20\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mb =\u001b[39m\u001b[39m'\u001b[39m, b)\n", + "\u001b[1;31mNameError\u001b[0m: name 'b' is not defined" + ] + } + ], + "source": [ + "my_income = 150\n", + "my_degree = 'BSc'\n", + "\n", + "if my_degree == 'BSc':\n", + " x = 5\n", + " if my_income > 300:\n", + " b = 2\n", + " print('I am a rich BSc student')\n", + " else:\n", + " print('I am a poor BSc student')\n", + "\n", + "elif my_degree == 'MSc':\n", + "\n", + " if my_income > 300:\n", + " print('I am a rich MSc student')\n", + " else:\n", + " print('I am a poor MSc student')\n", + "\n", + "print('x =', x)\n", + "print('b =', b)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "9nDrNWr2cjMd", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, we can make it as complicated as we want in terms of conditional branching.

Additionally, you can see that only variables within the blocks which run were created, while other variables were not. Thus, we have a NameError that we tried to access a variable (b) that was not defined." + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Python_2_1.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.13" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/book/flow/loops.ipynb b/book/flow/loops.ipynb new file mode 100644 index 0000000..e350ac6 --- /dev/null +++ b/book/flow/loops.ipynb @@ -0,0 +1,853 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "fHmKWsUSKuj4", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Loops\n", + "\n", + "Let's do another step to automatize things even more! Previous Sections introduced a lot of fundamental concepts, but they still don't unveil the true power of any programming language — loops!

If we want to perform the same procedure multiple times, then we would have to take the same code and copy-paste it. This approach would work, however it would require a lot of manual work and it does not look cool.

This problem is resolved with a loop construction. As the name suggest, this construction allows you to loop (or run) certain piece of code several times at one execution." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "BcEOnv2kTT9A", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### for loop\n", + "\n", + "The first and the most popular looping technique is a for loop. Let's see some examples:\n", + "\n", + "Let's create a list with some stuff in it. In order to iterate (or go through each element of a list) we use a `for` loop.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "fNaiOimubLMF", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "77085dd8-83cc-41d8-b7c1-17fc55dc38eb" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Start of the loop\n", + "In my list I can find: 100\n", + "In my list I can find: marble\n", + "In my list I can find: False\n", + "In my list I can find: 2\n", + "In my list I can find: 2\n", + "In my list I can find: [7, 7, 7]\n", + "In my list I can find: end\n", + "End of the loop\n" + ] + } + ], + "source": [ + "my_list = [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n", + "\n", + "print('Start of the loop')\n", + "for list_item in my_list:\n", + " print('In my list I can find:', list_item)\n", + "print('End of the loop')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "NkKA4qLDb9IM", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "General for loop construction looks like this:

\n", + "for iterator_variable in iterable:\n", + " do something with iterator_variable

\n", + "\n", + "During each iteration the following steps are happening under the hood (or above it):\n", + "1. iterator_variable = iterable[0]iterator_variable is assigned the first value from the iterable.\n", + "2. Then, you use iterator_variable as you wish.\n", + "3. By the end of the 'cycle', the next element from the iterable is selected (iterable[1]), i.e., we return to step 1, but now assigning the second element... and so on.\n", + "4. When there is not a next element (in other words, we have reached the end of the iterable) — it exits and the code under the loop is now executed.\n", + "\n", + "Looks cool, but what if we want to alter the original iterable (not the iterator_variable) within the loop?\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "1hZm9bOuhOiE", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "0b50490d-1d74-41cb-ba84-d4a595a7eede" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Try #1, before: [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n", + "Try #1, after [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n" + ] + } + ], + "source": [ + "x = my_list\n", + "print('Try #1, before:', x)\n", + "\n", + "for item in x:\n", + " item = [5,6,7]\n", + "\n", + "print('Try #1, after', x)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Nothing has changed.... let's try another method. `range()` is used to generate a sequence of numbers more info [here](https://www.w3schools.com/python/ref_func_range.asp).\n", + "\n", + "`range(length_of_x)` will generate numbers from 0 till `length_of_x`, excluding the last one.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "range(0, 7)\n", + "Try #2, before [100, 'marble', False, 2, 2, [7, 7, 7], 'end']\n", + "Try #2, after [-1, -1, -1, -1, -1, -1, -1]\n" + ] + } + ], + "source": [ + "length_of_x = len(x)\n", + "\n", + "indices = range(length_of_x)\n", + "\n", + "print(indices)\n", + "print('Try #2, before', my_list)\n", + "\n", + "for id in indices:\n", + " my_list[id] = -1\n", + "\n", + "print('Try #2, after', my_list)\n", + " \n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Now we have a method in our arsenal which can not only loop through a list but also access and alter its contents. Also, you can generate new data by using a for loop and by applying some processing to it. Here's an example on how you can automatize your greetings routine!\n", + "\n", + "We create a variable `message` with a general greeting and a list with your friends names. Then an empty list where all greetings will be stored (otherwise you cannot use the `.append` in the for loop below!). \n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Ohayo, Mike-kun!', 'Ohayo, Alex-kun!', 'Ohayo, Maria-kun!']\n" + ] + } + ], + "source": [ + "\n", + "message = \"Ohayo\"\n", + "names = [\"Mike\", \"Alex\", \"Maria\"]\n", + "greetings = []\n", + "\n", + "for name in names:\n", + " personalized_greeting = f'{message}, {name}-kun!' \n", + " greetings.append(personalized_greeting) \n", + "\n", + "print(greetings)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "And you can also have loops inside loops!. Let's say that you put down all your expenses per day separately in euros. You can also keep them within one list together.Additionally, you can access also each expense separately! day3 is third array and 2nd expense is second element within that array." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All my expenses [[15, 100, 9], [200], [10, 12, 15, 5, 1]]\n", + "My second expense on day 3 is 12\n" + ] + } + ], + "source": [ + "day1_expenses = [15, 100, 9]\n", + "day2_expenses = [200]\n", + "day3_expenses = [10, 12, 15, 5, 1]\n", + "\n", + "expenses = [day1_expenses, day2_expenses, day3_expenses]\n", + "print('All my expenses', expenses)\n", + "\n", + "print(f'My second expense on day 3 is {expenses[2][1]}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's use it in some calculations. The code bellow iterates over the expenses for each day, calculates the total expenses for each day, and then adds them together to obtain the overall total expenses. " + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Option #1: In total I have spent 367 euro!\n" + ] + } + ], + "source": [ + "total_expenses = 0\n", + "\n", + "for i in range(len(expenses)): \n", + " daily_expenses_list = expenses[i]\n", + " daily_expenses = 0\n", + " for j in range(len(daily_expenses_list)): \n", + " daily_expenses += daily_expenses_list[j]\n", + " total_expenses += daily_expenses\n", + " \n", + "print(f'Option #1: In total I have spent {total_expenses} euro!')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`````{admonition} Let's break it down\n", + "This code calculates the total expenses over multiple days using nested loops. Here's an explanation in simpler terms:\n", + "\n", + "1. We start with the variable `total_expenses` set to 0 to keep track of the total expenses.\n", + "2. The code loops over each day's expenses using the outer loop, which runs from 0 to the length of the `expenses` list.\n", + "3. Inside the loop, it accesses the expenses made on the current day by assigning `daily_expenses_list` to the expenses at index `i`.\n", + "4. It initializes `daily_expenses` as 0 to temporarily store the sum of expenses for the current day.\n", + "5. The code enters the inner loop, which iterates over the expenses for the current day using the range of the length of `daily_expenses_list`.\n", + "6. Inside the inner loop, it adds each expense to `daily_expenses` to calculate the total expenses for the current day.\n", + "7. After the inner loop completes, it adds `daily_expenses` to the `total_expenses` variable to accumulate the expenses across all days.\n", + "8. Once the outer loop finishes, it prints the total expenses using an f-string format to display the result.\n", + "`````\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Option #2" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Option #2: In total I have spent 367 euro!\n" + ] + } + ], + "source": [ + "total_expenses = 0\n", + "\n", + "for i in range(len(expenses)):\n", + " for j in range(len(expenses[i])):\n", + " total_expenses += expenses[i][j]\n", + " \n", + "print(f'Option #2: In total I have spent {total_expenses} euro!')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Option #3 - advanced techniques gathered after eternal suffering." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Option #3: In total I have spent 367 euro!\n" + ] + } + ], + "source": [ + "total_expenses = 0\n", + "total_expenses = sum(map(sum, expenses))\n", + "print(f'Option #3: In total I have spent {total_expenses} euro!')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "TNGZ78d8LOYC", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### while loop\n", + "\n", + "The second popular loop construction is a while loop. The main difference is that it is suited for code structures that must repeat unless a certain logical condition is satisfied. It looks like this:

while logical_condition == True:
do something

And here is a working code example:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "rqsX011pL6p6", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "39bce5bb-bf01-469c-8758-6127efc4e943" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sum in the beginning of the cycle: 0\n", + "sum in the end of the cycle: 1\n", + "sum in the beginning of the cycle: 1\n", + "sum in the end of the cycle: 2\n", + "sum in the beginning of the cycle: 2\n", + "sum in the end of the cycle: 3\n", + "sum in the beginning of the cycle: 3\n", + "sum in the end of the cycle: 4\n", + "sum in the beginning of the cycle: 4\n", + "sum in the end of the cycle: 5\n" + ] + } + ], + "source": [ + "sum = 0\n", + "\n", + "while sum < 5:\n", + " print('sum in the beginning of the cycle:', sum)\n", + " sum += 1\n", + " print('sum in the end of the cycle:', sum)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "mW02NDD4MJWn", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, this loop was used to increase the value of the sum variable until it reached $5$. The moment it reached $5$ and the loop condition was checked — it returned False and, therefore, the loop stopped.

Additionally, it is worth to mention that the code inside the loop was altering the variable used in the loop condition statement, which allowed it to first run, and then stop. In the case where the code doesn't alter the loop condition, it won't stop (infinite loop), unless another special word is used.

Here's a simple example of an infinite loop, which you may run (by removing the #'s) but in order to stop it — you have to interrupt the Notebook's kernel or restart it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "collapsed": true, + "id": "AmIcH59oNaxU", + "outputId": "e944bfe2-f906-45c9-ef2a-03280956679a" + }, + "outputs": [], + "source": [ + "# a, b = 0, 7\n", + "\n", + "# while a + b < 10:\n", + "# a += 1\n", + "# b -= 1\n", + "# print(f'a:{a};b:{b}')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "ryvB-qKfNxPh", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### break keyword\n", + "\n", + "After meeting and understanding the loop constructions, we can add a bit more control to it. For example, it would be nice to exit a loop earlier than it ends — in order to avoid infinite loops or just in case there is no need to run the loop further. This can be achieved by using the break keyword. The moment this keyword is executed, the code exits from the current loop." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "hvib4ruNTN6_", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "b0f08946-864e-430a-a8cc-765303a9ac6e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Before normal loop\n", + "0 iteration and still running...\n", + "1 iteration and still running...\n", + "2 iteration and still running...\n", + "3 iteration and still running...\n", + "4 iteration and still running...\n", + "5 iteration and still running...\n", + "6 iteration and still running...\n", + "After normal loop\n", + "Before interrupted loop\n", + "0 iteration and still running...\n", + "1 iteration and still running...\n", + "2 iteration and still running...\n", + "3 iteration and still running...\n", + "4 iteration and still running...\n", + "Leaving the loop\n", + "After interupted loop\n" + ] + } + ], + "source": [ + "stop_iteration = 4\n", + "\n", + "print('Before normal loop')\n", + "for i in range(7):\n", + " print(f'{i} iteration and still running...')\n", + "print('After normal loop')\n", + "\n", + "print('Before interrupted loop')\n", + "for i in range(7):\n", + " print(f'{i} iteration and still running...')\n", + "\n", + " if i == stop_iteration:\n", + " print('Leaving the loop')\n", + " break\n", + "print('After interupted loop')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "guxGK4uGUXBA", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "The second loop shows how a small intrusion of an if statement and the break keyword can help us with stopping the loop earlier. The same word can be also used in a while loop:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "tVkdaOP8Ul-W", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "5f391d65-82a2-4408-d74d-af89b84a040b" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Before the loop\n", + "Inside the loop #1\n", + "Inside the loop #2\n", + "Inside the loop #3\n", + "Inside the loop #4\n", + "Inside the loop #5\n", + "Inside the loop #6\n", + "Too many iterations is bad for your health\n", + "After the loop\n" + ] + } + ], + "source": [ + "iteration_number = 0\n", + "\n", + "print('Before the loop')\n", + "while True:\n", + " iteration_number += 1\n", + "\n", + " print(f'Inside the loop #{iteration_number}')\n", + " if iteration_number > 5:\n", + " print('Too many iterations is bad for your health')\n", + " break\n", + "print('After the loop')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "AtRCfdMlWzhn", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### continue keyword\n", + "\n", + "Another possibility to be more flexible when using loops is to use the continue keyword.

This will allow you to skip some iterations (more precisely — the moment the keyword is used it will skip the code underneath it and will start the next iteration from the beginning)." + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "_1q4EB0bXMyk", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "57b11d07-251a-4319-d0ba-1d3ee1685b61" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Begin normal loop\n", + "\n", + "0 iteration and still running...\n", + "Calculating cool function for 0 -> f(0) = 3\n", + "1 iteration and still running...\n", + "Calculating cool function for 1 -> f(1) = 15\n", + "2 iteration and still running...\n", + "Calculating cool function for 2 -> f(2) = 41\n", + "3 iteration and still running...\n", + "Calculating cool function for 3 -> f(3) = 81\n", + "4 iteration and still running...\n", + "Calculating cool function for 4 -> f(4) = 135\n", + "5 iteration and still running...\n", + "Calculating cool function for 5 -> f(5) = 203\n", + "6 iteration and still running...\n", + "Calculating cool function for 6 -> f(6) = 285\n", + "\n", + "End normal loop\n", + "\n", + "-------------------\n", + "Begin altered loop\n", + "\n", + "0 iteration and still running...\n", + "1 iteration and still running...\n", + "Calculating cool function for 1 -> f(1) = 15\n", + "2 iteration and still running...\n", + "3 iteration and still running...\n", + "Calculating cool function for 3 -> f(3) = 81\n", + "4 iteration and still running...\n", + "5 iteration and still running...\n", + "Calculating cool function for 5 -> f(5) = 203\n", + "6 iteration and still running...\n", + "\n", + "End altered loop\n" + ] + } + ], + "source": [ + "def calculate_cool_function(arg):\n", + " res = 7 * arg ** 2 + 5 * arg + 3\n", + " print(f'Calculating cool function for {arg} -> f({arg}) = {res}')\n", + "\n", + "print('Begin normal loop\\n')\n", + "for i in range(7):\n", + " print(f'{i} iteration and still running...')\n", + " calculate_cool_function(i)\n", + "print('\\nEnd normal loop\\n')\n", + "\n", + "print('-------------------')\n", + "\n", + "print('Begin altered loop\\n')\n", + "for i in range(7):\n", + " print(f'{i} iteration and still running...')\n", + "\n", + " # skipping every even iteration\n", + " if i % 2 == 0:\n", + " continue\n", + " \n", + " calculate_cool_function(i)\n", + " \n", + "print('\\nEnd altered loop')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "_30hKsC4a1vy", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, with the help of the continue keyword we managed to skip some of the iterations. Also worth noting that $0$ is divisible by any number, for that reason the calculate_cool_function(i) at i = 0 didn't run." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "lDKimbtECAAz", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "## Additional study material\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/tutorial/controlflow.html\n", + "* https://realpython.com/python-conditional-statements/\n", + "* Think Python (2nd ed.) - Section 5\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/tutorial/datastructures.html\n", + "* https://realpython.com/python-data-structures/\n", + "* Think Python (2nd ed.) - Sections 8, 10, 11, 12\n", + "\n", + "* Official Python Documentation - https://docs.python.org/3/tutorial/controlflow.html\n", + "* https://realpython.com/python-for-loop/\n", + "* Think Python (2nd ed.) - Section 7" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### After this Notebook you should be able to:\n", + "\n", + "- generate an array for the x-axis\n", + "- calculate the **`cos`** or **`sin`** of the x-axis\n", + "- plot such functions\n", + "- understand how to load Python files as modules\n", + "- understand conditions with **`if`**, **`elif`** and, **`else`**\n", + "- understand the differences between **`list`**, **`tuple`**, and **`dict`**\n", + "- slice lists and tuples\n", + "- use **`for`** and **`while`** loops\n", + "- use the **`break`** and **`continue`** keywords inside of loops\n" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Python_2_1.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.13" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/book/flow/nutshell.md b/book/flow/nutshell.md new file mode 100644 index 0000000..91c024e --- /dev/null +++ b/book/flow/nutshell.md @@ -0,0 +1,3 @@ +# Flow: in a Nutshell + +Nutshell. \ No newline at end of file diff --git a/book/flow/nutshell/conditions.ipynb b/book/flow/nutshell/conditions.ipynb new file mode 100644 index 0000000..d133b5d --- /dev/null +++ b/book/flow/nutshell/conditions.ipynb @@ -0,0 +1,82 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conditions and if statements\n", + "\n", + "\n", + "In previous sections, you have acquired essential skills in Python such as variable creation, operator utilization, and code analysis. These skills enable you to accomplish a wide range of tasks. However, there is still a need for increased flexibility. Manually modifying your code to accommodate different data and reverting those changes can be cumbersome. In this section, you will delve into the concept of code control, which allows you to navigate the execution of your code based on specific conditions. To achieve this, you will explore a fundamental programming construct called the if statement. Through this construct, you will gain the ability to selectively process data based on defined conditions, enhancing the adaptability and efficiency of your code.\n", + "\n", + "We have three sections:\n", + "\n", + "* If Statement: The if statement enables us to execute a block of code only if a specified condition is true. It provides a way to make decisions and selectively perform actions based on whether a condition evaluates to true or false.\n", + "\n", + "* Elif Statement: The elif statement allows us to consider multiple conditions one after another and execute different blocks of code based on the first condition that evaluates to true. It provides a means to handle various possibilities and choose the appropriate action based on the situation.\n", + "\n", + "* If-else Statement: The if-else statement combines the if and else statements to perform one action if a condition is true and a different action if the condition is false. It offers a way to provide alternative paths of execution, ensuring that the code responds differently based on whether a condition is met or not.\n", + "\n", + "These conditional statements allow you to make decisions and control the flow of your program based on specific conditions. For example like this: \n" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x is positive\n", + "x is non-positive\n", + "x is zero\n" + ] + } + ], + "source": [ + "x = 5\n", + "if x > 0:\n", + " print(\"x is positive\")\n", + "\n", + "x = -2\n", + "if x > 0:\n", + " print(\"x is positive\")\n", + "else:\n", + " print(\"x is non-positive\")\n", + "\n", + "x = 0\n", + "if x > 0:\n", + " print(\"x is positive\")\n", + "elif x < 0:\n", + " print(\"x is negative\")\n", + "else:\n", + " print(\"x is zero\")\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/flow/nutshell/loops.ipynb b/book/flow/nutshell/loops.ipynb new file mode 100644 index 0000000..2f2abe8 --- /dev/null +++ b/book/flow/nutshell/loops.ipynb @@ -0,0 +1,181 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Loops " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### for loop \n", + "for Loop: A for loop is used to iterate over a sequence (such as a list, tuple, or string) or any iterable object. It allows you to perform a set of statements repeatedly for each item in the sequence. Here is a simple example of how to use a for loop:" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apple\n", + "banana\n", + "orange\n" + ] + } + ], + "source": [ + "fruits = [\"apple\", \"banana\", \"orange\"]\n", + "for fruit in fruits:\n", + " print(fruit)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### while loop\n", + "while Loop: A while loop is used to repeatedly execute a block of code as long as a given condition is true. It allows you to keep looping until the condition becomes false. Here is a simple example of how to use a while loop:" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n" + ] + } + ], + "source": [ + "count = 0\n", + "while count < 5:\n", + " print(count)\n", + " count += 1\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### break statement\n", + "break Statement: The break statement is used to prematurely exit a loop. When encountered, it terminates the loop and resumes execution at the next statement outside the loop. Here is a simple example of how to use a break statement:" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "apple\n" + ] + } + ], + "source": [ + "fruits = [\"apple\", \"banana\", \"orange\"]\n", + "for fruit in fruits:\n", + " if fruit == \"banana\":\n", + " break\n", + " print(fruit)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### continue statement\n", + "continue Statement: The continue statement is used to skip the remaining code inside a loop for the current iteration and move to the next iteration. Here is a simple example of how to use a continue statement:" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "4\n", + "5\n" + ] + } + ], + "source": [ + "numbers = [1, 2, 3, 4, 5]\n", + "for num in numbers:\n", + " if num == 3:\n", + " continue\n", + " print(num)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Break down of all examples**: In the first example, the for loop iterates over a list of fruits and prints each fruit. The while loop in the second example prints numbers from 0 to 4. The break statement in the third example terminates the loop when the condition is met. Lastly, the continue statement in the fourth example skips printing the number 3 and moves to the next iteration. These loop constructs provide powerful control flow mechanisms to repeat and control the execution of code blocks based on specific conditions." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [] + } + ], + "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.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/flow/nutshell/structures.ipynb b/book/flow/nutshell/structures.ipynb new file mode 100644 index 0000000..dcc9e18 --- /dev/null +++ b/book/flow/nutshell/structures.ipynb @@ -0,0 +1,314 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Data Structures\n", + "\n", + "Welcome to an exciting new adventure in data management! In the previous module, you learned how to create variables, which was just the tip of the iceberg. Now, imagine a scenario where you have numerous variables or want to organize and access them within a single entity. That's where data structures come into play!\n", + "\n", + "Data structures are like superheroes that help us tackle complex data management challenges. They come in various forms, each with its unique purpose and complexity. Today, we'll dive into some of the superheroes of Python's built-in data structures: the mighty list, the versatile dict, and the steadfast tuple. These data structures provide us with powerful tools to store, organize, and manipulate data, enabling us to unleash the true potential of our code. Let's dive in and unlock the secrets of organized data!" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### List\n", + "A list is a powerful data structure in Python that allows you to store and manipulate an ordered collection of items. It's like having a magic box where you can keep multiple things together and change them whenever you want. Let's explore 4 different ways to create and use lists:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. Creating an empty list:\n", + "You can create an empty list by simply using empty square brackets [ ]. It's like having a blank canvas ready to be filled with items." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 5, 3]\n" + ] + } + ], + "source": [ + "my_list = [2,5,3]\n", + "\n", + "print (my_list)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Creating an empty list - using the class constructor: You can also use the list class constructor list() to create an empty list. It's another way of preparing your container for future data." + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [], + "source": [ + "my_list = list()\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3. Creating a list from existing data: To create a list with existing data, you can directly enclose the items within square brackets [ ], separating them with commas. It's like assembling your collection of items in one go." + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['apple', 'banana', 'orange', 'kiwi']\n" + ] + } + ], + "source": [ + "fruits = ['apple', 'banana', 'orange', 'kiwi']\n", + "print (fruits)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4. Creating a list from existing data: You can use the list constructor list( ) with an iterable (such as a string or another list) to create a new list containing the elements of that iterable. It's like transforming one collection into another." + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 4, 5]\n" + ] + } + ], + "source": [ + "numbers = list(range(1, 6)) # Creates a list [1, 2, 3, 4, 5]\n", + "print (numbers)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### tuple\n", + "A tuple is a data structure in Python that allows you to store an ordered collection of items. Unlike lists, tuples are immutable, meaning their elements cannot be modified once they are assigned. Let's explore how to define tuples and create examples:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. Defining a tuple using ( ) brackets or comma:\n", + "You can define a tuple by enclosing the items within parentheses () or by simply separating them with commas. It's like creating a fixed ensemble of elements." + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 2, 3)\n", + "(1, 2, 3)\n" + ] + } + ], + "source": [ + "my_tuple1 = (1, 2, 3)\n", + "my_tuple2 = 1, 2, 3\n", + "\n", + "print (my_tuple1)\n", + "print (my_tuple2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Creating a tuple using the tuple class constructor: You can also use the tuple class constructor tuple() to create a tuple. It accepts an iterable as an argument and generates a tuple with its elements. It's like assembling data into a coordinated ensemble." + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(4, 5, 6)\n", + "(1, 2, 3)\n", + "(3, 5)\n", + "('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')\n" + ] + } + ], + "source": [ + "my_tuple3 = tuple([4, 5, 6])\n", + "\n", + "coordinates = (3, 5) \n", + "days_of_week = tuple(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']) \n", + "\n", + "my_tuple4 = (1, 2, 3)\n", + "print (my_tuple3)\n", + "print (my_tuple4)\n", + "print (coordinates)\n", + "print (days_of_week)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dict\n", + "A dictionary is a versatile data structure in Python that allows you to store and retrieve data using a key-value pairing. It's like having a real-life dictionary where you can quickly look up information using specific words. Let's explore how to define dictionaries, we will explore 3 examples:" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. Creating a dictionary using { } brackets: You can create a dictionary by enclosing key-value pairs within curly braces { }, separating each pair with a colon ' : ' It's like building a repository of information with quick access to specific entries." + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'John', 'age': 25, 'city': 'New York'}\n" + ] + } + ], + "source": [ + "my_dict = {\"name\": \"John\", \"age\": 25, \"city\": \"New York\"}\n", + "\n", + "print (my_dict)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2. Creating an empty dictionary using the class constructor: You can also use the dict class constructor dict( ) to create an empty dictionary. It's like preparing a blank canvas to populate with key-value pairs later." + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": {}, + "outputs": [], + "source": [ + "my_dict2 = dict()\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3. Creating a non-empty dictionary by specifying pairs of key-value patterns: To create a dictionary with existing data, you can specify pairs of key-value patterns within the curly braces { }. Each key-value pair is separated by a colon : and pairs are separated by commas. It's like defining relationships between different pieces of information." + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'Alice', 'age': 30, 'city': 'London'}\n" + ] + } + ], + "source": [ + "student_scores = {\"Alice\": 85, \"Bob\": 92, \"Charlie\": 78}\n", + "contacts = {\"John\": \"+123456789\", \"Emily\": \"+987654321\", \"Sam\": \"+345678912\"}\n", + "my_dict3 = dict()\n", + "my_dict3[\"name\"] = \"Alice\"\n", + "my_dict3[\"age\"] = 30\n", + "my_dict3[\"city\"] = \"London\"\n", + "\n", + "print (my_dict3)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the above code cell, we have created two dictionaries: student_scores and contacts, by specifying key-value pairs within the { } brackets. Additionally, we have also demonstrated how to create an empty dictionary my_dict3 using the dict( ) constructor and then added key-value pairs to it using the square bracket notation. These examples showcase the flexibility of dictionaries in storing and accessing data through key-value relationships." + ] + } + ], + "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.11.2" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/book/flow/structures.ipynb b/book/flow/structures.ipynb new file mode 100644 index 0000000..6af696d --- /dev/null +++ b/book/flow/structures.ipynb @@ -0,0 +1,1113 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "fHmKWsUSKuj4", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "# Data Structures\n", + "\n", + "In this Section you will tackle a data management problem! In the first module you have learned how to create variables, which is cool. But when you populate a lot of variables, or you want to store & access them within one entity, you need to have a data structure.

There are plenty of them, which differ their use cases and complexity. Today we will tackle some of the standard Python built-in data structures. The most popular of those are: list, dict and tuple." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "BcEOnv2kTT9A", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### list\n", + "\n", + "First, the easiest and the most popular data structure in Python: list (which is similar to a typical array you could have seen in a different programming language).

\n", + "You can create a list in the following ways:\n", + "\n", + "1. Creating an empty list, option 1\n", + "2. Creating an empty list, option 2 - using the class constructor\n", + "3. Creating a list from existing data - option 1\n", + "4. Creating a list from existing data - option 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "U8OUPaXESz44", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "ee38751f-5efe-4a85-a9a9-a34efc3bfb02" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Type of my_list1 object \n", + "Contents of my_list1 []\n", + "--------------------\n", + "Type of my_list2 object \n", + "Contents of my_list2 []\n", + "--------------------\n", + "Type of my_list3 object \n", + "Contents of my_list3 [5, 'hello', 37.5]\n", + "--------------------\n", + "Type of my_list3 object \n", + "Contents of list_with_letters ['s', 'a', 'n', 'd', 's', 't', 'o', 'n', 'e']\n", + "--------------------\n" + ] + } + ], + "source": [ + "#1\n", + "empty_list1 = []\n", + "print('Type of my_list1 object', type(empty_list1))\n", + "print('Contents of my_list1', empty_list1)\n", + "print('--------------------')\n", + "\n", + "#2\n", + "empty_list2 = list()\n", + "print('Type of my_list2 object', type(empty_list2))\n", + "print('Contents of my_list2', empty_list2)\n", + "print('--------------------')\n", + "\n", + "#3\n", + "my_var1 = 5\n", + "my_var2 = \"hello\"\n", + "my_var3 = 37.5\n", + "\n", + "my_list = [my_var1, my_var2, my_var3]\n", + "print('Type of my_list3 object', type(my_list))\n", + "print('Contents of my_list3', my_list)\n", + "print('--------------------')\n", + "\n", + "\n", + "#4\n", + "cool_rock = \"sandstone\" # remember that a string is a collection of characters\n", + "\n", + "list_with_letters = list(cool_rock)\n", + "\n", + "print('Type of my_list3 object', type(list_with_letters))\n", + "print('Contents of list_with_letters', list_with_letters)\n", + "print('--------------------')\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "I-9MNCzBUgH9", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, in all three cases we created a list, only the method how we did it was slightly different:\n", + "- the first method uses the bracket notation.\n", + "- the second method uses class constructor approach. \n", + "\n", + "Both methods also apply to the other data structures.\n", + "\n", + "Now, we have a list — what can we do with it?\n", + "\n", + "Well... we can access and modify any element of an existing list. In order to access a list element, square brackets [] are used with the index of the element we want to access inside. Sounds easy, but keep in mind that Python has a zero-based indexing (as mentioned in Section 1.4 in Notebook 1).\n", + "\n", + ":::{note}\n", + "A zero-based indexing means that the first element has index 0 (not 1), the second element has index 1 (not 2) and the n-th element has index n - 1 (not n)!\n", + ":::" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The ``len()` function returns the lengths of an iterable (string, list, array, etc). Since we have 3 elements, thus we can access 0th, 1st, and 2nd elements. \n", + "\n", + "After the element is accessed, it can be used as any variable, the list only provides a convenient storage. Since it is a storage - we can easily alter and swap list elements" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 295 + }, + "collapsed": true, + "id": "CksNFv0AVmLw", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "bbddff89-959c-4065-89a5-04500ceedf91" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "First element of my list: 5\n", + "Last element of my list: 37.5\n", + "Sum of 5 and 37.5 is 42.5\n", + "[12, 'My new element', 37.5]\n" + ] + } + ], + "source": [ + "print(len(my_list))\n", + "print('First element of my list:', my_list[0])\n", + "print('Last element of my list:', my_list[2])\n", + "\n", + "summation = my_list[0] + my_list[2]\n", + "print(f'Sum of {my_list[0]} and {my_list[2]} is {summation}')\n", + "\n", + "\n", + "my_list[0] += 7\n", + "my_list[1] = \"My new element\"\n", + "\n", + "print(my_list)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "we can only access data we have - Python will give us an error for the following" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "ename": "IndexError", + "evalue": "list assignment index out of range", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[4], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m my_list[\u001b[39m10\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m199\u001b[39m\n", + "\u001b[1;31mIndexError\u001b[0m: list assignment index out of range" + ] + } + ], + "source": [ + "my_list[10] = 199" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "zxkLDWef7IM-", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "We can also add new elements to a list, or remove them! Adding is realized with the append method and removal of an element uses the del keyword. We can also store a list inside a list - list inception! Useful for matrices, images etc. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "Yos0Cl9C7W1H", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "ba48887c-c2ff-4fc6-a231-68543e8bf97a" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[12, 'My new element', 37.5, 'new addition to my variable collection!']\n", + "[12, 'My new element', 37.5, 'new addition to my variable collection!', ['another list', False, (1+2j)]]\n", + "[12, 'My new element', 'new addition to my variable collection!', ['another list', False, (1+2j)]]\n" + ] + } + ], + "source": [ + "my_list.append(\"new addition to my variable collection!\")\n", + "print(my_list)\n", + "\n", + "my_list.append(['another list', False, 1 + 2j])\n", + "print(my_list)\n", + "\n", + "del my_list[2]\n", + "print(my_list)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "WZgLxAbJ8icK", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Lists also have other useful functionalities, as you can see from the official documentation. Since lists are still objects you can try and apply some operations to them as well." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "UEBv_4u09K9T", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "96987502-088b-48d8-d114-2b9967f2de78" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 4, False, 'second list', 0, 222]\n", + "['second list', 0, 222, 'second list', 0, 222, 'second list', 0, 222, 'second list', 0, 222]\n", + "['second list', 0, 222, 5050, 0, 222, 'second list', 0, 222, 'second list', 0, 222]\n" + ] + } + ], + "source": [ + "lst1 = [2, 4, False]\n", + "lst2 = ['second list', 0, 222]\n", + "\n", + "lst1 = lst1 + lst2\n", + "print(lst1)\n", + "\n", + "lst2 = lst2 * 4\n", + "print(lst2)\n", + "\n", + "lst2[3] = 5050\n", + "print(lst2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "SVvYBl6H96du", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "As you can see, adding lists together concatenates them and multiplying them basically does the same thing (it performs addition several times, just like in real math...).

Additionally, you can also use the in keyword to check the presence of a value inside a list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "15hwh0COFf-p", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "2b3d16c6-9487-49ea-a6f6-8ffb989ac95c" + }, + "outputs": [], + "source": [ + "print(lst1)\n", + "\n", + "if 222 in lst1:\n", + " print('We found 222 inside lst1')\n", + "else:\n", + " print('Nope, nothing there....')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "NAJZYyQd-fG2", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### tuple\n", + "\n", + "If you understood how list works, then you already understand 95% of tuple. Tuples are just like lists, with some small differences.

1. In order to create a tuple you need to use () brackets, comma or a tuple class constructor.
2. You can change the content of your list, however tuples are immutable (just like strings).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 313 + }, + "collapsed": true, + "id": "QnEd7YSsE2Ih", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "1a2e1b57-dbff-4c7d-d7c4-8968fecf67a1" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Type of tupl1 \n", + "Content of tupl1 ()\n", + " ()\n" + ] + } + ], + "source": [ + "#1\n", + "tupl1 = tuple() \n", + "print('Type of tupl1', type(tupl1))\n", + "print('Content of tupl1', tupl1)\n", + "#2\n", + "tupl2 = () # option 2 with ()\n", + "print(type(tupl2), tupl2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Creating a non-empty tuple using brackets or # Creating a non-empty tuple using comma. Can we change an element of a tuple?" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "my tuple (26.5, 'Oil', False, 'some additional stuff', 777)\n", + "A comma made tuple (2, 'hi!', 228)\n", + "4th element of my_tuple: some additional stuff\n" + ] + }, + { + "ename": "TypeError", + "evalue": "'tuple' object does not support item assignment", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[8], line 13\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mA comma made tuple\u001b[39m\u001b[39m'\u001b[39m, comma_tuple)\n\u001b[0;32m 12\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m4th element of my_tuple:\u001b[39m\u001b[39m'\u001b[39m, my_tuple[\u001b[39m3\u001b[39m])\n\u001b[1;32m---> 13\u001b[0m my_tuple[\u001b[39m3\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m'\u001b[39m\u001b[39mwill I change?\u001b[39m\u001b[39m'\u001b[39m\n", + "\u001b[1;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" + ] + } + ], + "source": [ + "my_var1 = 26.5\n", + "my_var2 = 'Oil'\n", + "my_var3 = False\n", + "\n", + "my_tuple = (my_var1, my_var2, my_var3, 'some additional stuff', 777)\n", + "print('my tuple', my_tuple)\n", + "\n", + "\n", + "comma_tuple = 2, 'hi!', 228\n", + "print('A comma made tuple', comma_tuple)\n", + "\n", + "print('4th element of my_tuple:', my_tuple[3])\n", + "my_tuple[3] = 'will I change?'" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "1RxahCCiHJRl", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Since tuples are immutable, it has no append() method nor any other methods that alter the object they target.\n", + "\n", + "You might think that tuple is a useless class. However, there are some reasons for it to exist:\n", + "\n", + "1.Storing constants & objects which shouldn't be changed.\n", + "2.Saving memory (tuple uses less memory to store the same data than a list). ``.__sizeof__()`` determines the size of a variable in bytes.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "A9cA-BpNIMzd", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "d7100baa-0a2c-4498-b8c0-01d1733e732f" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "size of a = 48 bytes\n", + "size of b = 64 bytes\n" + ] + } + ], + "source": [ + "my_name = 'Vasyan'\n", + "my_age = 27\n", + "is_student = True\n", + "\n", + "a = (my_name, my_age, is_student)\n", + "b = [my_name, my_age, is_student]\n", + "\n", + "print('size of a =', a.__sizeof__(), 'bytes') \n", + "print('size of b =', b.__sizeof__(), 'bytes')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "IYyveiZJJOTZ", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### dict\n", + "\n", + "After seeing lists and tuples, you may think:

\"Wow, storing all my variables within another variable is cool and gnarly! But... sometimes it's boring & inconvenient to access my data by using it's position within a tuple/list. Is there a way that I can store my object within a data structure but access it via something meaningful, like a keyword...?\"

Don't worry if you had this exact same thought.. Python had it as well!

Dictionaries are suited especially for that purpose — to each element you want to store, you give it a nickname (i.e., a key) and use that key to access the value you want.\n", + "\n", + "To create an empty dictionary we used ``{}`` or class constructor ``dict()``" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "r5vjDJ8CKaT8", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "46ee6315-d5a5-40a5-8db3-175a681dbf0c" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Type of empty_dict1 \n", + "Content of it -> {}\n", + "Type of empty_dict2 \n", + "Content of it -> {}\n" + ] + } + ], + "source": [ + "empty_dict1 = {}\n", + "print('Type of empty_dict1', type(empty_dict1))\n", + "print('Content of it ->', empty_dict1)\n", + "\n", + "\n", + "empty_dict2 = dict()\n", + "print('Type of empty_dict2', type(empty_dict2))\n", + "print('Content of it ->', empty_dict2)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To create a non-empty dictionary we specify pairs of **key:value** pattern" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Content of my_dict>>> {'name': 'Jarno', 'color': 'red', 'year': 2007, 'is cool': True, 6: 'it works', (2, 22): 'that is a strange key'}\n" + ] + } + ], + "source": [ + "my_dict = {\n", + " 'name': 'Jarno',\n", + " 'color': 'red',\n", + " 'year': 2007,\n", + " 'is cool': True,\n", + " 6: 'it works',\n", + " (2, 22): 'that is a strange key'\n", + "}\n", + "\n", + "print('Content of my_dict>>>', my_dict)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "2tQEahKqM9p8", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "In the last example, you can see that only strings, numbers, or tuples were used as keys. Dictionaries can only use immutable data (or numbers) as keys:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 242 + }, + "collapsed": true, + "id": "V38R-AweNbF7", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "6039cc3b-8d72-4f23-986f-e1027265aec5" + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "unhashable type: 'list'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[14], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m mutable_key_dict \u001b[39m=\u001b[39m {\n\u001b[0;32m 2\u001b[0m \u001b[39m5\u001b[39m: \u001b[39m'\u001b[39m\u001b[39mlets try\u001b[39m\u001b[39m'\u001b[39m,\n\u001b[0;32m 3\u001b[0m \u001b[39mTrue\u001b[39;00m: \u001b[39m'\u001b[39m\u001b[39mI hope it will run perfectly\u001b[39m\u001b[39m'\u001b[39m,\n\u001b[0;32m 4\u001b[0m \u001b[39m6.78\u001b[39m: \u001b[39m'\u001b[39m\u001b[39mheh\u001b[39m\u001b[39m'\u001b[39m,\n\u001b[0;32m 5\u001b[0m [\u001b[39m'\u001b[39m\u001b[39mNo problemo\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39mright?\u001b[39m\u001b[39m'\u001b[39m]: \u001b[39mFalse\u001b[39;00m \n\u001b[0;32m 6\u001b[0m }\n\u001b[0;32m 8\u001b[0m \u001b[39mprint\u001b[39m(mutable_key_dict)\n", + "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'" + ] + } + ], + "source": [ + "mutable_key_dict = {\n", + " 5: 'lets try',\n", + " True: 'I hope it will run perfectly',\n", + " 6.78: 'heh',\n", + " ['No problemo', 'right?']: False \n", + "}\n", + "\n", + "print(mutable_key_dict)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "erVQ8Yy6OFzW", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Alright, now it is time to access the data we have managed to store inside my_dict using keys!\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 313 + }, + "collapsed": true, + "id": "4_s_--xzORQx", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "d2dcabbb-057f-41e2-d54c-07d8ca3aa344" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Some random content of my_dict Jarno that is a strange key\n" + ] + } + ], + "source": [ + "print('Some random content of my_dict', my_dict['name'], my_dict[(2, 22)])" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Remember the mutable key dict? Let's make it work by omitting the list item." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accessing weird dictionary...\n", + "I hope it will run perfectly\n", + "lets try\n", + "heh\n" + ] + } + ], + "source": [ + "mutable_key_dict = {\n", + " 5: 'lets try',\n", + " True: 'I hope it will run perfectly',\n", + " 6.78: 'heh'\n", + "}\n", + "\n", + "\n", + "print('Accessing weird dictionary...')\n", + "print(mutable_key_dict[True])\n", + "print(mutable_key_dict[5])\n", + "print(mutable_key_dict[6.78])" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Trying to access something we have and something we don't have" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": true, + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "My favorite year is 2007\n" + ] + }, + { + "ename": "KeyError", + "evalue": "'song'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[17], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mMy favorite year is\u001b[39m\u001b[39m'\u001b[39m, my_dict[\u001b[39m'\u001b[39m\u001b[39myear\u001b[39m\u001b[39m'\u001b[39m])\n\u001b[1;32m----> 2\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mMy favorite song is\u001b[39m\u001b[39m'\u001b[39m, my_dict[\u001b[39m'\u001b[39;49m\u001b[39msong\u001b[39;49m\u001b[39m'\u001b[39;49m])\n", + "\u001b[1;31mKeyError\u001b[0m: 'song'" + ] + } + ], + "source": [ + "print('My favorite year is', my_dict['year'])\n", + "print('My favorite song is', my_dict['song'])" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "mVmNASbEPw27", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + ":::{warning} \n", + "It is best practice to use mainly strings as keys — the other options are weird and are almost never used.\n", + ":::\n", + "\n", + "What's next? Dictionaries are mutable, so let's go ahead and add some additional data and delete old ones." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "C2Tm8iaXQ4ej", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "62ea0bcc-a09b-474e-dd7b-e2688746ff31" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "my_dict right now {'name': 'Jarno', 'color': 'red', 'year': 2007, 'is cool': True, 6: 'it works', (2, 22): 'that is a strange key'}\n", + "my_dict after some operations {'name': 'Jarno', 'color': 'red', 'is cool': True, 6: 'it works', (2, 22): 'that is a strange key', 'new_element': 'magenta', 'weight': 27.8}\n" + ] + } + ], + "source": [ + "print('my_dict right now', my_dict)\n", + "\n", + "my_dict['new_element'] = 'magenta'\n", + "my_dict['weight'] = 27.8\n", + "del my_dict['year']\n", + "\n", + "print('my_dict after some operations', my_dict)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "J80LstNFSFeN", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "You can also print all keys present in the dictionary using the .keys() method, or check whether a certain key exists in a dictionary, as shown below. More operations can be found here." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "pEYa3nKRUZD1", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "2b850789-9071-414f-ce44-bb23203243a6" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dict_keys(['name', 'color', 'is cool', 6, (2, 22), 'new_element', 'weight'])\n", + "\n", + "my_dict has a ['name'] key: True\n" + ] + } + ], + "source": [ + "print(my_dict.keys())\n", + "print(\"\\nmy_dict has a ['name'] key:\", 'name' in my_dict)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "### Real life example: \n", + "\n", + "Analyzing satellite metadata

Metadata is a set of data that describes and gives information about other data. For Sentinel-1, the metadata of the satellite is acquired as an .xml file. It is common for Dictionaries to play an important role in classifying this metadata. One could write a function to read and obtain important information from this metadata and store them in a Dictionary. Some examples of keys for the metadata of Sentinel-1 are:\n", + " \n", + "_dict_keys(['azimuthSteeringRate', 'dataDcPolynomial', 'dcAzimuthtime', 'dcT0', 'rangePixelSpacing', 'azimuthPixelSpacing', 'azimuthFmRatePolynomial', 'azimuthFmRateTime', 'azimuthFmRateT0', 'radarFrequency', 'velocity', 'velocityTime', 'linesPerBurst', 'azimuthTimeInterval', 'rangeSamplingRate', 'slantRangeTime', 'samplesPerBurst', 'no_burst'])_\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "XvpRgp7eUsLP", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "The last important thing for this Notebook are slices. Similar to how you can slice a string (shown in Section 1.4, in Notebook 1). This technique allows you to select a subset of data from an iterable (like a list or a tuple)." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "S96Y3-HcXN3P", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "b0d9151f-f476-4ffa-de00-74f85a4b962c" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The first three elements of x: [1, 2, 3]\n", + "[1, 2, 3]\n", + "The last element is 7 or 7 or 7\n", + "[1, 2, 3]\n", + "[1, 2, 3]\n" + ] + } + ], + "source": [ + "x = [1, 2, 3, 4, 5, 6, 7]\n", + "n = len(x) \n", + "\n", + "print('The first three elements of x:', x[0:3])\n", + "print(x[:3])\n", + "print('The last element is', x[6], 'or', x[n - 1], 'or', x[-1])\n", + "print(x[0:-4])\n", + "print(x[0:3:1])" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`````{admonition} Let's break it down\n", + "This code demonstrates how to select specific elements from a list in Python using slicing:\n", + "\n", + "1. The list `x` contains numbers from 1 to 7.\n", + "2. `x[0:3]` selects the first three elements of `x`.\n", + "3. `x[:3]` achieves the same result by omitting the starting index.\n", + "4. `x[6]`, `x[n - 1]`, and `x[-1]` all access the last element of `x`.\n", + "5. `x[0:-4]` selects elements from the beginning to the fourth-to-last element.\n", + "6. `x[0:3:1]` selects elements with a step size of 1.\n", + "\n", + "`````" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "d4v9TBKyZJEh", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + } + }, + "source": [ + "Thus, the general slicing call is given by iterable[start:end:step]. \n", + "\n", + "Here's another example:\n", + "\n", + "You can select all even numbers using `[::2]` or reverse the list using `[::-1]` or select a middle subset for example `[5:9]`." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "collapsed": true, + "id": "GO8qP2d1ZXkq", + "nbgrader": { + "grade": false, + "locked": true, + "solution": false + }, + "outputId": "832458e8-6202-4fa8-8898-6d2a2a1ad423" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Selecting all even numbers [0, 2, 4, 6, 8, 10]\n", + "All odd numbers [1, 3, 5, 7, 9]\n", + "Normal order [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", + "Reversed order [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]\n", + "Numbers from 5 to 8: [5, 6, 7, 8]\n" + ] + } + ], + "source": [ + "numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", + "\n", + "print('Selecting all even numbers', numbers[::2])\n", + "print('All odd numbers', numbers[1::2])\n", + "print('Normal order', numbers)\n", + "print('Reversed order', numbers[::-1])\n", + "print('Numbers from 5 to 8:', numbers[5:9])" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Python_2_1.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.13" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/book/python.md b/book/python.md new file mode 100644 index 0000000..729f684 --- /dev/null +++ b/book/python.md @@ -0,0 +1,60 @@ +# Programming and Python + +## Why do you need Python? + +Python is a computer programming language that is widely used in both academia and industries related to Civil Engineering, Environmental Engineering and Applied Earth Sciences. Being skilled in Python will help you on multiple occasions, including in your master courses. + +## What can computers do for us? +As an engineer or scientist, you will deal with units of information which are called data. The most important tasks that a computer can do for us are: + +1. Reading data +2. Processing data +3. Visualizing data + +These are tasks that require many repetitions and high precision. + +_1. Reading data_ +Reading data means the computer acquires data from a source and places it into its volatile memory for processing. Volatile memory keeps the data stored until the power supply is interrupted. The way data is stored in a computer determines how the computer will be able to use it. + +_2. Processing data_ +Data processing is the manipulation of the stored data in a system. After processing data by performing transformations, calculations, and more, you get an output; results. + +_3. Visualizing data_ +We map data (original or found) to graphic elements to communicate clearly and efficiently the information contained in the data. A graphic element is an element of a chart, such as a line or a point in the chart. + +## What is programming? + +Programming is giving your computer a list of instructions for computations in a language it can understand. In your case, this language is Python. A computation is a series of arithmetical ("math") and non-arithmetical ("non-math") steps that transform input to output (result). +There are five different kinds of instructions for computations you use. By ordering and combining them, the computer can achieve results that fulfill the three tasks described earlier. The five kinds of instructions are: + +input: + Insert data from a file, the network, other devices, or simply by typing it in. + +output: + Display data on the screen, save them in a file, send it over the network, etc. + +math: + Perform basic mathematical operations like addition and multiplication. + +conditional execution: + Check for certain conditions before further instruction. + +repetition: + Perform instructions repeatedly, usually with some variation. + + +## Introduction to Python + +The features of Python are what make it so popular. From the definition available on the corresponding Wiki page: "Python is an interpreted high-level general-purpose programming language. Its design philosophy emphasizes code readability with its use of significant indentation. Its language constructs, as well as its object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.". Quite a simple, yet concise description due to the meaning hidden behind each buzzword: + +
    +
  • Interpreted means that there is an interpreter, a software tool, which reads and performs instructions written in Python. If your laptop, phone, or refrigerator has the interpreter, it can run most of the Python scripts! +
  • High-level means that the programming language operates with abstract and more easily understandable concepts. In other words, you don't have to write or understand, code related to the hardware part of your machine (like binary code or assembly). +
  • General-purpose means that the amount of Python application fields are endless. You can write Python scripts to manage and automate some primitive tasks for yourself, you can use it for data science, create your own machine / deep learning project, write your personal web application or even develop a game. +
  • Programming language means a set of specific predefined semantics, instructions, and syntax rules, which are used for writing necessary instructions. It is strictly defined, meaning that 99.99% of all errors in the code are made by the coder, not by the computer. +
+ +Python scripts run with the help of a Python interpreter, but they can be written by using different software tools. Just like as you write your essay (you can type it in Word, Google Docs, Overleaf, or even on plain paper) you can write your Python code with different editors. You could use the default notepad, notepad++, find a proper website with an inbuilt code editor & interpreter (IDEone, for example), or use specialized Python code editors (Spyder, PyCharm, Visual Studio, etc). In all cases you will produce a set of instructions, which are stored in a file with the *.py extension and the interpreter will run it completely (from top to bottom). + +For this course we will use a slightly different approach to developing a Python script: IPython and Jupyter Notebooks. Think of these as two freely-available tools that add extra functionality to the basic Python programming language. As an example, imagine the camera built into your phone: on it's own it can take pictures, but there are many apps that add filters or sharing via social media that make the impact of your photos much more powerful. This is exactly what IPython and Jupyter Notebooks do for Python, and why they are such important tools in the toolbox of modern engineers. The next Chapter will introduce you to your Python Toolbox for this course! + diff --git a/book/toolbox.md b/book/toolbox.md new file mode 100644 index 0000000..1154aeb --- /dev/null +++ b/book/toolbox.md @@ -0,0 +1,41 @@ +(toolbox)= +# Python Toolbox + +This page describes several ways to write and execute Python code, some of which don't require any installation on your computer and work entirely in a web browser! These approaches are described in the sections below, and are based on the tools IPython and Jupyter Notebooks. + +**IPython** is an interactive Python interpreter that adds features that are useful for engineering, such as command history or inline display of figures. As you will see below, you can enter multiple lines of text and evaluate them at once; this is often referred to as a *cell* of code. In a nutshell, if you string many of these cells together into a single digital document, you more or less end up with a **Jupyter Notebook**; this leverages the power of IPython by allowing you to type, run and save the cells in any order, as well as type formatted text in between. Together, these two tools make up our toolbox for this course, and, as you will see, both of them can run in your internet browser, so there is no need to install special software! + +## Interactive Pages + +This course is powered by a special software (the [Sphinx-Thebe](https://github.com/executablebooks/sphinx-thebe) that allows you to run Python code in your browser and gives you an experience that is more or less identical the the "standard" Jupyter Notebook experience you would have on your own computer if you installed the dedicated software. You can access this tool by clicking on the rocket icon ({fa}`rocket`) at the top right of a page where this is enabled. + +(calculator)= +## IPython: Your Primary Python Calculator + +Below is an example of an IPython interpreter embedded in this webpage, which we refer to as our **Python Calculator**. Note that the square brackets with numbers (e.g, `[1]: ...`) are a feature of IPython that keeps track of the cells you have run: the first (pre-loaded) command is a print statement that executes once the interpreter is ready for use. You can try entering code yourself (for example, type `x=2`) and executing it using `Shift+Enter`. You just defined a variable! Note that typing `Enter` in the interpreter adds extra lines, it does not execute the cell. Try entering multiple lines, for example, `3*x`, `Enter` and `print(x)`, then execute. Can you tell what happened? + + + +The simple exercise above should be all you need to get started with this course. Throughout this course we encourage you to the Python Calculator in a new browser tab, which will allow you to read the exercise and run code side by side. You can test it here in a new tab. When the console is critical for completing the exercises in a certain chapter, a drop-down note will be added that includes a special link inside, just like this: + +`````{admonition} Open the Python Calculator for this page +:class: tip, dropdown +Click this link and wait until the message "You may begin!" is printed to start evaluating code. More information about this tool can be found [here](calculator). + +Remember that most pages in this course can also be run interactively using the {fa}rocket icon above (read more about it [here](toolbox)). +````` + +All exercises in this course can be completed using only the Python Calculator. We hope you find it to be a simple but useful way to practice and learn the Python programming language. + +```{note} +A special instance of the Python Calculator is set up for each page which pre-loads a few packages needed to complete the exercise. Make sure you use link that is on the page of the exercises you are working on. +``` + +## Anaconda: Python on Your Computer + +If you want to explore Python programming and Jupyter ecosystems beyond the exercises covered in this course, it might be worthwhile to install a Python distribution on your own computer. The most common and easiest way to do this is with [Anaconda](https://www.anaconda.com/download). Installation instructions are not included in this course, but you can find plenty of website of videos that cover this, as well as using the Anaconda Navigator to open a Jupyter Lab or Jupyter Notebook environment. Most of the pages in this online textbook can be downloaded in the form of a Jupyter Notebook file (a file ending with `.ipynb`): open it via one of the Jupyter environments and you are ready to go! \ No newline at end of file diff --git a/docs/restructure.md b/docs/restructure.md new file mode 100644 index 0000000..53f9aa4 --- /dev/null +++ b/docs/restructure.md @@ -0,0 +1,10 @@ +# Restructuring the book + +Notes from Shiya and Robert early 2025 when chapters were broken down into smaller chapters and sections. + +- names of subdirectories changed from numbers to single words (e.g., `01` becomes `basics`), where the "home" page of that chapter has the same name and is located in the root directory of the book. For example, see `./book/basics.md` and `./book/basics/.md` +- Each chapter contains subdirectories `Exercises/` and `nutshell/` at minimum. +- Each nutshell chapter should have an identical file structure with subpage names to the main chapter +- Jupyter Quiz questions were converted to h5p questions. This is preseved with commented code in the subpage where the h5p exercise has been moved to. +- Small "checks" are kept on subpages, but bigger "exercises" are preserved on a final subpage in the chapter. +- Exercises/checks will be numbered using the automatic numbering of jupyter book and naming it "exercise" in the heading (e.g., `### Exercise` renders as "1.2.3 Exercise"). \ No newline at end of file