{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Python Fundamentals\n", "\n", "Python is an **interpreted language**. By this we mean that the Python interpreter will run a program by executing the source code line-by-line without the need for compilation into machine code beforehand. Furthermore, Python is an **Object-Oriented Programming (OOP)** language. Everything we define in our code exists within the interpreter as a Python object, meaning it has associated **attributes** (data) and **methods** (functions that operate on that data). We will see these concepts in more detail later.\n", "\n", "First, let's have a look at the basics of any programming language. All programs consist of the following\n", "\n", "- Variables,\n", "- Functions,\n", "- Loops, and\n", "- Conditionals.\n", "\n", "### Variables\n", "\n", "Variables are basic elements of any programming language. They\n", "\n", "- store information,\n", "- can be manipulated by the program, and\n", "- can be of different types, e.g. integers, floating point numbers (floats), strings (sequences of characters), or booleans (true or false)\n", "\n", "#### Creating Variables\n", "\n", "Python is **dynamically typed**, meaning you don't need to declare variable types explicitly. The interpreter infers the type based on the assigned value. For example, the following code creates a variable `x` and assigns it the integer value `100`. The `type()` function is then used to check the type of the variable." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.705567Z", "iopub.status.busy": "2026-01-19T18:20:21.705076Z", "iopub.status.idle": "2026-01-19T18:20:21.712916Z", "shell.execute_reply": "2026-01-19T18:20:21.712094Z" } }, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 100\n", "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Python interpreter output `int`, indicating that `x` is of type integer.\n", "\n", "As the example above shows, you can create a variable by simply assigning a value to it using the equals sign (`=`). What happens under the hood is that Python creates an object in memory to store the value `100` and then creates a reference (the variable name `x`) that points to that object. When you later use the variable `x` in your code, Python retrieves the value from the memory location that `x` references. For example, we can then do computations with `x`:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.753621Z", "iopub.status.busy": "2026-01-19T18:20:21.753356Z", "iopub.status.idle": "2026-01-19T18:20:21.756547Z", "shell.execute_reply": "2026-01-19T18:20:21.756092Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "150\n" ] } ], "source": [ "y = x + 50\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python retrieved the value of `x` (which is `100`), added `50` to it, and assigned the result to the new variable `y`.\n", "\n", "Note that you can reassign variables to new values or even different types. For example, you can change the value of `x` simply by assigning a new value to it" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.758885Z", "iopub.status.busy": "2026-01-19T18:20:21.758657Z", "iopub.status.idle": "2026-01-19T18:20:21.761479Z", "shell.execute_reply": "2026-01-19T18:20:21.761020Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "200\n" ] } ], "source": [ "x = 200\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that now `x` points to a new object in memory with the value `200`. The previous object with the value `100` will be automatically cleaned up by Python's garbage collector if there are no other references to it. This might not seem important now, but there are some implications of this behavior when working with mutable objects, which we will cover later.\n", "\n", "\n", "#### Naming Variables\n", "\n", "The process of naming variables is an important aspect of programming. Good variable names enhance code readability and maintainability, making it easier for others (and yourself) to understand the purpose of each variable. \n", "\n", "For example, consider the following two variable names" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.763652Z", "iopub.status.busy": "2026-01-19T18:20:21.763437Z", "iopub.status.idle": "2026-01-19T18:20:21.765946Z", "shell.execute_reply": "2026-01-19T18:20:21.765431Z" } }, "outputs": [], "source": [ "a = 25\n", "number_of_students = 25" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first variable name, `a`, is vague and does not convey any information about what it represents. In contrast, `number_of_students` is descriptive and clearly indicates that the variable holds the count of students. This makes the code more understandable, especially in larger programs where many variables are used.\n", "\n", "Python imposes certain rules on how variable names can be constructed:\n", "\n", "1. They must start with a letter (a-z, A-Z) or an underscore (_).\n", "2. They can only contain letters, numbers (0-9), and underscores.\n", "3. They cannot be the same as Python's reserved keywords (e.g., `if`, `else`, `while`, `for`, etc.). `help(keywords)` will show which words are reserved.\n", "4. Variable names are case-sensitive, meaning that `Variable`, `variable`, and `VARIABLE` would be considered different variables.\n", "\n", "In addition to these rules, good practices for naming variables include to\n", "\n", "- Use meaningful and descriptive names that convey the purpose of the variable\n", "- Use lowercase letters and separate words with underscores (`snake_case`) for better readability (some programmers use `camelCase`, but snake_case is preferred in Python)\n", "- Avoid using single-letter names except for loop counters or very short-lived variables\n", "- Avoid using built-in function names because that will overwrite the function (i.e., if we write `type` we will no longer be able to use `type` to access the `type` of variables)\n", "- Be consistent with naming conventions throughout your codebase\n", "- While you can use names in any language, English is generally preferred so that anyone can follow the code\n", "\n", "The following code snippet lists all reserved keywords in Python that cannot be used as variable names" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.768256Z", "iopub.status.busy": "2026-01-19T18:20:21.768035Z", "iopub.status.idle": "2026-01-19T18:20:21.771329Z", "shell.execute_reply": "2026-01-19T18:20:21.770914Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "None\n", "True\n", "and\n", "as\n", "assert\n", "async\n", "await\n", "break\n", "class\n", "continue\n", "def\n", "del\n", "elif\n", "else\n", "except\n", "finally\n", "for\n", "from\n", "global\n", "if\n", "import\n", "in\n", "is\n", "lambda\n", "nonlocal\n", "not\n", "or\n", "pass\n", "raise\n", "return\n", "try\n", "while\n", "with\n", "yield\n" ] } ], "source": [ "import keyword\n", "\n", "for kw in keyword.kwlist:\n", " print(kw)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Make sure you don't use any of these words as variable names in your code.\n", "\n", "\n", "#### Basic Data Types\n", "\n", "Python has several built-in data types that are commonly used:\n", "\n", "- **Integers (`int`)**: Whole numbers, e.g., `42`, `-7`\n", "- **Floating-point numbers (`float`)**: Numbers with decimal points, e.g., `3.14`, `-0.001`\n", "- **Complex numbers (`complex`)**: Numbers with real and imaginary parts, e.g., `2 + 3j`\n", "- **Strings (`str`)**: Sequences of characters enclosed in single or double quotes, e.g., `'Hello, World!'`, `\"Python\"`\n", "- **Booleans (`bool`)**: Logical values representing `True` or `False`\n", "\n", "Since Python is dynamically typed, the creation of variables of these types is straightforward, as shown in the following examples:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.773427Z", "iopub.status.busy": "2026-01-19T18:20:21.773229Z", "iopub.status.idle": "2026-01-19T18:20:21.776436Z", "shell.execute_reply": "2026-01-19T18:20:21.775975Z" } }, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "this_is_int = 5\n", "type(this_is_int)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.778456Z", "iopub.status.busy": "2026-01-19T18:20:21.778247Z", "iopub.status.idle": "2026-01-19T18:20:21.781524Z", "shell.execute_reply": "2026-01-19T18:20:21.781096Z" } }, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "this_is_float = 3.14\n", "type(this_is_float)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.783638Z", "iopub.status.busy": "2026-01-19T18:20:21.783432Z", "iopub.status.idle": "2026-01-19T18:20:21.786834Z", "shell.execute_reply": "2026-01-19T18:20:21.786314Z" } }, "outputs": [ { "data": { "text/plain": [ "complex" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "this_is_complex = 2 + 3j\n", "type(this_is_complex)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.788976Z", "iopub.status.busy": "2026-01-19T18:20:21.788747Z", "iopub.status.idle": "2026-01-19T18:20:21.792257Z", "shell.execute_reply": "2026-01-19T18:20:21.791742Z" } }, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "this_is_str = \"Hello, Python!\"\n", "type(this_is_str)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.794319Z", "iopub.status.busy": "2026-01-19T18:20:21.794109Z", "iopub.status.idle": "2026-01-19T18:20:21.797562Z", "shell.execute_reply": "2026-01-19T18:20:21.797095Z" } }, "outputs": [ { "data": { "text/plain": [ "bool" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "this_is_bool = True\n", "type(this_is_bool)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that boolean values are special in the sense that they are equivalent to integers: `True` is equivalent to `1` and `False` is equivalent to `0`. This means you can perform arithmetic operations with boolean values, and they will behave like integers in those contexts.\n", "\n", "There is another data type called `NoneType`, which you might encounter. It represents the absence of a value and is created using the `None` keyword." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.799786Z", "iopub.status.busy": "2026-01-19T18:20:21.799575Z", "iopub.status.idle": "2026-01-19T18:20:21.802812Z", "shell.execute_reply": "2026-01-19T18:20:21.802358Z" } }, "outputs": [ { "data": { "text/plain": [ "NoneType" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "this_is_none = None\n", "type(this_is_none)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also create more complex data types, which we will cover in the section on data structures.\n", "\n", "\n", "#### Basic Operations\n", "\n", "A key element of programming is manipulating the variables you create. Python supports various basic operations for different data types, including arithmetic operations for numbers, string operations for text, and boolean operations for logical values.\n", "\n", "**Arithmetic Operations**: You can perform arithmetic operations on integers and floats using operators like `+`, `-`, `*`, `/`, `//` (floor division), `%` (modulus), and `**` (exponentiation)." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.804888Z", "iopub.status.busy": "2026-01-19T18:20:21.804686Z", "iopub.status.idle": "2026-01-19T18:20:21.807067Z", "shell.execute_reply": "2026-01-19T18:20:21.806650Z" } }, "outputs": [], "source": [ "a = 10\n", "b = 3" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.808870Z", "iopub.status.busy": "2026-01-19T18:20:21.808687Z", "iopub.status.idle": "2026-01-19T18:20:21.811445Z", "shell.execute_reply": "2026-01-19T18:20:21.810922Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "13\n" ] } ], "source": [ "sum_result = a + b # Addition\n", "print(sum_result)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.813270Z", "iopub.status.busy": "2026-01-19T18:20:21.813101Z", "iopub.status.idle": "2026-01-19T18:20:21.815531Z", "shell.execute_reply": "2026-01-19T18:20:21.815113Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7\n" ] } ], "source": [ "diff_result = a - b # Subtraction\n", "print(diff_result)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.817544Z", "iopub.status.busy": "2026-01-19T18:20:21.817371Z", "iopub.status.idle": "2026-01-19T18:20:21.820581Z", "shell.execute_reply": "2026-01-19T18:20:21.819838Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "30\n" ] } ], "source": [ "prod_result = a * b # Multiplication\n", "print(prod_result)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.822997Z", "iopub.status.busy": "2026-01-19T18:20:21.822779Z", "iopub.status.idle": "2026-01-19T18:20:21.826286Z", "shell.execute_reply": "2026-01-19T18:20:21.825886Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.3333333333333335\n" ] } ], "source": [ "div_result = a / b # Division\n", "print(div_result)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.828535Z", "iopub.status.busy": "2026-01-19T18:20:21.828322Z", "iopub.status.idle": "2026-01-19T18:20:21.831281Z", "shell.execute_reply": "2026-01-19T18:20:21.830876Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "floor_div_result = a // b # Floor Division\n", "print(floor_div_result)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.833504Z", "iopub.status.busy": "2026-01-19T18:20:21.833276Z", "iopub.status.idle": "2026-01-19T18:20:21.836340Z", "shell.execute_reply": "2026-01-19T18:20:21.835893Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "mod_result = a % b # Modulus\n", "print(mod_result)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.838893Z", "iopub.status.busy": "2026-01-19T18:20:21.838653Z", "iopub.status.idle": "2026-01-19T18:20:21.841685Z", "shell.execute_reply": "2026-01-19T18:20:21.841247Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1000\n" ] } ], "source": [ "exp_result = a ** b # Exponentiation\n", "print(exp_result)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**String Operations**: Strings can be concatenated using the `+` operator and repeated using the `*` operator." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.843868Z", "iopub.status.busy": "2026-01-19T18:20:21.843648Z", "iopub.status.idle": "2026-01-19T18:20:21.846837Z", "shell.execute_reply": "2026-01-19T18:20:21.846358Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, World!\n" ] } ], "source": [ "str1 = \"Hello, \"\n", "str2 = \"World!\"\n", "concat_str = str1 + str2 # Concatenation\n", "print(concat_str)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes, you may want to repeat a string multiple times" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.849201Z", "iopub.status.busy": "2026-01-19T18:20:21.848958Z", "iopub.status.idle": "2026-01-19T18:20:21.852073Z", "shell.execute_reply": "2026-01-19T18:20:21.851634Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Hello, Hello, \n" ] } ], "source": [ "repeat_str = str1 * 3 # Repetition\n", "print(repeat_str)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another useful operation is string interpolation, which allows you to embed variables within strings. This can be done using f-strings (formatted string literals) by prefixing the string with `f` and including expressions inside curly braces `{}`." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.854433Z", "iopub.status.busy": "2026-01-19T18:20:21.854198Z", "iopub.status.idle": "2026-01-19T18:20:21.857655Z", "shell.execute_reply": "2026-01-19T18:20:21.857103Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Her name is Alba and she is 30 years old.\n" ] } ], "source": [ "name = \"Alba\"\n", "age = 30\n", "intro_str = f\"Her name is {name} and she is {age} years old.\"\n", "print(intro_str)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Boolean Operations**: You can use logical operators like `and`, `or`, and `not` to combine or negate boolean values." ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.860048Z", "iopub.status.busy": "2026-01-19T18:20:21.859815Z", "iopub.status.idle": "2026-01-19T18:20:21.863030Z", "shell.execute_reply": "2026-01-19T18:20:21.862538Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "bool1 = True\n", "bool2 = False\n", "and_result = bool1 and bool2 # Logical AND\n", "print(and_result)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.865207Z", "iopub.status.busy": "2026-01-19T18:20:21.864989Z", "iopub.status.idle": "2026-01-19T18:20:21.868104Z", "shell.execute_reply": "2026-01-19T18:20:21.867639Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "or_result = bool1 or bool2 # Logical OR\n", "print(or_result)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.870349Z", "iopub.status.busy": "2026-01-19T18:20:21.870102Z", "iopub.status.idle": "2026-01-19T18:20:21.873080Z", "shell.execute_reply": "2026-01-19T18:20:21.872643Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "not_result = not bool1 # Logical NOT\n", "print(not_result)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To compare values, you can use comparison operators like `==` (equal to), `!=` (not equal to), `<` (less than), `>` (greater than), `<=` (less than or equal to), and `>=` (greater than or equal to)." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.875364Z", "iopub.status.busy": "2026-01-19T18:20:21.875143Z", "iopub.status.idle": "2026-01-19T18:20:21.877779Z", "shell.execute_reply": "2026-01-19T18:20:21.877245Z" } }, "outputs": [], "source": [ "a = 10\n", "b = 20" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.880086Z", "iopub.status.busy": "2026-01-19T18:20:21.879824Z", "iopub.status.idle": "2026-01-19T18:20:21.882989Z", "shell.execute_reply": "2026-01-19T18:20:21.882394Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "eq_result = (a == b) # Equal to\n", "print(eq_result)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.885322Z", "iopub.status.busy": "2026-01-19T18:20:21.885083Z", "iopub.status.idle": "2026-01-19T18:20:21.888005Z", "shell.execute_reply": "2026-01-19T18:20:21.887515Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "neq_result = (a != b) # Not equal to\n", "print(neq_result)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.890293Z", "iopub.status.busy": "2026-01-19T18:20:21.890071Z", "iopub.status.idle": "2026-01-19T18:20:21.893041Z", "shell.execute_reply": "2026-01-19T18:20:21.892609Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "lt_result = (a < b) # Less than\n", "print(lt_result)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.895152Z", "iopub.status.busy": "2026-01-19T18:20:21.894937Z", "iopub.status.idle": "2026-01-19T18:20:21.897928Z", "shell.execute_reply": "2026-01-19T18:20:21.897492Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "gt_result = (a > b) # Greater than\n", "print(gt_result)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.900008Z", "iopub.status.busy": "2026-01-19T18:20:21.899799Z", "iopub.status.idle": "2026-01-19T18:20:21.902715Z", "shell.execute_reply": "2026-01-19T18:20:21.902289Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "le_result = (a <= b) # Less than or equal to\n", "print(le_result)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.904710Z", "iopub.status.busy": "2026-01-19T18:20:21.904515Z", "iopub.status.idle": "2026-01-19T18:20:21.907302Z", "shell.execute_reply": "2026-01-19T18:20:21.906886Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "ge_result = (a >= b) # Greater than or equal to\n", "print(ge_result)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the result of comparison operations is always a boolean value (`True` or `False`). This will be useful when we discuss conditional statements later.\n", "\n", ":::{.callout-warning}\n", "\n", "Be careful not to confuse the assignment operator `=` with the equality comparison operator `==`. The single equals sign `=` assigns a value to a variable, while the double equals sign `==` checks if two values are equal and returns a boolean result.\n", "\n", ":::\n", "\n", "\n", "We can also combine multiple comparison operations using logical operators. For example, to check if a number is within a certain range, we can use the `and` operator" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.909488Z", "iopub.status.busy": "2026-01-19T18:20:21.909294Z", "iopub.status.idle": "2026-01-19T18:20:21.912239Z", "shell.execute_reply": "2026-01-19T18:20:21.911800Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "num = 15\n", "is_in_range = (num > 10) and (num < 20)\n", "print(is_in_range)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This checks if `num` is greater than `10` and less than `20`, returning `True` if both conditions are met. Of course, we can also use `or` to check if at least one condition is met or `not` to negate a condition.\n", "\n", "\n", "### Functions\n", "\n", "Functions are reusable blocks of code that perform a specific task. They help organize code, improve readability, and allow for code reuse. In Python, you define a function using the `def` keyword, followed by the function name and parentheses containing any parameters. For example, here is a simple function that takes two arguments, performs a calculation, and returns the result" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.914381Z", "iopub.status.busy": "2026-01-19T18:20:21.914176Z", "iopub.status.idle": "2026-01-19T18:20:21.916591Z", "shell.execute_reply": "2026-01-19T18:20:21.916137Z" } }, "outputs": [], "source": [ "def function_name(arg1, arg2):\n", " r3 = arg1 + arg2\n", " return r3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the indentation (whitespace at the beginning of a line) is crucial in Python, as it defines the scope of the function. The code block inside the function must be indented consistently. In the example above, two spaces are used for indentation, but tabs or four spaces are also common conventions. VSCode will automatically convert tabs to spaces based on your settings and the convention used in the file.\n", "\n", "Suppose we want to create a function that greets a user by their name. We can define such a function as follows" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.918787Z", "iopub.status.busy": "2026-01-19T18:20:21.918587Z", "iopub.status.idle": "2026-01-19T18:20:21.921191Z", "shell.execute_reply": "2026-01-19T18:20:21.920689Z" } }, "outputs": [], "source": [ "def greet(name):\n", " greeting = f\"Hello, {name}!\"\n", " return greeting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can then call the function by passing the required argument" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.923301Z", "iopub.status.busy": "2026-01-19T18:20:21.923101Z", "iopub.status.idle": "2026-01-19T18:20:21.925830Z", "shell.execute_reply": "2026-01-19T18:20:21.925427Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Alba!\n" ] } ], "source": [ "message = greet(\"Alba\")\n", "print(message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could also define the function without a return value and simply print the greeting directly" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.928095Z", "iopub.status.busy": "2026-01-19T18:20:21.927886Z", "iopub.status.idle": "2026-01-19T18:20:21.930427Z", "shell.execute_reply": "2026-01-19T18:20:21.930019Z" } }, "outputs": [], "source": [ "def greet_print(name):\n", " print(f\"Hello, {name}!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can call this function in the same way" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.932466Z", "iopub.status.busy": "2026-01-19T18:20:21.932248Z", "iopub.status.idle": "2026-01-19T18:20:21.935163Z", "shell.execute_reply": "2026-01-19T18:20:21.934717Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Alba!\n" ] } ], "source": [ "greet_print(\"Alba\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also define functions with multiple outputs by returning a tuple of values. For example, here is a function that takes two numbers and returns both their sum and product" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.937561Z", "iopub.status.busy": "2026-01-19T18:20:21.937334Z", "iopub.status.idle": "2026-01-19T18:20:21.940178Z", "shell.execute_reply": "2026-01-19T18:20:21.939731Z" } }, "outputs": [], "source": [ "def sum_and_product(x, y):\n", " sum_result = x + y\n", " product_result = x * y\n", " return sum_result, product_result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can call this function and unpack the returned values into separate variables" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.942354Z", "iopub.status.busy": "2026-01-19T18:20:21.942146Z", "iopub.status.idle": "2026-01-19T18:20:21.945114Z", "shell.execute_reply": "2026-01-19T18:20:21.944639Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sum: 15, Product: 50\n" ] } ], "source": [ "s, p = sum_and_product(5, 10)\n", "print(f\"Sum: {s}, Product: {p}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or you can capture the returned tuple in a single variable" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.947253Z", "iopub.status.busy": "2026-01-19T18:20:21.947048Z", "iopub.status.idle": "2026-01-19T18:20:21.950028Z", "shell.execute_reply": "2026-01-19T18:20:21.949488Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Result: (15, 50)\n" ] } ], "source": [ "result = sum_and_product(5, 10)\n", "print(f\"Result: {result}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can define functions with multiple `return` statements to handle different conditions. For example, here is a function that checks if a number is positive, negative, or zero and returns an appropriate message" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.952382Z", "iopub.status.busy": "2026-01-19T18:20:21.952186Z", "iopub.status.idle": "2026-01-19T18:20:21.954850Z", "shell.execute_reply": "2026-01-19T18:20:21.954455Z" } }, "outputs": [], "source": [ "def check_number(num):\n", " if num > 0:\n", " return \"Positive\"\n", " elif num < 0:\n", " return \"Negative\"\n", " else:\n", " return \"Zero\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can call this function with different numbers to see the results" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.956706Z", "iopub.status.busy": "2026-01-19T18:20:21.956531Z", "iopub.status.idle": "2026-01-19T18:20:21.959233Z", "shell.execute_reply": "2026-01-19T18:20:21.958882Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Positive\n", "Negative\n", "Zero\n" ] } ], "source": [ "print(check_number(10)) # Output: Positive\n", "print(check_number(-5)) # Output: Negative\n", "print(check_number(0)) # Output: Zero" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you pass a variable to a function, the function receives a local copy of that value. Modifying this copy inside the function does not affect the original variable outside. However, if you need to modify a variable defined outside the function (a global variable), you must explicitly declare it using the global keyword. The difference between local and global variables is also called the scope of a variable. The following example illustrates the difference" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.961238Z", "iopub.status.busy": "2026-01-19T18:20:21.961048Z", "iopub.status.idle": "2026-01-19T18:20:21.964745Z", "shell.execute_reply": "2026-01-19T18:20:21.964349Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Input you gave me 10\n", "Inside the function - modified input_var: 15\n", "Outside the function - global_var: 10\n", "Input you gave me 10\n", "Inside the function - modified global_var: 20\n", "Outside the function - global_var: 20\n" ] } ], "source": [ "global_var = 10\n", "\n", "def edit_input(input_var):\n", "\n", " # Access the input variable\n", " print(\"Input you gave me\", input_var) \n", "\n", " input_var = input_var + 5 # This modifies the local copy of input_var and not global_var\n", " print(\"Inside the function - modified input_var:\", input_var)\n", "\n", " return input_var # Return the modified value\n", "\n", "def edit_global(input_var):\n", "\n", " global global_var # Make global_var accessible inside the function\n", "\n", " # Access the input variable\n", " print(\"Input you gave me\", input_var) \n", "\n", " global_var = global_var + input_var # This modifies the global variable\n", " print(\"Inside the function - modified global_var:\", global_var)\n", "\n", " return None\n", "\n", "# Call the function\n", "edit_input(global_var)\n", "print(\"Outside the function - global_var:\", global_var) \n", "\n", "# Call the function\n", "edit_global(global_var)\n", "print(\"Outside the function - global_var:\", global_var) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Oftentimes it is better to avoid global variables if possible, as they can lead to code that is harder to understand and maintain. Instead, prefer passing variables as arguments to functions and returning results. For example, if you would like to modify the value of `global_var`, you could simply assign the returned value of the function to it" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.967086Z", "iopub.status.busy": "2026-01-19T18:20:21.966898Z", "iopub.status.idle": "2026-01-19T18:20:21.969621Z", "shell.execute_reply": "2026-01-19T18:20:21.969195Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Input you gave me 20\n", "Inside the function - modified input_var: 25\n", "Outside the function - global_var: 25\n" ] } ], "source": [ "global_var = edit_input(global_var)\n", "print(\"Outside the function - global_var:\", global_var) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Functions can also have **default arguments**, which are used if no value is provided when the function is called. For example, here is a function that greets a user with a default name if none is provided" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.971468Z", "iopub.status.busy": "2026-01-19T18:20:21.971300Z", "iopub.status.idle": "2026-01-19T18:20:21.974108Z", "shell.execute_reply": "2026-01-19T18:20:21.973725Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Guest!\n", "Hello, Jesus!\n" ] } ], "source": [ "def greet_with_default(name=\"Guest\"):\n", " print(f\"Hello, {name}!\")\n", "\n", "greet_with_default()\n", "greet_with_default(\"Jesus\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We used the same function, once without providing an argument (so it uses the default value \"Guest\") and once with a specific name (\"Jesus\").\n", "\n", "We can also use **keyword arguments** to call functions. This allows us to specify the names of the parameters when calling the function, making it clear what each argument represents. For example" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.975904Z", "iopub.status.busy": "2026-01-19T18:20:21.975732Z", "iopub.status.idle": "2026-01-19T18:20:21.978570Z", "shell.execute_reply": "2026-01-19T18:20:21.978161Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My name is Alba and I am 30 years old.\n" ] } ], "source": [ "def introduce(name, age):\n", " print(f\"My name is {name} and I am {age} years old.\")\n", "\n", "introduce(name=\"Alba\", age=30)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can even change the order of the arguments when using keyword arguments, as shown above. You can also mix positional and keyword arguments, but positional arguments must come before keyword arguments." ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.980431Z", "iopub.status.busy": "2026-01-19T18:20:21.980266Z", "iopub.status.idle": "2026-01-19T18:20:21.983517Z", "shell.execute_reply": "2026-01-19T18:20:21.982420Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "My name is Alba and I am 30 years old.\n" ] } ], "source": [ "introduce(\"Alba\", age=30) # This works" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.985954Z", "iopub.status.busy": "2026-01-19T18:20:21.985778Z", "iopub.status.idle": "2026-01-19T18:20:21.988185Z", "shell.execute_reply": "2026-01-19T18:20:21.987719Z" } }, "outputs": [], "source": [ "#| error: true\n", "#introduce(age=30, \"Alba\") # This will raise a SyntaxError" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Positional arguments must be provided in the correct order, starting from the first parameter defined in the function. If you try to provide them in the wrong order, Python will raise a `TypeError`. For example, the following code will raise an error because the first argument is expected to be `name`, but we intended to provide an integer for `age`." ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.990532Z", "iopub.status.busy": "2026-01-19T18:20:21.990358Z", "iopub.status.idle": "2026-01-19T18:20:21.992694Z", "shell.execute_reply": "2026-01-19T18:20:21.992186Z" } }, "outputs": [], "source": [ "#| error: true\n", "#introduce(30, name=\"Alba\") # This will raise a TypeError" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, note that the function needs to be defined before it is called in the code. If you try to call a function before its definition, Python will raise a `NameError` indicating that the function is not defined." ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.994710Z", "iopub.status.busy": "2026-01-19T18:20:21.994533Z", "iopub.status.idle": "2026-01-19T18:20:21.996948Z", "shell.execute_reply": "2026-01-19T18:20:21.996542Z" } }, "outputs": [], "source": [ "#| error: true\n", "#test_function() # This will raise a NameError\n", "\n", "def test_function():\n", " print(\"This is a test function.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But the following will work correctly" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:21.998923Z", "iopub.status.busy": "2026-01-19T18:20:21.998743Z", "iopub.status.idle": "2026-01-19T18:20:22.002128Z", "shell.execute_reply": "2026-01-19T18:20:22.001650Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a test function.\n" ] } ], "source": [ "def test_function():\n", " print(\"This is a test function.\")\n", "\n", "test_function() # This will work correctly" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For this reason, function definitions are often placed at the beginning of a script or notebook cell, before any calls to those functions.\n", "\n", "\n", "\n", "### Conditional statements\n", "\n", "Conditional statements allow you to control the flow of your program based on certain conditions. In Python, you can use `if`, `elif`, and `else` statements to execute different blocks of code depending on whether a condition is true or false. We have already seen an example of this in the `check_number` function above.\n", "\n", "In the following example, the `do_something()` function will only be executed if `condition` evaluates to `True`, while `do_some_other_thing()` will always be executed.\n", "\n", "```python\n", "if condition:\n", " do_something()\n", "\n", "do_some_other_thing()\n", "```\n", "\n", "It is important to note that Python uses indentation to define the scope of code blocks. The code inside the `if` statement must be indented consistently to indicate that it belongs to that block.\n" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.004039Z", "iopub.status.busy": "2026-01-19T18:20:22.003831Z", "iopub.status.idle": "2026-01-19T18:20:22.006843Z", "shell.execute_reply": "2026-01-19T18:20:22.006439Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is greater than 5\n", "This line is also part of the if block\n", "This line is outside the if block\n" ] } ], "source": [ "a = 10\n", "\n", "if a > 5:\n", " print(\"a is greater than 5\")\n", " print(\"This line is also part of the if block\")\n", "\n", "print(\"This line is outside the if block\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also nest `if` statements within each other to create more complex conditions. For example" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.008888Z", "iopub.status.busy": "2026-01-19T18:20:22.008702Z", "iopub.status.idle": "2026-01-19T18:20:22.011809Z", "shell.execute_reply": "2026-01-19T18:20:22.011342Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is between 5 and 15\n" ] } ], "source": [ "a = 10\n", "\n", "if a > 5:\n", " if a < 15:\n", " print(\"a is between 5 and 15\")\n", " else:\n", " print(\"a is greater than or equal to 15\")\n", "else:\n", " print(\"a is less than or equal to 5\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, we first check if `a` is greater than `5`. If that condition is true, we then check if `a` is less than `15`. Depending on the outcome of these checks, different messages will be printed. Compared to the previous example, we also used an `else` statement to handle the case where `a` is not less than `15`.\n", "\n", "We can also use `elif` (short for \"else if\") to check multiple conditions in a more concise way. For example" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.013818Z", "iopub.status.busy": "2026-01-19T18:20:22.013474Z", "iopub.status.idle": "2026-01-19T18:20:22.016838Z", "shell.execute_reply": "2026-01-19T18:20:22.016269Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is between 5 and 15\n" ] } ], "source": [ "a = 10\n", "\n", "if a < 5:\n", " print(\"a is less than 5\")\n", "elif a < 15:\n", " print(\"a is between 5 and 15\")\n", "else:\n", " print(\"a is greater than or equal to 15\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To reach the `elif` block, the first `if` condition must evaluate to `False`. If it evaluates to `True`, the code inside that block will be executed, and the rest of the conditions will be skipped. If none of the conditions are met, the code inside the `else` block will be executed.\n", "\n", "Note that if statements can also be written in a single line using a ternary conditional operator. For example" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.019079Z", "iopub.status.busy": "2026-01-19T18:20:22.018896Z", "iopub.status.idle": "2026-01-19T18:20:22.021668Z", "shell.execute_reply": "2026-01-19T18:20:22.021287Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is greater than 5\n" ] } ], "source": [ "a = 10\n", "result = \"a is greater than 5\" if a > 5 else \"a is less than or equal to 5\"\n", "print(result)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above code assigns a different string to the variable `result` based on the condition `a > 5`. If the condition is true, it assigns \"a is greater than 5\"; otherwise, it assigns \"a is less than or equal to 5\".\n", "\n", "\n", "### Loops\n", "\n", "Loops allow you to execute a block of code multiple times, which is useful for iterating over collections of data or performing repetitive tasks. In Python, there are two main types of loops: `for` loops and `while` loops.\n", "\n", "`while` loops repeatedly execute a block of code as long as a specified condition is true. For example" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.023474Z", "iopub.status.busy": "2026-01-19T18:20:22.023308Z", "iopub.status.idle": "2026-01-19T18:20:22.026506Z", "shell.execute_reply": "2026-01-19T18:20:22.026117Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Count is 0\n", "Count is 1\n", "Count is 2\n", "Count is 3\n", "Count is 4\n", "Final count is 5\n" ] } ], "source": [ "count = 0\n", "while count < 5:\n", " print(\"Count is\", count)\n", " count += 1 # Increment count by 1\n", "\n", "print(\"Final count is\", count)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this example, the loop will continue to run as long as `count` is less than `5`. Inside the loop, we print the current value of `count` and then increment it by `1`. Once `count` reaches `5`, the condition becomes false, and the loop exits. Note that `count += 1` is a shorthand for `count = count + 1`.\n", "\n", "`for` loops are used to iterate over a sequence (like a list, tuple, or string) or other iterable objects. We will see examples of such objects in the section on data structures. For the moment, let's look at a simple example of a `for` loop that iterates over a list of numbers" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.028640Z", "iopub.status.busy": "2026-01-19T18:20:22.028444Z", "iopub.status.idle": "2026-01-19T18:20:22.031278Z", "shell.execute_reply": "2026-01-19T18:20:22.030905Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number is 1\n", "Number is 2\n", "Number is 3\n", "Number is 4\n", "Number is 5\n" ] } ], "source": [ "numbers = [1, 2, 3, 4, 5]\n", "for num in numbers:\n", " print(\"Number is\", num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or alternatively, we can use the `range()` function to generate a sequence of numbers to iterate over" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.034304Z", "iopub.status.busy": "2026-01-19T18:20:22.033933Z", "iopub.status.idle": "2026-01-19T18:20:22.037468Z", "shell.execute_reply": "2026-01-19T18:20:22.036890Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i is: 0\n", "i is: 1\n", "i is: 2\n", "i is: 3\n", "i is: 4\n" ] } ], "source": [ "for i in range(5): # Generates numbers from 0 to 4\n", " print(\"i is:\", i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the function `range` also to get a sequence of number to loop over. It follows the syntax `range(start, stop, step)`\n", "\n", "- **Start**\n", " - Where the sequence starts: it includes the start value (first number will always be `start`)\n", " - Optional \n", " - Defaults to 0 (unless otherwise specified)\n", "- **Stop**:\n", " - Where the sequence ends: it does not include the stop value (last number will always be `stop`-`step`)\n", " - Required field\n", "- **Step**: \n", " - Step size of the sequence, i.e., how much we increase the value at each iteration: `start + step`, `start + 2*step`, `start + 3*step`, ...\n", " - Optional\n", " - Defaults to 1 (unless otherwise specified)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.039768Z", "iopub.status.busy": "2026-01-19T18:20:22.039551Z", "iopub.status.idle": "2026-01-19T18:20:22.042624Z", "shell.execute_reply": "2026-01-19T18:20:22.042151Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i is 2\n", "i is 4\n", "i is 6\n", "i is 8\n" ] } ], "source": [ "for i in range(2, 10, 2): # Generates even numbers from 2 to 8\n", " print(\"i is\", i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But as mentioned before, `for` loops can iterate over any iterable object, not just sequences of numbers. For example, we can iterate over the characters in a string" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.044906Z", "iopub.status.busy": "2026-01-19T18:20:22.044710Z", "iopub.status.idle": "2026-01-19T18:20:22.047619Z", "shell.execute_reply": "2026-01-19T18:20:22.047075Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C\n", "e\n", "m\n", "f\n", "i\n" ] } ], "source": [ "for letter in \"Cemfi\":\n", " print(letter)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or over a list of strings" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.050714Z", "iopub.status.busy": "2026-01-19T18:20:22.050429Z", "iopub.status.idle": "2026-01-19T18:20:22.054029Z", "shell.execute_reply": "2026-01-19T18:20:22.053648Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Winter is coming\n", "Winter is coming\n", "Winter is coming\n", "Winter is coming\n", "Winter is coming\n", "Get ready to enjoy the summer break, it's June!\n", "July is perfect to find reasons to escape from Madrid\n", "August is perfect to find reasons to escape from Madrid\n", "Winter is coming\n", "Winter is coming\n", "Winter is coming\n", "Winter is coming\n" ] } ], "source": [ "months_of_year = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]\n", "\n", "# Loop through the months and add some summer vibes\n", "for month in months_of_year:\n", " if month == \"June\":\n", " print(f\"Get ready to enjoy the summer break, it's {month}!\")\n", " elif month == \"July\" or month ==\"August\":\n", " print(f\"{month} is perfect to find reasons to escape from Madrid\") \n", " else:\n", " print(f\"Winter is coming\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Where we combined loops with conditional statements to print different messages based on the current month.\n", "\n", "Note that you can use the `break` statement to exit a loop prematurely when a certain condition is met, and the `continue` statement to skip the current iteration and move to the next one. " ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.056341Z", "iopub.status.busy": "2026-01-19T18:20:22.056157Z", "iopub.status.idle": "2026-01-19T18:20:22.058778Z", "shell.execute_reply": "2026-01-19T18:20:22.058401Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i is 0\n", "i is 1\n", "i is 2\n", "i is 3\n", "i is 4\n" ] } ], "source": [ "for i in range(10):\n", " if i == 5:\n", " break # Exit the loop when i is 5\n", " print(\"i is\", i)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.060560Z", "iopub.status.busy": "2026-01-19T18:20:22.060389Z", "iopub.status.idle": "2026-01-19T18:20:22.063205Z", "shell.execute_reply": "2026-01-19T18:20:22.062846Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i is 1\n", "i is 3\n", "i is 5\n", "i is 7\n", "i is 9\n" ] } ], "source": [ "for i in range(10):\n", " if i % 2 == 0:\n", " continue # Skip even numbers\n", " print(\"i is\", i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also create nested loops, where one loop is placed inside another loop. This is useful for iterating over multi-dimensional data structures or performing more complex tasks." ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.065033Z", "iopub.status.busy": "2026-01-19T18:20:22.064859Z", "iopub.status.idle": "2026-01-19T18:20:22.067660Z", "shell.execute_reply": "2026-01-19T18:20:22.067224Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i: 0, j: 0\n", "i: 0, j: 1\n", "i: 1, j: 0\n", "i: 1, j: 1\n", "i: 2, j: 0\n", "i: 2, j: 1\n" ] } ], "source": [ "for i in range(3):\n", " for j in range(2):\n", " print(f\"i: {i}, j: {j}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`enumerate()` is a built-in function that adds a counter to an iterable and returns it as an enumerate object. This is particularly useful when you need both the index and the value of items in a loop. " ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "execution": { "iopub.execute_input": "2026-01-19T18:20:22.069747Z", "iopub.status.busy": "2026-01-19T18:20:22.069570Z", "iopub.status.idle": "2026-01-19T18:20:22.072429Z", "shell.execute_reply": "2026-01-19T18:20:22.072018Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index: 0, Fruit: apple\n", "Index: 1, Fruit: banana\n", "Index: 2, Fruit: cherry\n" ] } ], "source": [ "fruits = [\"apple\", \"banana\", \"cherry\"]\n", "for index, fruit in enumerate(fruits):\n", " print(f\"Index: {index}, Fruit: {fruit}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercises\n", "\n", "Now that we have covered the basics of Python programming, it's time to practice what we've learned. Here are some exercises to help you reinforce your understanding of variables, data types, functions, conditionals, and loops.\n", "\n", "1. Create two variables, `a` and `b`, and assign them the values `10` and `20`, respectively. Write a function that takes these two variables as input and returns their product and their difference.\n", "2. Write a function called `is_even` that takes a number as input and returns `True` if the number is even and `False` otherwise. Try calling the function with different numbers to test it.\n", "3. Write a loop that computes the result of the sum $\\sum_{i=1}^{10} i^2$ and prints the result.\n", "4. Write a loop to compute the product of all odd numbers between `1` and `20`. Print the final result. *Hint:* You could reuse the `is_even` function you defined earlier.\n", "5. Compute the sum of all numbers between `1` and `1000` that are divisible by `3` or `5`. Print the final result." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3", "path": "/usr/local/share/jupyter/kernels/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.13.5" } }, "nbformat": 4, "nbformat_minor": 4 }