{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "96402b05",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "# A.2 Loops and if statements"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f91431e",
   "metadata": {},
   "source": [
    "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In Python, a `for` loop is a set of programming commands that is executed several times. A `for` loop is explained here by looping over all the items in a list. There are two syntax rules for defining a `for` loop. First, a colon (`:`) must always terminate the line that starts with `for`, and second, the lines of code that must be executed during each step of the loop must all be indented. This is illustrated in the following example, in which the variable `item` takes on the value of each element in the list `alist` during the `for` loop. The first line after the `for` statement is indented, which means that this line is executed every time Python loops through the list. In this example, Python prints the value as well as the variable type of `item` for pass through the loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "558fcd2c",
   "metadata": {
    "tags": [
     "remove-input"
    ]
   },
   "outputs": [],
   "source": [
    "alist = ['Dupuit', 0, 2.3, 12]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0f39bc6e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dupuit has type <class 'str'>\n",
      "0 has type <class 'int'>\n",
      "2.3 has type <class 'float'>\n",
      "12 has type <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "for item in alist:\n",
    "    print(item, 'has type', type(item))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c01ec1eb",
   "metadata": {},
   "source": [
    "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; There is no explicit command that marks the end of the code that must be executed during a loop. Instead, Python’s interpreter infers this based on the indentation. Proper indentation is thus essential as it controls the way the code behaves. This helps tremendously in creating neat, readable scripts. The length of the indentation is arbitrary, as long as it remains the same; the default is four spaces, so use that.\n",
    "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Looping over the elements of a list is a very pythonic way of doing things. Programmers using other languages may be used to loops that get executed a certain number of times. This is possible too and is typically done using the `range` command. In the following example, `range(4)` creates 4 numbers, from 0 up to (but not including) 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e33671f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Step 0\n",
      "Step 1\n",
      "Step 2\n",
      "Step 3\n"
     ]
    }
   ],
   "source": [
    "for i in range(4):\n",
    "    print(f'Step {i}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5abf153",
   "metadata": {},
   "source": [
    "The `range(n)` command creates a sequence with `n` numbers to iterate over, starting at 0. `range` can optionally be defined by specifying a starting value (the default is zero) and a step (the default step is 1). So a `range` starting at `-3` and stopping before the counter reaches `+3` with steps of `2` is defined as"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3cdda944",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-3\n",
      "-1\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "for k in range(-3, 3, 2):\n",
    "    print(k)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d93f926f",
   "metadata": {},
   "source": [
    "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Python also provides the `enumerate` function, which generates an index counter as it loops through a list. This can be useful for example when the corresponding items in another list have to be modified during the loop. In the following example, the strings in the list `names` are combined to full names using the strings in the list `last_names`. By including `enumerate()` in the line that starts the `for` loop, a counter `i` is created so that each time the `for` loop steps to the next element in the list `last_names`, `i` is incremented by 1. Notice the syntax: The counter `i` is a user-defined variable name that precedes the name that is used within the `for` loop for the active element in the `list` (`last_name` in this case)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e14eeebe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "First names ['Henry', 'Willem', 'Alexander']\n",
      "Full names ['Henry Darcy', 'Willem Badon Ghyben', 'Alexander Herzberg']\n"
     ]
    }
   ],
   "source": [
    "names = [\"Henry\", \"Willem\", \"Alexander\"]\n",
    "last_names = [\"Darcy\", \"Badon Ghyben\", \"Herzberg\"]\n",
    "print(\"First names\", names)\n",
    "for i, last_name in enumerate(last_names):\n",
    "    names[i] = names[i] + \" \" + last_name\n",
    "print(\"Full names\", names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41f09654",
   "metadata": {},
   "source": [
    "## Conditional statements\n",
    "\n",
    "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Conditional statements (also called `if` statements) can be used to control the flow of a program depending on whether or not certain conditions are met. Just like with the `for` loop, a colon must be typed at the end of the line starting with `if`, and the lines that must be executed if the evaluated condition is true must be indented. There is no specific command to end the `if` statement: As with `for` loops it is inferred from the indentation.\n",
    "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; In the next code cell, it is checked if the list `alist` actually contains elements by calling the `len` function, which returns the number of items (zero for an empty list)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "93a177c8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "alist contains no elements\n"
     ]
    }
   ],
   "source": [
    "alist = [] # Defines an empty list\n",
    "if (len(alist) == 0):\n",
    "    print (\"alist contains no elements\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3bddffe",
   "metadata": {},
   "source": [
    "Note that a double equal sign is used for the comparison (since a single equal sign is reserved for value assignment). Other comparison operators in Python include the following (note that the comparisons return a Boolean variable type, which can be printed to the screen)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c310722e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "a = 4\n",
    "print(a <= 4) # a is smaller than or equal to 4\n",
    "print(a == 4) # a is equal to 4.\n",
    "print(a >= 4) # a is larger than or equal to 4\n",
    "print(a != 4) # a is not equal to 4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf64fe11",
   "metadata": {},
   "source": [
    "Conditions can be compounded with the and or or statements, with parentheses for readability"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3a64c465",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The value of a is 7\n"
     ]
    }
   ],
   "source": [
    "a = 7\n",
    "if (a > 3) and (a < 8):\n",
    "    print('The value of a is', a)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccfa9329",
   "metadata": {},
   "source": [
    "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; In the following code example, the `if` statement is placed inside a `for` loop to determine what message is printed to the screen. The message varies according to the value of the loop variable `i`. The `if` statement now also includes the `elif` and `else` commands (note how the indentation works)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "de638c5e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-1 is negative\n",
      "0 is zero\n",
      "1 is positive\n",
      "2 is positive\n"
     ]
    }
   ],
   "source": [
    "for i in range(-1, 3):\n",
    "    if i < 0:\n",
    "        print(i, 'is negative')\n",
    "    elif i == 0:\n",
    "        print(i, 'is zero')\n",
    "    else:\n",
    "        print(i, 'is positive')"
   ]
  }
 ],
 "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.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
