{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Python training UGA 2017\n", "\n", "**A training to acquire strong basis in Python to use it efficiently**\n", "\n", "Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)\n", "\n", "# Standard types and basic statements" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Function calls\n", "\n", "There are [built-in functions](https://docs.python.org/3/library/functions.html) and the developers can of course define other functions. To call a function:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "print(\"hello\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some functions return a result." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "round(1.2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's common to store the result in a variable:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "my_var = round(1.2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "which can then be used:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "print(my_var)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Few standard types\n", "\n", "- Simple types (`int`, `float`, `bool`, `complex`)\n", "- Standard type `str`\n", "- Standard type `list`\n", "- Standard type `tuple`" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### `int` (integers)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "a = 4\n", "c = -10\n", "\n", "# binary notation (base 2)\n", "b = 0b010\n", "\n", "# octal notation (base 8)\n", "o = 0o011\n", "\n", "# hexadecimal (base 16)\n", "h = 0x1cf0\n", "\n", "a = int('1') # base 10\n", "a = int('111', 2) # base 2\n", "a = int('70', 8) # base 8\n", "a = int('16', 16) # base 16" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remark: `int` in Python 3 are impressive! No limit! See https://docs.python.org/3.1/whatsnew/3.0.html#integers" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Arithmetic operations" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "13\n", "7\n", "30\n", "3.3333333333333335\n", "3\n", "1\n" ] } ], "source": [ "print(10 + 3)\n", "print(10 - 3)\n", "print(10 * 3)\n", "print(10 / 3) # float division\n", "print(10 // 3) # integer division\n", "print(10 % 3)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### `bool` (booleans)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = bool('1')\n", "b = False\n", "b = True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Comparison operations (bool)\n", "\n", "- `==` equal\n", "- `!=` différent\n", "- `<` inferior\n", "- `<=` inferior or equal\n", "- `>` superior\n", "- `>=` superior or equal" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "##### Keyword `is`: check identity" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "False\n" ] } ], "source": [ "a = None\n", "print(a is None)\n", "print(a is not None)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "##### Keywords `and` and `or`" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True and True" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True and False" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "False and False" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True or True" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True or False" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "False or False" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### `float` (real, double precision) and `complex`" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# float\n", "a = float('1')\n", "a = 1.234\n", "a = 1e2\n", "a = -1e-2\n", "a = .2" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1+2j) 1.0 2.0\n" ] } ], "source": [ "# complex (2 floats)\n", "c = complex('1')\n", "c = 1 + 2j\n", "print(c, c.real, c.imag)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remark: notation `var_name.attr_name` to access to an attribute of an object." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Warning about floating-point arithmetic and numerical errors!" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.0\n" ] } ], "source": [ "b = 1e16\n", "c = 1.2 + b\n", "d = c - b\n", "print(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Very general issue (not Python): \n", "\n", "See https://en.wikipedia.org/wiki/Floating-point_arithmetic and https://docs.python.org/3/tutorial/floatingpoint.html" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Standard type `str`" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Strings on \n", "more thand \n", "one line.\n", "\n" ] } ], "source": [ "s = 'hello'\n", "s = \"hello\"\n", "\n", "s = ('How is it possible to write a very very '\n", " 'very long string with lines limited to 79 characters?')\n", "\n", "s = \"\"\"Strings on \n", "more thand \n", "one line.\n", "\"\"\"\n", "print(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Warning: big difference between Python 2 and Python 3. In Python 3, `str` are unicode and there is another type `bytes`." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Methods of the type `str`\n", "\n", "Objects of built-in types have methods associated with their type (object oriented programming). The built-in function `dir` returns a list of name of the attributes. For a string, these attributes are python system attributes (with double-underscores) and several public methods:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']\n" ] } ], "source": [ "s = 'abcdef'\n", "print(dir(s))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To access an attribute of an object (here, the method `str.startswith`), we use the dot:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.startswith('a')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### standard type `str`\n", "\n", "#### function `str.format`\n", "\n", "```text\n", "Docstring:\n", "S.format(*args, **kwargs) -> str\n", "\n", "Return a formatted version of S, using substitutions from args and kwargs.\n", "The substitutions are identified by braces ('{' and '}').\n", "```" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.23456789'" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1.23456789\n", "'a = {}'.format(a)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.2346'" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'a = {:.4f}'.format(a)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.2346'" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'a = {:8.4f}'.format(a)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.2346e+00 (scientific notation)'" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'a = {:.4e} (scientific notation)'.format(a)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\t2\t3\n" ] } ], "source": [ "print('{}\\t{}\\t{}'.format(1, 2, 3))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### standard type `str`\n", "\n", "#### New in Python 3.6: format strings" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.23456789'" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1.23456789\n", "f'a = {a}'" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.2346'" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f'a = {a:.4f}'" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.2346'" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f'a = {a:8.4f}'" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a = 1.2346e+00 (scientific notation)'" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f'a = {a:.4e} (scientific notation)'" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\t2\t3\n" ] } ], "source": [ "print(f'{1}\\t{1+1}\\t{2+1}')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### standard type `str`\n", "\n", "Strings are immutable **[\"sequences\"](https://docs.python.org/3/library/stdtypes.html)**.\n", "\n", "- lookup" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n" ] } ], "source": [ "s = 'abcdef'\n", "print('a' in s)\n", "print('hello' not in s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- We can get an element of a string (**index starts from 0**):" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n" ] } ], "source": [ "print(s[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- since strings are immutable, they can not be modified inplace. If we try, we get an error:\n", "\n", "```python\n", "s[0] = 'b'\n", "```\n", "```text\n", "---------------------------------------------------------------------------\n", "TypeError Traceback (most recent call last)\n", " in ()\n", "----> 1 s[0] = 'b'\n", "\n", "TypeError: 'str' object does not support item assignment\n", "```\n", "\n", "- since strings are sequences, they can be \"sliced\" (we will soon study in details this powerful notation):" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'bc'" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s[1:3]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- it is very simple to manipulate strings in many ways:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Abcdef ABCDEF\n", "Abcdef ABCDEF\n", "Abcdef ABCDEF\n", "Abcdef ABCDEF\n", "\n" ] } ], "source": [ "print((s.capitalize() + ' ' + s.upper() + '\\n') * 4 ) " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Slicing \n", "\n", "Very general, can be used on all sequences as `str`, `list`, etc... Not simple for beginners but very powerfull (see [here](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) and [here](http://avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html)).\n", "\n", "Python indexes and slices for a six-element str. Indexes enumerate the elements, slices enumerate the spaces between the elements.\n", "\n", "```text\n", "Index from rear: -6 -5 -4 -3 -2 -1\n", "Index from front: 0 1 2 3 4 5 \n", " +---+---+---+---+---+---+\n", " | a | b | c | d | e | f | \n", " +---+---+---+---+---+---+ \n", "Slice from front: 0 1 2 3 4 5 6 \n", "Slice from rear: -6 -5 -4 -3 -2 -1 None\n", "```" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ce'" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = 'abcdef'\n", "# s[start:stop:step]\n", "s[2:6:2]" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'cdef'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# s[start:stop]\n", "s[2:6]" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'bcdef'" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# s[start:]\n", "s[1:]" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ab'" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# s[:stop]\n", "s[:2]" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'fedcba'" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# step = -1: goes through the string in reverse order\n", "s[::-1]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Do it yourself\n", "\n", "Suppose we have a string representing a header line of the form:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "s = ' wind;temperature;;pressure '" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "- Remove leading and ending blanks (see `str.replace` and `str.strip`)\n", "- Extract the first field (e.g. using `find` method and slicing)\n", "- Extract the last field (e.g. using `rfind` method and slicing)\n", "- Check for empty field (e.g. `find` \";;\" pattern)\n", "- Remove empty field (e.g. using replace method)\n", "- BONUS : Extract the second field (tip :`find` can take an argument that tells where to start the search)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### A possible solution:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--wind;temperature;;pressure--\n", "wind\n", "temperature\n", "pressure\n", "16\n", "wind;temperature;pressure\n" ] } ], "source": [ "s = ' wind;temperature;;pressure '\n", "# remove leading blanks\n", "s = s.strip()\n", "print(\"--{}--\".format(s))\n", "# extract the first field\n", "idx = s.find(\";\")\n", "s0 = s[0:idx]\n", "print(s0)\n", "# extract the second field\n", "idx1 = s.find(\";\", idx+1) # start the search after the first \";\"\n", "s1 = s[idx+1:idx1]\n", "print(s1)\n", "# extract the last field\n", "idx2 = s.rfind(\";\")\n", "s2 = s[idx2+1:]\n", "print(s2)\n", "idx_first_empty_field = s.find(\";;\")\n", "print(idx_first_empty_field)\n", "# remove empty field\n", "s_no_empty = s.replace(\";;\", \";\")\n", "print(s_no_empty)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### standard type `list`\n", "\n", "A list is a **mutable sequence of (possibly inhomogeneous) elements**." ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "list" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type([0, 'a'])" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['2', 6, 3.0]\n" ] } ], "source": [ "# create an empty list\n", "l = []\n", "# fill the list (with the function append)\n", "l.append('2')\n", "# fill the list (with the function extend)\n", "l.extend([6, 3.])\n", "print(l)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['2', 6, 3.0, 'hello', 3]\n" ] } ], "source": [ "# concatenate lists with the operator +\n", "print(l + ['hello', 3])" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 3.0 6\n", "['2', 6]\n" ] } ], "source": [ "# get values\n", "print(l[0], l[2], l[-2])\n", "# slicing\n", "print(l[0:2])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### standard type `tuple`\n", "\n", "A tuple is a **immutable sequence of (possibly inhomogeneous) elements**.\n", "\n", "Remark: when you need a sequence that won't be modified, tuple is usually more efficient than list." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tuple" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = 0, 'a', 1.2\n", "t1 = (5, 'hello')\n", "t2 = tuple([1.1, 2])\n", "type(t)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'a'" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t[1] # indexing" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 1.2)" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t[1:] # slicing" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello\n" ] } ], "source": [ "a, b = t1 # tuple assigment\n", "print(b)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Mutable and immutable objects\n", "\n", "The objects of type `str`, `int`, `float`, `bool` are immutable. They can not be modified. Of course, a name that points towards an integer can point towards a different integer." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "10\n" ] } ], "source": [ "i = 1\n", "i = i + 2 # (or i += 2)\n", "print(i)\n", "i = 10\n", "print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, the objects `1` and `3` have not been modified.\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Mutable and immutable objects\n", "\n", "An object of type `list` is mutable:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 5]\n", "[0, 5, 'hello']\n" ] } ], "source": [ "l = [0, 5]\n", "print(l)\n", "l.append('hello')\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Here, the object list tagged by the name `l` has been modified inplace." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## References and `del` keyword\n", "\n", "`del` removes a reference. If an object in not binded to any names, Python can delete it from its internal memory." ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['a']\n" ] } ], "source": [ "l = ['a', 'b']\n", "del l[1]\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### More on slicing \n", "\n", "Very general, can be used on all sequences as `str`, `list`, etc... Not simple for beginners but very powerfull (see [here](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) and [here](http://avilpage.com/2015/03/a-slice-of-python-intelligence-behind.html)).\n", "\n", "Python indexes and slices for a six-element str. Indexes enumerate the elements, slices enumerate the spaces between the elements.\n", "\n", "```text\n", "Index from rear: -6 -5 -4 -3 -2 -1\n", "Index from front: 0 1 2 3 4 5 \n", " +---+---+---+---+---+---+\n", " | a | b | c | d | e | f | \n", " +---+---+---+---+---+---+ \n", "Slice from front: 0 1 2 3 4 5 6 \n", "Slice from rear: -6 -5 -4 -3 -2 -1 0\n", "```" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ce'" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = 'abcdef'\n", "# s[start:stop:step]\n", "s[2:6:2]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### More on slicing \n", "\n", "#### Assigment to mutable object" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 2, 3, 4, 5, 'a']\n", "[0, 1, 2, 3, 4, 5, 'a']\n" ] } ], "source": [ "l = [0, 1, 2, 3, 4, 5]\n", "l1 = l # assigment to a new name l1 (no copy of the object).\n", "# the names l and l1 points towards the same object.\n", "l1.append('a')\n", "print(l1)\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "#### Shallow copy" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0, 1, 2, 3, 4, 5, 'a']\n", "[0, 1, 2, 3, 4, 5]\n" ] } ], "source": [ "l = [0, 1, 2, 3, 4, 5]\n", "l1 = l[:] # shallow copy of l\n", "l1.append('a')\n", "print(l1)\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### More on slicing\n", "\n", "Other examples of slices for a six-element list. Indexes enumerate the elements, slices enumerate the spaces between the elements." ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = [0, 1, 2, 3, 4, 5] \n", "all([\n", " len(a) == 6,\n", " a[1:] == [1, 2, 3, 4, 5],\n", " a[:5] == [0, 1, 2, 3, 4],\n", " a[0] == 0,\n", " a[:-2] == [0, 1, 2, 3],\n", " a[5] == 5,\n", " a[1:2] == [1],\n", " a[-1] == 5,\n", " a[1:-1] == [1, 2, 3, 4],\n", " a[-2] == 4,\n", "])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Do it yourself\n", "\n", "Suppose we have the string containing header line." ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s = 'wind;temperature;pressure'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Extract the list of items (i.e. \"wind\", \"temperature\", \"pressure\"; see `str.split`).\n", "- Add \"Snow level\" to the list of items (e.g. using append)\n", "- Build a new header such that items are capitalized (e.g. using the methods `str.join` and `str.capitalize` and iterating on the list)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### A possible solution:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['wind', 'temperature', 'pressure']\n", "['Wind', 'Temperature', 'Pressure', 'Snow level']\n" ] }, { "data": { "text/plain": [ "'Wind;Temperature;Pressure;Snow level'" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = 'wind;temperature;pressure'\n", "list_items = s.split(\";\")\n", "print(list_items)\n", "list_items.append(\"snow level\".capitalize())\n", "list_items[0] = list_items[0].capitalize()\n", "list_items[1] = list_items[1].capitalize()\n", "list_items[2] = list_items[2].capitalize()\n", "\n", "print(list_items)\n", "\";\".join(list_items)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### The function `range` \n", "\n", "The function returns a range object:" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "range(1, 8, 2)" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# start, stop, step\n", "range(1, 8, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can make a list with the range object:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 3, 5, 7]" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# start, stop, step\n", "list(range(1, 8, 2))" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 3, 4, 5, 6, 7]" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# start, stop (step=1)\n", "list(range(2, 8))" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5, 6, 7]" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# stop argument (start=0, step=1)\n", "list(range(8))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Do it yourself\n", "\n", "Build a list of odd numbers in decreasing order." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Conditions: `if`, `elif`, `else`\n", "\n", "```python\n", "if expression:\n", " statement(s)\n", "else:\n", " statement(s)\n", "```\n", "\n", "The statement contains the block of code that executes if the conditional expression in the if statement resolves to 1 or a TRUE value." ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is equal to 0.\n" ] } ], "source": [ "a = 0\n", "if a == 0:\n", " print('a is equal to 0.')\n" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a is positive.\n" ] } ], "source": [ "a = 1\n", "if a < 0:\n", " print('a is negative.')\n", "elif a == 0:\n", " print('a is equal to 0.')\n", "elif a > 0:\n", " print('a is positive.')\n", "else:\n", " print(\"I don't know.\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Loops" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Loops with the keyword `while`\n", "\n" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i = 4\n" ] } ], "source": [ "i = 0\n", "while i < 4:\n", " i += 1\n", "print('i =', i)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i = 1\n", "i = 2\n", "i = 3\n", "i = 4\n" ] } ], "source": [ "i = 0\n", "while i < 4:\n", " i += 1\n", " print('i =', i)\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Do it yourself\n", "\n", "- Edit a script with the spyder editor that calculates the average of a set of numbers. For example `numbers = [67, 12, 2, 9, 23, 5]`\n", "\n", " * using the functions `sum` and `len`\n", " * manually, using the keyword `while`\n", " \n", "- Run the script \n", "\n", " * in spyder,\n", " * in a ipython session opened from another terminal,\n", " * with the command `python`." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### A possible solution:" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "19.666666666666668\n" ] } ], "source": [ "numbers = [67, 12, 2, 9, 23, 5]\n", "local_sum = 0\n", "i = 0\n", "while i < len(numbers):\n", " local_sum = local_sum + numbers[i]\n", " i = i+1\n", "avg = local_sum / len(numbers)\n", "print(avg)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Loops with the keyword `for`" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0, 1, 2, 3, 4, " ] } ], "source": [ "for index in range(5):\n", " print(index, end=', ')" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "grenoble, paris, berlin, london, " ] } ], "source": [ "cities = [\"grenoble\", \"paris\", \"berlin\", \"london\"]\n", "for city in cities:\n", " print(city, end=\", \")" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(0, grenoble)\n", "(1, paris)\n", "(2, berlin)\n", "(3, london)\n" ] } ], "source": [ "# the built-in function enumerate is very useful\n", "for index, city in enumerate(cities): \n", " print('({}, {})'.format(index, city))\n", " cities[index] = city.capitalize()" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['Grenoble', 'Paris', 'Berlin', 'London']" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cities" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Loops: keywords `continue` and `break`\n", "\n", "- `continue`: passes the block in the loop and continues the loop." ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1, 2, 3, 4, 6, 7, " ] } ], "source": [ "for x in range(1, 8):\n", " if x == 5:\n", " continue\n", " print(x, end=', ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- `break`: stop the loop." ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1, 2, 3, 4, " ] } ], "source": [ "for x in range(1, 11):\n", " if x == 5:\n", " break\n", " print(x, end=', ')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Do it yourself\n", "\n", "- Simplify your script by using a `for` loops.\n", "\n", "- In ipython, try to understand how the function `enumerate` works. Use it in your script.\n", "\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### A possible solution:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "19.666666666666668\n" ] } ], "source": [ "l = [67, 12, 2, 9, 23, 5]\n", "local_sum = 0\n", "for e in l:\n", " local_sum += e\n", "avg = local_sum / len(l)\n", "print(avg)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Do it yourself\n", "\n", "We build a list:" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "integer remove from the list: 9\n", "shuffled list: [13, 16, 15, 14, 5, 17, 12, 8, 11, 1, 18, 2, 10, 19, 4, 7, 0, 6, 3]\n" ] } ], "source": [ "from random import shuffle, randint\n", "\n", "n = 20\n", "i = randint(0, n-1)\n", "print('integer remove from the list:', i)\n", "l = list(range(n))\n", "l.remove(i)\n", "shuffle(l)\n", "print('shuffled list: ', l)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One element has been removed:\n", "\n", "- Find this element (given that you can change the ordering of `l`).\n", "- Find this element (given that you cannot change the ordering of `l`)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### A possible solution:" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[13, 16, 15, 14, 5, 17, 12, 8, 11, 1, 18, 2, 10, 19, 4, 7, 0, 6, 3]\n", "[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]\n", "missing 9\n" ] } ], "source": [ "# we can change ordering, let's sort\n", "print(l)\n", "l_sorted = sorted(l)\n", "print(l_sorted)\n", "found = None\n", "for idx, elem in enumerate(l_sorted):\n", " if elem != idx:\n", " found = idx\n", " break\n", "if found is None:\n", " found = len(l)\n", "print(\"missing \", idx)\n", " " ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "missing 9\n" ] } ], "source": [ "# we cannot sort -> higher complexity\n", "for elem in range(len(l)+1):\n", " if elem not in l:\n", " break\n", "print(\"missing \", elem)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "missing 9\n" ] } ], "source": [ "# another solution\n", "actual_sum = sum(l)\n", "len_l = len(l)\n", "original_sum = (len_l + 1) * (len_l) // 2\n", "print(\"missing \", original_sum - actual_sum)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exceptions and `try`, `except` syntax" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Exceptions and errors are common in all codes. There is a good system to handle them in Python. Let's first see what gives such buggy code\n", "\n", "```python\n", "l = ['a']\n", "i = 1\n", "print(l[i])\n", "```\n", "\n", "When these lines are executed, Python stops its execution and print a traceback:\n", "```text\n", "---------------------------------------------------------------------------\n", "IndexError Traceback (most recent call last)\n", " in ()\n", " 1 l = ['a']\n", " 2 i = 1\n", "----> 3 print(l[i])\n", "\n", "IndexError: list index out of range\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Exceptions and `try`, `except` syntax\n", "\n", "Handling exception:" ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "list index out of range\n" ] } ], "source": [ "l = ['a']\n", "i = 1\n", "try:\n", " print(l[i])\n", "except IndexError as e:\n", " print(e)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remark: never use \n", "```python \n", "except:\n", "```\n", "It means \"except all errors and exceptions\". A user Control-C is an exception (`KeyboardInterrupt`) so it would be caught and have no effect." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Full syntax\n", "\n", "```python\n", "try:\n", " ...\n", "except as e1:\n", " ...\n", "except as e2:\n", " ...\n", "else:\n", " ...\n", "finally:\n", " ...\n", "```\n", "\n", "[Non exhaustive error list](https://docs.python.org/3/library/exceptions.html):\n", "\n", "- ArithmeticError\n", "- ZeroDivisionError\n", "- IndexError\n", "- KeyError\n", "- AttributeError\n", "- IOError\n", "- ImportError\n", "- NameError\n", "- SyntaxError\n", "- TypeError" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Do it yourself: \n", "\n", "For each line of this string, append a variable of correct type in a list (i.e. \"hello\" should stay hello, \n", "2 should become an int and 1.5 a float). Do it by catching errors.\n", "\n", "**Hints:** \n", " - int(\"a\") and float(\"a\") raise ValueError\n", " - the above str_variable can be split using \"\\n\"" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [], "source": [ "str_variables = \"\"\"hello\n", "1.5\n", "2\"\"\"\n", "\n", "the_list_you_should_get = [\"hello\", 1.5, 2]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### A possible solution:" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hello is not a int\n", "hello is not a float\n", "1.5 is not a int\n", "['hello', 1.5, 2]\n" ] } ], "source": [ "split_list = []\n", "for value in str_variables.split(\"\\n\"):\n", " try:\n", " value = int(value)\n", " except ValueError: \n", " print(value, \"is not a int\")\n", " try:\n", " value = float(value)\n", " except ValueError:\n", " print(value, 'is not a float')\n", " split_list.append(value)\n", "\n", " \n", "print(split_list)" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2" }, "pycharm": { "stem_cell": { "cell_type": "raw", "source": [], "metadata": { "collapsed": false } } } }, "nbformat": 4, "nbformat_minor": 2 }