{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Course 2.1: lists and for loops\n", "=============================\n", "We first review quickly some of the material we introduced in the first worksheet:\n", " - basic Python objects: booleans (`bool`), integers (`int`), floating point (`float`) and string (`str`)\n", " - binary operations `+`, `*`, `-`, `/`, `//`, `%` and comparisons `==`, `!=`, `<`, `<=`, `>`, `>=`\n", " - tab-completion and documentation\n", " - using modules\n", " \n", "Next, we will learn:\n", " - how to manipulate objects of type `list` (creation, removing/adding elements, copy)\n", " - how to go through the element of an iterable using `for` loops" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# floating point numbers (type 'float') have limited precision\n", "print(1e308)\n", "print(1e309)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# as a consequence some operations involving floats overflow\n", "print(7.13 ** 154.37)\n", "print(421.23 ** 125.2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# as another consequence addition is not commutative\n", "1e100 + 1 - 1e100 == 1e100 - 1e100 + 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# integer (type 'int') have unlimited precision\n", "103 ** 2543" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# operations on them are exact\n", "10**100 + 1 - 10**100 == 10**100 - 10**100 + 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# when you have a Python object you can:\n", "# - use tab-completion to get its list of methods\n", "# - execute the cell with a '?' at the end to get the help" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = \"I am a string\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# press Tab\n", "s." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# press Shift-Enter\n", "s.upper?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# there are many features that are inside modules\n", "# you need to use import to be able to use them" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import math\n", "print(math.cos(math.pi / 4))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# arange from numpy\n", "# the syntax is arange(start, stop, step)\n", "from numpy import arange\n", "arange(0, 5, 1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "arange(0, 5, 2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# plotting\n", "import matplotlib.pyplot as plt\n", "plt.plot([0,1,2], [2,0,2])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists\n", "------\n", "\n", "A list is an object is an ordered list of other objects. It is constructed with square brackets \"`[`\" and \"`]`\". We also access its elements using them." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l = [1, 34, 18] # a list of 3 elements\n", "print(l)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l[0] # access element at position 0 (= first)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l[2] # access element at position 2 (= third)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l[-1] # access element at last position" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l[5] # the element at 6-th position (?!)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(l) # get the length of the list" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above comands also works for strings (and other \"list like\" Python objects):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s = \"AIMS Rwanda\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s[-4]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`str` and `list` are also similar with respect to addition and multiplication:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"Rwa\" + \"nda\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "[1, 4] + [5, -4, 1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"abc\" * 7" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "[1, 2, 3] * 7" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** In this exercise we will see the similarities and differences between `numpy` arrays and lists.\n", "- Construct a numpy array that contains the integers from 2 to 137 included (*hint: you need to use an `import` statement and use `arange`*)\n", "- Access the element at position 57 (ie the 58th element of the list) using the square brackets `[` and `]`\n", "- Compute its length using `len`\n", "- Assuming that you already imported `numpy` what is the result of\n", "```python\n", "a = numpy.arange(0, 5)\n", "b = numpy.arange(2, 7)\n", "a + b\n", "```\n", "- what about\n", "```python\n", "3 * a\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists can contain lists" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l = [[1, 2], [[1, 3], [1, 5, 2]]]\n", "print(l[1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For loop\n", "--------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`for` loop are used to run through the elements of a list one after the other. There are two different usage\n", "- to perform an operation with each element\n", "```python\n", "l = [1, 'haha', 18.3]\n", "for x in l:\n", " print(x)\n", "```\n", "- to build another list from the previous one (this is called \"list comprehension\")\n", "```python\n", "l = [1, 2, 3]\n", "l2 = [x**2 for x in l]\n", "print(l2)\n", "```\n", "\n", "**Exercise:**\n", "- Copy paste the two examples above. Do you understand what is happening?\n", "- Create a string `s` containing `\"AIMS\"`.\n", "- Write a for loop to print each character of `s`.\n", "- Use a list comprehension to build the list `['AA', 'II', 'MM', 'SS']`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:**\n", "- Let `l0` be the following list\n", "```python\n", "l0 = [4, 1, 7, -3, 2, 2, 5, 8, 17, 13, 2, 5, 3, 9]\n", "```\n", "- What is the result of `l0[1]`?\n", "- Using a `for` loop of the first type, print the squares of the integers from 1 to 30.\n", "- Using a list comprehension make a list that contains the squares of the elements of `l0`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** We are using the list `l0` from the previous exercise.\n", "- What is the following loop doing\n", "```python\n", "s = 0\n", "for i in l0:\n", " s = s + i\n", "```\n", " Run this code and check your answer.\n", "- Can you modify this loop in order that it computes the sum of the cubes of elements of `l0`?\n", "- Can you modify this loop in order that it computes the product?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to use more than one instruction inside a for loop.\n", "```python\n", "for x in l:\n", " instruction1\n", " instruction2\n", " instruction3\n", " etc\n", "```\n", "\n", "**Exercise:** We are still using the list `l0` from the previous exercises\n", "- What is doing the following loop\n", "```python\n", "s = 0\n", "for a in l0:\n", " print(s)\n", " s = s + a\n", "```\n", "Run the code and check your answer.\n", "- Make one loop that computes the sum and the product of elements of `l0` (you need to do only one loop to compute the two quantities)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Modifying lists\n", "---------------\n", "Lists can be modified using the following syntax\n", "```python\n", "l = [0,1,2] # creating a list\n", "l[0] = 25 # modifying element at position 0\n", "```\n", "**Exercise:** Copy paste this code and check that it works as expected." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since lists can be modified it is sometimes useful to make copies. This is achieved with the following code\n", "```python\n", "l = [3, 2, 1]\n", "t = l[:] # makes a copy\n", "l[0] = -1 # modifies l\n", "t[1] = 3 # modifies its copy t\n", "```\n", "**Exercise:**\n", "- Copy paste the code above\n", "- What are the values of `l` and `t` at the end?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "**Exercise:** \n", "- What happens when you try to modify a string?\n", "- What happens when you try to modify a numpy array?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:**\n", "- Make a copy of the list `l0` that was used in the previous exercises.\n", "- Using a for loop modifies this copy so that the entry `i`-th entry becomes the square of what it was" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Lists can also be modified through methods\n", "\n", "- adding terms with `append`, `extend` and `insert`\n", "- removing terms with `clear` and `pop`\n", "\n", "**Exercise:**\n", "- Look at the documentation of these 5 methods (*hint: you need to use the question mark `?`*)\n", "- What is the value of the list `l` after the evaluation of these lines\n", "```python\n", "l = [0] * 3 + [1, 2] * 2\n", "l.append(5)\n", "l.append(2)\n", "l.pop(2)\n", "```\n", "Check your answer by copying, pasting and executing the above code." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`range`\n", "-------\n", "If you want to iterate over integers there is a useful function called `range` (that has similarities with `numpy.arange`). It is a function that can be called with either one, two or three arguments:\n", "\n", " - `range(stop)`: all integers from `0` to `stop-1` included\n", " - `range(start, stop)`: all integers from `start` to `stop-1`\n", " - `range(start, stop, step)`: all integers from `start` to `stop` and with a difference of `step` between each consecutive terms\n", "\n", "**Exercise:**\n", "Copy/paste the codes below in 3 code cells and before executing it try to guess what will be the output\n", "\n", "1 -\n", "```python\n", "for x in range(5):\n", " print(x)\n", "```\n", "\n", "2 - \n", "```python\n", "for x in range(12, 20, 3):\n", " print(x)\n", "```\n", "\n", "3 - \n", "```python\n", "for x in range(30, -1, -10):\n", " print(x)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** What is the value of $$\\sum_{k = 1}^{20} k^k$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:**\n", "- Compute $$(1) \\cdot (1 + 2) \\cdot (1 + 2 + 3) \\cdot (1 + 2 + 3 + 4) \\cdot \\ldots (1 + 2 + \\ldots + 30)$$\n", "- Compute $$1 + (1 \\cdot 2) + (1 \\cdot 2 \\cdot 3) + \\ldots + (1 + 2 + \\ldots + 30)$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Construct a list which contains once the number 1, twice the number 2, 3 times the number 3, up to 50 times the number 50. That is to say\n", "```python\n", "[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, etc]\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** This exercise must be done **without using a list**. Recall that the Fibonacci sequence is defined by $F_0 = F_1 = 1$ and $F_{n+1} = F_n + F_{n-1}$. What is the 100-th Fibonacci number? " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Could you make a list containing the odd integers from 1 to 201 included? (*hint: have a look at the different possible ways to use `range`*)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:**\n", "- make the list of the first $50$ Fibonacci numbers $F_n$ (i.e. $n$ goes from $0$ to $49$)\n", "- make the list of the quantity $F_n^2 - F_{n-1} F_{n+1}$ for $n=1,2,...,48$ and print it.\n", "- What do you see? Could you prove it?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** In this exercise we will do some graphics. As in the first worksheet you should use `plot` from `matplotlib.pyplot`. If you do not remember how it works, have a look to this first worksheet.\n", "\n", "Let $S_0$ be the standard unit square with vertices $(0,0)$, $(1,0)$, $(1,1)$ and $(0,1)$. We define the square $S_n$ obtained as joining the middle of each side of $S_{n-1}$.\n", "- Draw on the same pictures $S_0$, $S_1$, $S_2$, ... up to $S_{10}$.\n", "- Do the same starting from another quadrilateral which is not regular\n", "- Do the same starting from a pentagon (five vertices)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** what does the following code?\n", "```python\n", "x = 1.0\n", "for i in range(10):\n", " x = (x + 2.0 / x) / 2.0\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the following two exercises, you will need to use nested loops. That is construction of the form\n", "```python\n", "for x in l1:\n", " for y in l2:\n", " do something\n", "```\n", "**Exercise:** Compute the value of $$\\sum_{x = 1}^{10} \\sum_{n = 0}^5 x^n$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:** Compute the value of $$\\sum_{x=1}^{10} \\sum_{n=x}^{10} x^n$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise:**\n", "- Using the recurrence relation satisfied by the binomial numbers $\\binom{n+1}{k+1} = \\binom{n}{k} + \\binom{n}{k+1}$ compute the list $\\binom{20}{0}, \\binom{20}{1}, \\ldots, \\binom{20}{20}$. In order to do that you need to start from the list `[1]` and design a loop that constructs successively `[1, 1]`, then `[1, 2, 1]`, then `[1, 3, 3, 1]`, etc.\n", "- What is the sum of these 21 binomial numbers?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note:** `range` constructs an object of a strange nature. Do you remember what does the following code (from worksheet 1)\n", "```python\n", "r = range(30)\n", "print(r)\n", "print(type(r))\n", "```\n", "Abstractly a `range` looks like a list: you can access elements with square brackets and compute the length\n", "```python\n", "r = range(0, 1523, 2)\n", "print(r[10])\n", "print(r[-5])\n", "print(len(r))\n", "```\n", "And as we have seen you can run a for loop on it (we say that it is *iterable*). However, the `range` object is not expanded in memory! As a consequence, the list of commands below is fine (but will run forever)\n", "```python\n", "j = 0\n", "for i in range(2**64):\n", " j = j + i\n", "```\n", "Note however that the list of integers from $0$ to $2^{64}$ is much bigger than the RAM available in your computer. This second example will freeze your computer (eating all the memory)\n", "```python\n", "l = list(range(2**64))\n", "```\n", "Execute the first of the two above list of commands. You can check that the code continue executing (look at the star that appears in the blue box on the left). To interrupt the execution you can use the menu on the top of the page: \"Kernel -> Interrupt\". Better to not execute the second example!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Copyright (C) 2016 Vincent Delecroix <vincent.delecroix@u-bordeaux.fr>\n", "\n", "This work is licensed under a Creative Commons Attribution-NonCommercial 4.0\n", "International License (CC BY-NC-SA 4.0). You can either read the\n", "[Creative Commons Deed](https://creativecommons.org/licenses/by-nc-sa/4.0/)\n", "(Summary) or the [Legal Code](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode)\n", "(Full licence)." ] } ], "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": 1 }