{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Python programming - Part I" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Greetings!\n", "\n", "We will be using Python as the programming language, and we will use this first lesson to make sure your Python distribution is working properly. We will also make sure you have a way to use the command line on your machine." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Python interpreter\n", "\n", "Before diving into the Python, I pause here to remind you that this course is meant to help you unleash the power of your computer on your scientific problems. Python is just the language of instruction. That said, let's start talking about how Python works.\n", "\n", "Python is an **interpreted language**, which means that each line of code you write is translated, or *interpreted*, into a set of instructions that your machine can understand by the **Python interpreter**. This stands in contrast to **compiled languages**. For these languages (the dominant ones being Fortran, C, and C++), your entire code is translated into machine language before you ever run it. When you execute your program, it is already in machine language.\n", "\n", "So, whenever you want your Python code to run, you give it to the Python interpreter.\n", "\n", "There are many ways to launch the Python interpreter. One way is to type\n", "\n", " python\n", " \n", "on the command line of a terminal. This launches the vanilla Python interpreter. We will never really use this in the course. Rather, we will have a *greatly* enhanced Python experience using a **notebook** through JupyterLab." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hello, world\n", "\n", "Traditionally, the first program anyone writes when learning a new language is called \"`Hello, world.`\" In this program, the words \"`Hello, world.`\" are printed on the screen.\n", "\n", "We will first write and run this little program using a JupyterLab console. After launching JupyterLab, you probably already have the Launcher in your JupyterLab window. If you do not, you can expand the `Files` tab at the left of your JupyterLab window (if it is not already expanded) by clicking on that tab, or alternatively hit `ctrl+b` (or `cmd+b` on macOS). At the top of the `Files` tab is a `+` sign, which gives you a Jupyter Launcher.\n", "\n", "In the Jupyter Launcher, click the `Python 3` icon under `Console`. This will launch a console, which has a large white space above a prompt that says `In []:`. You can enter Python code in this prompt, and it will be executed.\n", "\n", "To print `Hello, world.`, enter the code below. To execute the code, hit `shift+enter`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Hello, world.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hooray! We just printed `Hello, world.` to the screen. To do this, we used Python's built-in `print()` function. The `print()` function takes as an **argument** a **string**. It then prints that string to the screen. We will learn more about function syntax later, but we can already see the rough syntax with the `print()` function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## .py files\n", "\n", "Now let's use our new knowledge of the `print()` function to have our computer say a bit more than just `Hello, world.` Type these lines in at the prompt, hitting `enter` each time you need a new line. After you've typed them all in, hit `shift+enter` to run them." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The first few lines from The Zen of Python by Tim Peters\n", "print('Beautiful is better than ugly.')\n", "print('Explicit is better than implicit.')\n", "print('Simple is better than complex.')\n", "print('Complex is better than complicated.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the first line is preceded with a `#` sign, and the Python interpreter ignored it. The `#` sign denotes a **comment**, which is ignored by the interpreter, *but very very important for the human!*\n", "\n", "While the console prompt was nice entering all of this, a better option is to store them in a file, and then have the Python interpreter run the lines in the file. This is how you typically store Python code, and the suffix of such files is `.py`.\n", "\n", "So, let's create a `.py` file. To do this, use the JupyterLab Launcher to launch a text editor. Once it is launched, you can right click on the tab of the text editor window to change the name. We will call this file `zen.py`. Within this file, enter the four lines of code you previously entered in the console prompt. Be sure to save it.\n", "\n", "To run the code in this file, you can invoke the Python interpreter at the command line, followed by the file name. I.e., enter\n", "\n", " python zen.py\n", " \n", "at the command line. Note that when you run code this way, the interpreter exits after completion of running the code, and you do not get a prompt." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To shut down the console, you can click on the `Running` tab at the left of the JupyterLab window and click on `SHUTDOWN` next to the console." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## JupyterLab\n", "\n", "At this point, we have introduced JupyterLab, its text editor, and the console, as well as the Python interpreter itself. You might be asking...." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### What is Jupyter?\n", "\n", "From the [Project Jupyter website](http://jupyter.org):\n", ">Project Jupyter is an open source project was born out of the IPython Project in 2014 as it evolved to support interactive data science and scientific computing across all programming languages.\n", "\n", "So, Jupyter is an extension of IPython the pushes interactive computing further. It is language agnostic as its name suggests. The name \"Jupyter\" is a combination of [Julia](http://julialang.org/) (a new language for scientific computing), [Python](http://python.org/) (which you know and love), and [R](https://www.r-project.org) (the dominant tool for statistical computation). However, you can run over 40 different languages in a JupyterLab, not just Julia, Python, and R.\n", "\n", "Central to Jupyter/JupyterLab are **Jupyter notebooks**. In fact, the document you are reading right now was generated from a Jupyter notebook. We will use Jupyter notebooks extensively in the bootcamp, along with `.py` files and the console." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Why Jupyter notebooks?\n", "\n", "When writing code you will reuse, you should develop fully tested modules using `.py` files. You can always import those modules when you are using a Jupyter notebook (more on modules and importing them later in the bootcamp). So, a Jupyter notebook is not good for an application where you are building reusable code or scripts. However, Jupyter notebooks are **very** useful in the following applications.\n", "\n", "1. *Exploring data/analysis.* Jupyter notebooks are great for trying things out with code, or exploring a data set. This is an important part of the research process. The layout of Jupyter notebooks is great for organizing thoughts as you synthesize them.\n", "2. *Sharing your thinking in your analysis.* Because you can combine nicely formatted text and executable code, Jupyter notebooks are great for sharing how you go about doing your calculations with collaborators and with readers of your publications. Famously, LIGO used [a Jupyter notebook](https://losc.ligo.org/s/events/GW150914/GW150914_tutorial.html) to explain the signal processing involved in their first discovery of a gravitational wave.\n", "3. *Pedagogy.* All of the content in this class, including this lesson, was developed using Jupyter notebooks!\n", "\n", "Now that we know what Jupyter notebooks are and what the motivation is for using them, let's start!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Launching a Jupyter notebook\n", "\n", "To launch a Jupyter notebook, click on the `Notebook` icon of the JupyterLab launcher. If you want to open an existing notebook, right click on it in the `Files` tab of the JupyterLab window and open it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Cells\n", "\n", "A Jupyter notebook consists of **cells**. The two main types of cells you will use are **code cells** and **markdown cells**, and we will go into their properties in depth momentarily. First, an overview.\n", "\n", "A code cell contains actual code that you want to run. You can specify a cell as a code cell using the pulldown menu in the toolbar of your Jupyter notebook. Otherwise, you can can hit `Esc` and then `y` (denoted `Esc - y`\") while a cell is selected to specify that it is a code cell. Note that you will have to hit enter after doing this to start editing it.\n", "\n", "If you want to execute the code in a code cell, hit `Enter` while holding down the `Shift` key (denoted `Shift + Enter`). Note that code cells are executed in the order you shift-enter them. That is to say, the ordering of the cells for which you hit `Shift + Enter` is the order in which the code is executed. If you did not explicitly execute a cell early in the document, its results are not known to the Python interpreter. **This is a very important point and is often a source of confusion and frustration for students.**\n", "\n", "Markdown cells contain text. The text is written in **markdown**, a lightweight markup language. You can read about its syntax [here](http://daringfireball.net/projects/markdown/syntax). Note that you can also insert HTML into markdown cells, and this will be rendered properly. As you are typing the contents of these cells, the results appear as text. Hitting `Shift + Enter` renders the text in the formatting you specify.\n", "\n", "You can specify a cell as being a markdown cell in the Jupyter toolbar, or by hitting `Esc - m` in the cell. Again, you have to hit enter after using the quick keys to bring the cell into edit mode.\n", "\n", "In general, when you want to add a new cell, you can click the `+` icon on the notebook toolbar. The shortcut to insert a cell below is `Esc - b` and to insert a cell above is `Esc - a`. Alternatively, you can execute a cell and automatically add a new one below it by hitting `Alt + Enter`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Code cells\n", "\n", "Below is an example of a code cell printing `hello, world.` Notice that the output of the print statement appears in the same cell, though separate from the code block." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Say hello to the world.\n", "print('hello, world.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you evaluate a Python expression that returns a value, that value is displayed as output of the code cell. This only happens, however, for the last line of the code cell." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Would show 9 if this were the last line, but it is not, so shows nothing\n", "4 + 5\n", "\n", "# I hope we see 11.\n", "5 + 6" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Display of graphics\n", "\n", "When we learn about plotting with [matplotlib](https://matplotlib.org) and [seaborn](https://seaborn.pydata.org) later in the course, you will learn about displaying graphics in Jupyter notebooks." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Quick keys\n", "\n", "There are some keyboard shortcuts that are convenient to use in JupyterLab. We already encountered many of them. Importantly, pressing `Esc` brings you into command mode in which you are not editing the contents of a single cell, but are doing things like adding cells. Below are some useful quick keys. If two keys are separated by a `+` sign, they are pressed simultaneously, and if they are separated by a `-` sign, they are pressed in succession.\n", "\n", "|Quick keys | mode | action |\n", "|:---:|:---:|:---:|\n", "|`Alt + Enter` | both | run selected cell or cells - if no cells below, insert a code cell below |\n", "|`Esc` | edit | enter *command mode* |\n", "|`m` | command | switch cell to Markdown cell |\n", "|`y` | command | switch cell to code cell |\n", "|`a` | command | insert cell above |\n", "|`b` | command | insert cell below |\n", "|`Shift + M` | command | merge multiple selected cells into one cell |\n", "|`dd` | command | delete cell |\n", "|`Tab` | edit | code completion (or indent if at start of line) |\n", "|`Ctrl + /` | edit | toggle comment |\n", "|`Ctrl + ]` | edit | indent |\n", "|`Ctrl + [` | edit | dedent |\n", "|`Alt + Enter` | edit | execute cell and insert a cell below |\n", "\n", "There are [many others](https://gist.github.com/discdiver/9e00618756d120a8c9fa344ac1c375ac) (and they are shown in the pulldown menus within JupyterLab), but these are the ones I seem to encounter most often." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python as a powerful calculator\n", "\n", "### Python prompt and Read-Eval-Print Loop (REPL)\n", "\n", "Python is an *interpreted* language. We can collect sequences of commands into text files and save this to file as a *Python program*. It is convention that these files have the file extension “`.py`”, for example `hello.py`.\n", "\n", "We can also enter individual commands at the Python prompt which are immediately evaluated and carried out by the Python interpreter. This is very useful for the programmer/learner to understand how to use certain commands (often before one puts these commands together in a longer Python program). Python’s role can be described as Reading the command, Evaluating it, Printing the evaluated value and repeating (Loop) the cycle – this is the origin of the REPL abbreviation.\n", "\n", "Python comes with a basic terminal prompt; you may see examples from this with `>>>` marking the input:\n", "\n", "\n", " >>> 2 + 2\n", " 4\n", "\n", "We are using a more powerful REPL interface, the Jupyter Notebook. Blocks of code appear with an `In` prompt next to them:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "4 + 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To edit the code, click inside the code area. You should get a colored border around it. To run it, press Shift-Enter." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "10 + 10000" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "42 - 1.5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "47 * 11" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "10 / 0.5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 + 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This is a comment\n", "2 + 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 + 2 # and a comment on the same line as code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Parenthesis can be used for grouping:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 * 10 + 5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 * (10 + 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variables, operators and types\n", "\n", "Whether you are programming in Python or pretty much any other language, you will be working with **variables**. While the precise definition of a variable will vary from language to language, we'll focus on Python variables here. Like many of the concepts in this course, though, the knowledge you gain about Python variables will translate to other languages.\n", "\n", "We will talk more about **objects** later, but a variable, like everything in Python, is an object. For now, you can think of it this way. The following can be properties of a variable:\n", "1. The **type** of variable. E.g., is it an integer, like `2`, or a string, like `'Hello, world.'`?\n", "2. The **value** of the variable.\n", "\n", "Depending on the type of the variable, you can do different things to it and other variables of similar type. This, as with most things, is best explored by example. We'll go through some of the properties of variables and things you can do to them in this tutorial." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variable names in Python can contain alphanumerical characters `a-z`, `A-Z`, `0-9` and some special characters such as `_`. Normal variable names must start with a letter. \n", "\n", "By convention, variable names start with a lower-case letter, and Class names start with a capital letter. \n", "\n", "In addition, there are a number of Python keywords that cannot be used as variable names. These keywords are:\n", "\n", " False, None, True, and, as, assert, asyn, await, break, class, continue,\n", " def, del, elif, else, except, finally, for, from, global, if, import,\n", " in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield\n", "\n", "**Note:** *Be aware of the keyword `lambda`, which could easily be a natural variable name in a scientific program. But being a keyword, it cannot be used as a variable name.*" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# variable assignments\n", "x = 1.5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, Python creates the object `1.5`. Everything in Python is an object, and so is the floating point number 1.5. This object is stored somewhere in memory. Next, Python *binds a name to the object*. The name is `x`, and we often refer casually to `x` as a variable, an object, or even the value 1.5. However, technically, `x` is a name that is bound to the object `1.5`. Another way to say this is that `x` is a reference to the object.\n", "\n", "Note, however, if the last line does not return a value, such as if we assigned value to a variable, there is no visible output from the code cell.\n", "\n", "Once the variable `x` has been created through assignment of 0.5 in this example, we can make use of it:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x*3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Impossible equations aka assignments\n", "\n", "In computer programs we often find statements like" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = x + 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we read this as an equation as we are use to from mathematics,\n", "*x* = *x* + 1\n", " we could subtract *x* on both sides, to find that\n", "0 = 1.\n", " We know this is not true, so something is wrong here.\n", "\n", "The answer is that “equations“ in computer codes are not equations but *assignments*. They always have to be read in the following way two-step way:\n", "\n", "1. Evaluate the value on the right hand side of the equal sign\n", "\n", "2. Assign this value to the variable name shown on the left hand side. (In Python: bind the name on the left hand side to the object shown on the right hand side.)\n", "\n", "Some computer science literature uses the following notation to express assignments and to avoid the confusion with mathematical equations:\n", "\n", "$$x \\leftarrow x + 1$$\n", "\n", "Let’s apply our two-step rule to the assignment `x = x + 1` given above:\n", "\n", "1. Evaluate the value on the right hand side of the equal sign: for this we need to know what the current value of `x` is. Let’s assume `x` is currently `4`. In that case, the right hand side `x+1` evaluates to `5`.\n", "\n", "2. Assign this value (i.e. `5`) to the variable name shown on the left hand side `x`.\n", "\n", "Let’s confirm with the Python prompt that this is the correct interpretation:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 4 \n", "x = x + 1\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In Python, multiple assignments can be made in a single statement. Either single value can be assigned to several variables simultaneously:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = b = c = 0 # initialise a, b and c with 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or multiple values could be assigned to multiple variables using unpacking:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a, b, c = 5, 3.2, 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Although not explicitly specified, a variable does have a type associated with it. The type is derived from the value that was assigned to it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(4 / 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we assign a new value to a variable, its type can change." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we try to use a variable that has not yet been defined we get an `NameError`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Determining the type" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# integers\n", "x = 1\n", "type(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# float\n", "x = 1.0\n", "type(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# boolean\n", "b1 = True\n", "b2 = False\n", "\n", "type(b1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# complex numbers: note the use of `j` to specify the imaginary part\n", "x = 1.0 - 1.0j\n", "type(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(x.real, x.imag)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Type casting" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1.9\n", "\n", "print(x, type(x))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = int(x)\n", "\n", "print(x, type(x))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "z = complex(x)\n", "\n", "print(z, type(z))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a, b = 3+5j, complex(3, 5)\n", "print(a, b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = float(z)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Complex variables cannot be cast to floats or integers. We need to use `z.real` or `z.imag` to extract the part of the complex number we want:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(z.real, type(z.real))\n", "print(z.imag, type(z.imag))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operators and expressions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Operators** allow you to do things with variables, like add them. They are represented by special symbols, like `+` and `*`. For now, we will focus on **arithmetic** operators. Python's arithmetic operators are\n", "\n", "|action|operator|\n", "|:-------|:----------:|\n", "|addition | `+`|\n", "|subtraction | `-`|\n", "|multiplication | `*`|\n", "|division | `/`|\n", "|exponentiation | `**`|\n", "|modulus | `%`|\n", "|floor division | `//`|\n", "\n", "**Warning**: Do not use the `^` operator to raise to a power. That is actually the operator for bitwise XOR, which we will not cover in the course." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "10 % 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1 + 2, 1 - 2, 1 * 2, 1 / 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Integer division of float numbers\n", "3.0 // 2.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Note! The power operators in python isn't ^, but **\n", "2 ** 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and, using the fact that $\\sqrt[n]{x} = x^{1/n}$, we can compute the $\\sqrt{3} = 1.732050\\dots$ using `**`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3**0.5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(3*2)**4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Order of operations\n", "\n", "The order of operations is also as we would expect. Exponentiation comes first, followed by multiplication and division, floor division, and modulo. Next comes addition and subtraction. In order of precedence, our arithmetic operator table is\n", "\n", "|precedence|operators|\n", "|:-------:|:----------:|\n", "|1 | `**`|\n", "|2 | `*`, `/`, `//`, `%`|\n", "|3 | `+`, `-`|\n", "\n", "You can also group operations with parentheses. Operations within parentheses is are always evaluated first. As a watchout, *do not* use excessive parentheses. So often, I see students not trusting the order of operations and polluting their code with lots of parentheses, making it unreadable. This has been the source of countless bugs I've encountered in student code through the years.\n", "\n", "Let's practice." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1 + 4**2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1 + 4/2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "1**3 + 2**3 + 3**3 + 4**3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(1 + 2 + 3 + 4)**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interestingly, we also demonstrated that the sum of the first $n$ cubes is equal to the sum of the first $n$ integers **squared**. Fun!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Logical expressions\n", "* The boolean operators are spelled out as the words `and`, `not`, `or`. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "5 == 5.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "not False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "True or False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
expressionresult
true and truetrue
true and falsefalse
false and truefalse
false and falsefalse
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
expressionresult
not truefalse
not falsetrue
\n", "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
expressionresult
true or truetrue
true or falsetrue
false or truetrue
false or falsefalse
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Comparison operators `>`, `<`, `>=` (greater or equal), `<=` (less or equal), `==` equality, `is` identical." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 > 1, 2 < 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 > 2, 2 < 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2 >= 2, 2 <= 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# equality\n", "[1,2] == [1,2]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# objects identical?\n", "l1 = l2 = [1,2]\n", "\n", "l1 is l2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
OperatorWhat it means
==Equal to
!=Not equal to
<Less than
>Greater than
<=Less than or equal to
>=Greater than or equal to
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 4 }