{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Lecture 2: Python Syntax" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "507331f6-2beb-425c-89a6-21ff3bbdeb6f" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# Lecture 2: Python Syntax\n", "- Syntax and basics of Python\n", "- The Python interpreter\n", "- Goal: kickstart your Python knowledge
\n", " to the same level as M-students have in Matlab\n", "\n", "Recommended reading:\n", "- [1] Chapter 1.6, 2.1-2.2, 3, 4, 5, 6, 8\n", "- [2] Section 3, 4, 5\n", "\n", "[1] C. Horstmann: Python for everyone
\n", "[2] Python tutorial: https://docs.python.org/3/tutorial/" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Contents" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- Basic Types\n", " - `int`, `float`, `str`, `type`\n", " - type conversion\n", "- Data structures\n", " - `str`, `tuple`, `list`, `set`, `dict`\n", " - indexing and slicing, `del`\n", "- Control flow statements\n", " - Conditionals `if`, `elif`, `else`\n", " - `while`, `for`, `enumerate`, `zip`, `itertools`, iterators\n", " - list comprehensions, one-liners\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- Operators\n", " - Numerical operations, inplace operations\n", " - Division in Python 2 and 3\n", " - Boolean operators, bitwise operators\n", "- Functions\n", " - `def`, `lambda`, `return`, scope\n", " - `*args`, positional arguments\n", " - `**kwargs`, keyword arguments (with default values)\n", " - argument expansion, arbitrary argument list" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- References and copies\n", "- Introspection and help\n", " - `dir`, `help`\n", " - doc-strings\n", "- Packages and modules\n", " - `import`, `from x import y as z`\n", "- Error messages " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Basic Types\n", "- `int`, `float`, `str`\n", "- `type` and type conversion" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "e6431f55-51c0-41c5-951b-70b37e49c365" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "# Values and data types\n", "You can check the type of almost any value" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "77a62f08-4e10-4c89-9f3b-51e5e76ac0d0" } }, "outputs": [], "source": [ "type(3.14)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "18002cdf-6933-45c0-85e5-513a01fb1036" } }, "outputs": [], "source": [ "type('Hello World')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "3bde17f1-a6cb-4f0d-b3db-bcfbe031c829" } }, "outputs": [], "source": [ "type(100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "4bddacdf-9a2c-48cb-a0ba-c0251b48fbe4" } }, "outputs": [], "source": [ "type(True)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "9f574043-b03e-49ee-8ab9-42b1d1a075d5" } }, "source": [ "The types `float`, `int`, `str`, `bool`, etc. have the type: `type`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "18d8ae83-aec7-4fe0-ad0c-270be21d2f89" } }, "outputs": [], "source": [ "type(int)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c50d91da-74dd-446a-bb61-8f247ff0ac69" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Type conversion\n", "* Changing types is possible through the built in functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "5d5f24d7-2665-4a7f-bb12-8f74c6a9d0d1" } }, "outputs": [], "source": [ "x = int('123')\n", "type(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "9c8625b8-0447-43fb-b6d8-f8209997f656" } }, "outputs": [], "source": [ "x = str(45.3)\n", "type(x)\n", "print(x, type(x))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "3bddc5e7-f622-4726-93ab-ae9413ccc453" } }, "source": [ "But only if there the conversion makes sense" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "d2cf1a9a-1af9-4939-81da-76ee1ab7f7bb" } }, "outputs": [], "source": [ "x = int('Carl')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Data structures\n", "- `str`\n", "- `tuple`, `list`, `set`, `dict`\n", "- indexing and slicing\n", "- `del`" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "d0f3b5db-1e83-4a9a-a74d-41dbe9c9735a" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Strings: `str`\n", "- Similar to Matlab and other languages." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "07c3ed0e-5d70-411e-99aa-caf28aee2722" } }, "outputs": [], "source": [ "a = 'Hello World'\n", "b = \"Hello World\"\n", "c = \"\"\"Hello World\"\"\"\n", "d = '''Hello World'''" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- Strings are immutable in Python
\n", "Immutable /ɪˈmjuːtəb(ə)l/:
*unchanging over time or unable to be changed*" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 'Hello World'\n", "a[0] = 'Y'" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "dc589740-3804-4519-988d-56141c8a6b44" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "* Line breaks and special characters just like in Matlab" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "ad3ef4dd-8adf-47ad-b864-fedf192673e4" } }, "outputs": [], "source": [ "a = 'Hello\\nWorld'\n", "print(a.upper())" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "43c74564-ba67-44be-875d-6a0cbf54dfdf" }, "slideshow": { "slide_type": "-" } }, "source": [ "* More on strings in Lecture 3\n", "* E.g. string methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "', '.join(s for s in dir('') if not '__' in s) # Brain-teaser! :)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "87590288-ada1-444a-a3ee-5ea52945e901" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Tuples: `tuple()`, `()`\n", "- Ordered (immutable) collection of objects\n", "- Often used to store objects of different types" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "7a18295b-ae75-49c4-84e1-04cf28c23227" } }, "outputs": [], "source": [ "x = (3.14, int, 'John')\n", "x = 3.14, int, 'John' # paranthesis are optional\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "306a0914-d80b-4021-915e-3cafd77621b6" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "* Tuple-methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "', '.join(s for s in dir(tuple()) if '__' not in s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "help(tuple().index)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = 'A', 'B', 'C'\n", "t.index('C')" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- Tuples are immutable (like strings)
\n", " and can _not_ be changed in place" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = (3.14, int, 'John')\n", "x[0] = 3.1415" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "13afa2ca-6eba-4f11-b4f7-56f2932fb8e5" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Tuple unpacking\n", "* A convenient syntax for splitting up all the components of a tuple" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "77e486fc-e8d7-4ac1-9a25-bd79f596982f" } }, "outputs": [], "source": [ "x = 3.14, int, 'John'\n", "a, b, c = x\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ddfd43f5-290f-478c-8ab7-41e852481355" } }, "source": [ "* Also works for `list`, `set` and `dict`
though this usage is more rare" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "c5c92359-0c4f-42a4-bdb0-a760ee843a96" } }, "outputs": [], "source": [ "x = ['Hello', 'Foo', 'World']\n", "a, b, c = x\n", "print(a, c)\n", "\n", "x = {1, 2, 2}\n", "a, b = x\n", "print(a, b)\n", "\n", "x = {'John': 37, 'Sara': 25, 'Lisa': 45}\n", "a, b, c = x.items()\n", "print(a, c)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ad1c8625-d5d2-46d7-8bb6-cb6c747d59c9" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Lists: `list()`, `[]`\n", "- Lists are your standard storage option\n", "- Mixing object types is possible but strongly discouraged (use `tuple`)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "94472fef-df50-44a4-be0e-025e400c51aa" } }, "outputs": [], "source": [ "x = [43, 10, 15]\n", "len(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "76a1060e-ac31-4064-8441-50f8ee6c14ea" } }, "source": [ "* Can store any object (including other lists)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "04817f91-572a-4e5c-a049-0ef8236478ae" } }, "outputs": [], "source": [ "y = ['Hello', 'World']\n", "z = [[1, 2, 3], [4, 2], [9, 4, 2]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Lists can be changed in place" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "z[2] = 41\n", "print(z)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "72752a62-2e9a-4ba9-9fb3-842cb24341d3" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## `list` methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "', '.join(s for s in dir(list()) if '__' not in s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "help(list().sort)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "b419621e-240a-4be2-a7e0-9ff7c6b6513b" } }, "outputs": [], "source": [ "x = [4,67,2,10]\n", "x.sort()\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "9d62814c-1097-48b5-b6ee-9878fc4b6f88" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Indexing and slicing\n", "- Using square brackets `[]`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "9f5c735f-4e9e-46cd-9f03-7cd0fac88bcd" } }, "outputs": [], "source": [ "x = [43, 10, 15]\n", "x[1]" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "62798424-1e50-4366-8cf4-fc69e8962851" } }, "source": [ "- **Note:** indexing starts from 0
\n", " Index measures distance from start.\n", "- Negative indices are counted from the end\n", "- `-1` is the index of the last element" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "9b5889b0-cf1e-4607-a893-74787e2bbd0d" } }, "outputs": [], "source": [ "x[-1]" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "686d6c04-d1b3-484e-8885-f744ad703628" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Slicing\n", "- Similar to that of Matlab, but in the order -`start:end:increment`*\n", " ```\n", "Matlab Python\n", "x(a:b:c) ~ x[(a-1):c:b]\n", "end ~ -1 or nothing:\n", "```\n", "- True for single index\n", " ```\n", "x(end) ~ x[-1]\n", "```\n", "- But `-1+1 = 0` so when using slicing, the syntax is to leave it out\n", " ```\n", "x(1:2:end) ~ x[::2]\n", "x(7:end) ~ x[6:]\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Slicing examples\n", "- Note that ranges are given in a half open interval description, `a:b` $= [a,b)$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x = ['my', 'short', 'list', 'of', 'strings']" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[0:2]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[1:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[:1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[0::2]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[0:2:3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f998df0f-370e-4998-902c-4bc00aa6bb56" } }, "outputs": [], "source": [ "x[::-1]" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0c0b3165-d2f4-4fc6-b3e7-99dc0a3a874f" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Sets: `set()`, `{}`\n", "* Sets are containers of unique items" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = {1, 2, 3, 2, 7, 2, 3, 2, 6}\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x.add(8)\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "y = x.intersection({1, 4, 5, 6, 10})\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- `set`-methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "', '.join(s for s in dir(set()) if '__' not in s)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "help(set().intersection)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "- Useful for \"set operations\": E.g. Find common elements in two lists" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "A = ['Ada', 'Beda', 'Emil', 'Emilia']\n", "B = ['Ada', 'Emilia', 'Eva', 'Greta']\n", "s = set(A).intersection(B)\n", "l = list(s)\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "5a052bc1-4e05-4159-9e55-04f1bea298f6" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Dictionaries: `dict()`, `{}`\n", "- Important data structure that is very common in Python programs\n", "- Set of \"key-value\" pairs\n", "- Also called maps\n", " ```python\n", "x[key] = value\n", "```\n", "representing the mapping of $key \\to value$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f0e8fb92-a559-4072-a0a7-9cf83543ff7c" } }, "outputs": [], "source": [ "x = {'John': 37, 'Sara': 25, 'Lisa': 45}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x['Lisa']" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "856b088d-1bdb-444b-98b3-cf4df0ffde91" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "It is very common to create an empty dictionary and
add new entries as required (e.g. values are read from a file)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "c5188d50-cfca-42a3-b6b4-8f6b0f010c39" } }, "outputs": [], "source": [ "x = dict() # or x = {}\n", "x['John'] = 37\n", "x['Sara'] = 25\n", "x['Lisa'] = 45" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "475d63fb-25c2-4a3f-8865-3a5e37e39989" } }, "outputs": [], "source": [ "print(x['John'])" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "91e64bd5-9c87-42fa-b130-8a956573772b" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "* Check for existence of keys using `in` and `not in`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "bb0aa0bf-f7c9-4dc2-b976-1353613ceaf1" } }, "outputs": [], "source": [ "print( 'Lisa' in x )\n", "print( 'Jeff' not in x )" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "dc7ec8dc-6a94-4810-920b-f3631caf0645" } }, "source": [ "* You get access the `keys`, `values`, or `(key,value)` pairs
as iterators (more on this later):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "14348082-2783-448a-9e5f-393abc14748b" } }, "outputs": [], "source": [ "print( x.keys() )\n", "print( x.values() )\n", "print( x.items() )" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "be87c361-ab5d-4e17-9e93-f255262c7a63" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Deleting: `del`\n", "\n", "- `del` can be used to remove elements in `list`, `dict`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "86ebe89c-c682-4a61-9db0-7798c75d88c8" } }, "outputs": [], "source": [ "x = [4,5,6,4,3,5,1]\n", "del x[3:]\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "069497d3-c792-4c9f-a29d-e84954a21174" } }, "outputs": [], "source": [ "x = {'John': 37, 'Sara': 25, 'Lisa': 45}\n", "del x['John']\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are also methods for \"consuming\" elements, like `.pop`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sara_age = x.pop('Sara')\n", "print(sara_age)\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- `del` can also be used to remove an object
(i.e. force garbage collection)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 10\n", "del x\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Control flow statements\n", "- Conditionals `if`, `elif`, `else`\n", "- Indentation\n", "- `while`, `for`, `enumerate`, `zip`, `itertools`, `.items()`\n", "- Iterators `type(enumerate(['A', 'B', 'C']))`\n", "- List comprehension\n", "- Single statement, single line;" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "fc4d0512-e1b5-4352-a9da-39bd07bbf0f4" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Conditionals: `if`, `elif`, `else`\n", "- Works as expected\n", "- Built in boolean values: `True`, `False`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "cb46d6ee-ab7c-42b5-8bd2-8f66e9971b3a" } }, "outputs": [], "source": [ "if False:\n", " print('Stuff here')\n", "elif True:\n", " print(\"Let's print\")\n", " print('many lines')\n", "else:\n", " print('Good bye!')" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "3af93dab-d9e7-41ac-8654-e5d794867bf6" } }, "source": [ "- Can be used directly in assignments" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "2e681014-0167-4b40-a35e-979c6fc049fa" } }, "outputs": [], "source": [ "a = 1\n", "x = 1 if a > 2 else \n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "e061973c-28d4-446e-aa11-482662dee73c" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Indentation\n", "- Indentation is **not** optional in Python.
\n", "- It determines the scope in control flow!\n", "- Using 4 spaces per indentation is **strongly** encouraged.\n", "- Statements ending with colon `:` require a following indented block" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Matlab conditionals\n", "```matlab\n", "if x\n", " f();\n", "elseif y\n", " g();\n", "end\n", "for x = y\n", " disp('foo');\n", "end\n", "if q\n", "end\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python conditionals\n", "```python\n", "if x:\n", " f()\n", "elif y:\n", " g()\n", "for x in y:\n", " print('foo')\n", "if q:\n", " pass # no-operation, needed to avoid syntax errors\n", "```" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "068cb936-632d-4c88-b887-2eef4f3b4bd3" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Boolean expressions\n", "- `in`, `not`, `and`, `or`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "dc0d2ee2-c7ce-47e0-a900-0ba88079fd39" } }, "outputs": [], "source": [ "print( 1 in [1,2,3] )\n", "print( 7 not in (4,3,5) )\n", "print( 'W' in 'World' )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "dc0d2ee2-c7ce-47e0-a900-0ba88079fd39" } }, "outputs": [], "source": [ "print( 6 != 5, 6 == 5 )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "dc0d2ee2-c7ce-47e0-a900-0ba88079fd39" } }, "outputs": [], "source": [ "print( 6 >= 5, 6 <= 5 )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "dc0d2ee2-c7ce-47e0-a900-0ba88079fd39" } }, "outputs": [], "source": [ "print( 6 > 5, 6 < 5 )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "50215bbd-e6e4-4f81-992a-2dd575e6aaa2" } }, "outputs": [], "source": [ "print( True or False )\n", "print( True and False )\n", "print( not True )" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0cd1049a-6dd3-4e11-a2a3-e6512b263177" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## While loops: `while`, `break`, `continue`\n", "- Syntax\n", " ```python\n", "while condition:\n", " do_stuff\n", "```\n", "- `break` and `continue` work as in Matlab\n", "- Q: What is printed below?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 0\n", "while x < 10:\n", " x = x + 1\n", " if x == 3:\n", " continue\n", " print(x, end=', ')\n", " if x > 6:\n", " break " ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "5279c98a-411a-4529-a41a-5411d93d94a5" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## For-loops: `for`\n", "- Loop directly over the content in iteratable containers\n", "- `tuple`, `list`, `set`, `dict`, etc." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "a3cba75b-8ba4-4b75-aa56-6a8cffba8bdb" } }, "outputs": [], "source": [ "foo = ['This', 'is', 'a', 'list']\n", "for x in foo:\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- `range(start, end+1, step)` iterator over integer ranges\n", "- C.f. Matlab's colon operator: `range(a, b, c) ~ a : c : (b-1) `" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "7217f000-6001-4abd-86aa-68b08e5b2d16" } }, "outputs": [], "source": [ "for i in range(5):\n", " print(i, end=', ')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "c2e1155e-1221-4344-a1cc-5f78ea9209be" } }, "outputs": [], "source": [ "for i in range(1, 10, 2):\n", " print(i, end=', ')" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "f765ea2a-97d5-4d5c-97b5-3ab417d7c662" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### `for` ... `dict`\n", "* Looping over dictionaries loops over the keys" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "519307f4-ba60-4cea-9f8c-6444e00cb21d" } }, "outputs": [], "source": [ "foo = {'John': 37, 'Sara': 25, 'Lisa': 45}\n", "for x in foo:\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "4cb486d0-ca12-4869-a26d-1413cb21ec1b" } }, "source": [ "* unless you specify otherwise" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "585f756c-0169-4591-9c3b-906c31e20d9a" } }, "outputs": [], "source": [ "foo = {'John': 37, 'Sara': 25, 'Lisa': 45}\n", "for x in foo.items():\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "91fde302-e451-4e53-a618-faff74e89159" } }, "source": [ "* We can also directly unpack variables in for-loops" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "4b5670f7-5d32-4926-8206-b95f2985160d" } }, "outputs": [], "source": [ "for key, value in foo.items():\n", " print(key, \"is\", value, \"years old\")" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "e80a29a0-a6ea-42a9-bf10-6da5c8d04def" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### `enumerate` and `zip`\n", "- To get both the index and the value use `enumerate`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "43cf1699-683b-4cf4-a667-1f81b4bcab4e" } }, "outputs": [], "source": [ "foo = ['This', 'is', 'a', 'list', 'of', 'strings']\n", "for i, x in enumerate(foo):\n", " print('counter is', i, 'and value is', x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "04df1a5e-d47b-4f54-bf0c-b1ce6c170830" } }, "source": [ "- To loop over 2 (or more) sequences together use `zip`\n", "- `zip` \"zips\" the sequences into a sequence of tuples" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "d82fcec6-d865-4bb6-98e8-c95320786f1f" } }, "outputs": [], "source": [ "x = [3, 7, 4, 9, 3, 0]\n", "y = \"qwerty\"\n", "z = {1, 2, 3}\n", "for i, c, i2 in zip(x, y, z):\n", " print(i, c, i2)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "659430d7-449c-4516-9f2b-4c1b65bed921" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Iterators\n", "- For performance, `zip` doesn't actually create a list\n", "- It returns an \"iterator\" that dynamically constructs tuples" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f9c0b226-9ed4-493c-a9c4-76433e95bf2e" } }, "outputs": [], "source": [ "z = zip(x,y)\n", "print(z)\n", "print(type(z))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "6fd39378-4277-4fdd-ab4d-04995f4fa85b" }, "slideshow": { "slide_type": "-" } }, "source": [ "- If a list is **really** needed use `list`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "10678919-507f-413c-8bbd-c99e1de42f19" } }, "outputs": [], "source": [ "z = list(zip(x,y))\n", "print(z)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c8d43428-c426-4c9b-b5ae-0b9b679126c4" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## Single statement, single line\n", "- `if`, `while`, `for` etc. can all be written on a single line
\n", " when there is just 1 statement inside the block. E.g." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "ed04dbcc-d720-4a47-ab8a-ee98dcb5ad10" } }, "outputs": [], "source": [ "if 3 > 0: print('It works!')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for s in ['This', 'works', 'too!']: print(s, end=' ')" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "d32ccbfa-c450-400f-b140-bfc4118b36aa" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## List comprehensions\n", "- Short, convenient, and fast syntax for creating lists\n", "- Use with care, _will_ make code unreadable" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "7acc652b-49b4-4c56-b9b2-de462a2b96e3" } }, "outputs": [], "source": [ "l = list()\n", "for i in range(5):\n", " l.append(i**2)\n", "print(l)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "l = [k**2 for k in range(5)]\n", "print( l )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "cf40277d-fd47-433d-85e3-4420b0705507" } }, "outputs": [], "source": [ "l = [k**2 for k in range(10) if k % 2 != 0]\n", "print( l )" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "323dba81-cbd3-4ffa-bebf-ee8d62f589e5" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "* Also works for `set` and `dict`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "4b7d0e4b-f9d5-485d-abe8-e6e27a976a8f" } }, "outputs": [], "source": [ "d = {k**2 for k in range(10)}\n", "print(d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "e736e1bf-a2a1-4f80-a194-f357b9b31711" } }, "outputs": [], "source": [ "l = ['John', 'Jeff', 'Carl']\n", "d = { key : idx**2 for idx, key in enumerate(l) }\n", "print(d)\n", "\n", "d = {}\n", "for idx, key in enumerate(l):\n", " d[key] = idx**2\n", "print(d)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Operators\n", "- Numerical operations; `+, -, *, /, **`\n", "- Acting on: `list`, `tuple`, `str`\n", "- Division in Python 2 and 3\n", "- Inplace; `+=, -=, *=, /=, //=`\n", "- Boolean operators; `==, is, in, >, <, >=, >=`\n", "- Bitwise operators; `>>, <<, &, |, ^`" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "1d612b6d-359e-47dd-9be5-7680dac53c32" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Binary operators" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "1d904cf7-fb76-401f-ae48-3254a3f79eab" } }, "outputs": [], "source": [ "print('4 + 3 =', 4 + 3)\n", "print('4 - 3 =', 4 - 3)\n", "print('4 * 3 =', 4 * 3)\n", "print('4 / 3 =', 4 / 3)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "31d9fdb8-3470-4355-89cf-d2bf89ef84e5" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Less obvious operators\n", " * `a ** b` $= a^b$\n", " * `a // b` $= \\lfloor a/b \\rfloor$\n", " * `a % b ` $= a \\,\\text{mod}\\, b$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "cc0992de-e3b8-4e65-8fdf-f7271c52ea0d" } }, "outputs": [], "source": [ "print('5 ** 3 =', 5 ** 3)\n", "print('5 // 3 =', 5 // 3)\n", "print('5 % 3 =', 5 % 3)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "e3993eb7-0c2e-4667-9521-70e32c9b9783" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## **Note:** Division in Python v2 and v3\n", "- In Python 3\n", " - `a / b` is floating point division\n", " - `a // b` is integer division\n", "- In Python 2\n", " - `a / b` is **integer division** (unexpected!?)\n", " - `a / float(b)` is floating point division\n", "- In Python 2 `a / b` can be made floating point division by\n", "```python\n", "from __future__ import division\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Here: Python 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "4 / 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "4 // 3" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "88e4282b-9e78-4cb4-94af-674b40c8db95" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Inplace assignment operators" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "ef4855fa-4b26-483b-92f3-2135e78e55f4" } }, "outputs": [], "source": [ "x = 1\n", "x += 2 # x = x + 2\n", "x *= 3 # x = x * 3\n", "x /= 4 # etc.\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "3bf25cdd-c2cc-41ca-b178-27d09608102c" } }, "outputs": [], "source": [ "x = 1\n", "x //= 2\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "cc0140bf-95dc-4a86-98d2-a8cd3e9e6d41" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Bitwise operators\n", "- Binary representations:\n", "$$41 = 2^5 + 2^3 + 2^0 = 101001_b$$\n", "$$28 = 2^4 + 2^3 + 2^2 = 011100_b$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "7aeeddbe-8f25-434d-bc6d-15ac7bbb152d" } }, "outputs": [], "source": [ "a = 0b101001\n", "b = 0b011100\n", "print('a = {:d} = 0b{:06b}'.format(a, a))\n", "print('b = {:d} = 0b{:06b}'.format(b, b))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- Bit wise and `&`, or `|`, xor `^`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 0b101001\n", "b = 0b011100" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('a & b = 0b{:06b}'.format( a & b ))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('a | b = 0b{:06b}'.format( a | b ))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('a ^ b = 0b{:06b}'.format( a ^ b ))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "- Bit shift operators `>>` and `<<`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "a5b20ec7-17bc-49fd-979b-48a5efde90ca" } }, "outputs": [], "source": [ "print(\"41 >> 1 =\", 41 >> 1)\n", "print(\"41 << 1 =\", 41 << 1)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c8c9f92c-78b0-4617-bd18-b248a46249c3" }, "slideshow": { "slide_type": "-" } }, "source": [ "- `X >> 1` shifts the bits one step to the right\n", " $$41 >> 1 = 101001_b >> 1 = 010100_b = 2^4 + 2^2 = 20$$\n", "\n", "- This is equal to integer division by 2, `X >> 1 == X // 2`\n", "\n", "- In general: `a >> b == a // (2**b)`" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "6fb1584b-38cb-4892-9c42-8d8508b263d9" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Operators acting on non-scalars\n", "- Operators are **not** the same as in Matlab\n", "- Different types work differently with operators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- `string`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "be24e135-8968-4920-a1fb-ec28865f1eb7" } }, "outputs": [], "source": [ "'Hello World' * 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "ca33a7d9-4db4-4d38-aa97-0df14f50afb0" } }, "outputs": [], "source": [ "'Hello' + ' ' + 'World'" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ad56b07a-5ec0-48ec-8842-f1eaa5b6ce66" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "- `list`, `tuple`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "81ccf5ce-c7d0-4db3-a293-8f7b4aa48bfe" } }, "outputs": [], "source": [ "[1, 2, 3] * 3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "984d0948-0a78-4ca8-8441-fec641efa1a1" } }, "outputs": [], "source": [ "(1, 2, 3) + (4, 5)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0f891b6e-f177-4c96-ac46-398e7eb22392" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# Functions\n", "- `def`\n", "- `return`\n", "- scope\n", "- `args`, positional arguments\n", "- `kwargs`, keyword arguments (with default values)\n", "- `*args`, `**kwargs`, positional and keyword argument expansion\n", "- arbitrary argument list" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "65e93857-4b62-4422-9c88-e39e650942f8" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Function definition: `def`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "b61fa38e-2085-49b6-a644-6be07b4a867f" } }, "outputs": [], "source": [ "def print_value(x):\n", " print('The value is:', x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print_value(13)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "174e45b3-cb0a-43d5-bca6-3a3d40ffe0cc" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Return value(s): `return`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def my_sum(a, b):\n", " return a + b" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(my_sum(1, 2))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "3d654074-2e70-44b5-ba3d-333006ac2823" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Multiple return values\n", "- Using `tuple` expansion (as advertised)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "3464805f-11ed-4129-9134-4f8cc86e9178" } }, "outputs": [], "source": [ "def multi_return_function(x):\n", " return x, x**2, x**3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "b51a34cf-b9da-4c6d-9de7-c2e49165ecfc" } }, "outputs": [], "source": [ "x = multi_return_function(3)\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a, b, c = multi_return_function(3)\n", "print('a = ', a, ', b = ', b, ', c = ', c, sep='')" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "46053d87-bfc6-48db-8181-c6bd2d956f12" }, "slideshow": { "slide_type": "-" } }, "source": [ "* Wrong number of arguments in the tuple expansion is an error" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "360d4892-c666-4d72-a5a8-fa2913769a3c" } }, "outputs": [], "source": [ "a, b = multi_return_function(3)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "abcf7a48-1e20-4df6-894f-72f9aa215b9f" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Optional arguments\n", "- Has to be in the end of the function argument list" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "21202558-4dec-4e05-9625-7727aa1d1bfe" } }, "outputs": [], "source": [ "def my_function(a, b=2, c=3): # b and c have default values and are optional\n", " return a + b + c" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c3944b51-8f5a-4dfa-bce4-d9971d2e26f0" } }, "source": [ "* These all give the same result (and will all have `a=1, b=2` and `c=3`)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "a7a718b2-fabd-4322-9103-195d13659414" } }, "outputs": [], "source": [ "print(my_function(1, 2, 3))\n", "print(my_function(1, 2))\n", "print(my_function(1))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "d5acb9f4-aafd-49a9-bba7-12b29361cd9b" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Key-word arguments\n", "- Set function parameters by name" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "cc754f44-f935-47f2-91e3-2be433ee9857" } }, "outputs": [], "source": [ "print(my_function(a=1, b=2, c=3))\n", "print(my_function( 1, b=2, c=3))\n", "print(my_function( 1, 2, c=3))\n", "print(my_function( 1, c=3, b=2))\n", "print(my_function( 1, b=2))\n", "print(my_function( 1, c=3))\n", "print(my_function(a=1, c=3))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "a6ffcfbd-dd82-4dc5-8886-f3df350d6402" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "* Parameters without a name **must** come before named parameters!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "ef11b9f2-7fe7-4e52-820f-11106410dc50" } }, "outputs": [], "source": [ "my_function(a=1, 2, 3) # Not OK!\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_function(1, b=2, 3) # Not OK!" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "e67826a7-b400-4030-8912-8300c8edddb3" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "### Argument expansion" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "facd2cf0-968e-41aa-b0d3-5547680db3a4" } }, "source": [ "- Expand `list` and `tuple` to positional arguments using the `*` operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "5682a39a-778d-4971-b74f-3d222bfb99f4" } }, "outputs": [], "source": [ "def my_sum(a, b, c):\n", " return a + b + c" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "be7e55f5-e67d-4178-8bbf-5a644d8c7312" } }, "outputs": [], "source": [ "x = [2, 3, 4]\n", "\n", "s = my_sum(*x) # Uses: \"a, b, c = x\"\n", "\n", "print(s)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Key-word argument expansion\n", "- Key-word arguments can be passed using a `dict`\n", "- The key-value pairs are expanded using the `**` operator" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def pet_info(name, kind=None, owner=None):\n", " \"\"\"Returns a string summarizing the info on the pet.\"\"\"\n", " out = name\n", " if kind is not None: out += ' is a ' + kind\n", " if owner is not None: out += ' owned by ' + owner\n", " out += '.'\n", " return out" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pets = [\n", " dict(name='Snoopy', kind='dog', owner='Charlie'),\n", " dict(name='Garfield', kind='cat', owner='Jon'),\n", " dict(name='Bamse', kind='bear'),\n", " ]\n", "\n", "for pet in pets: \n", " print(pet_info(**pet)) # Expand dict to key-word arguments" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Arbitrary arguments\n", "- Functions taking any number of positional and key-word arguments\n", "- Sometimes useful, but makes the function hard to read" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def my_general_argument_function(*args, **kwargs):\n", " print('Got positional arguments:', args)\n", " print('Got key-word arguments:', kwargs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_general_argument_function(\n", " 'one', 'argument', 'at', 'a', 'time',\n", " key='words', are='very', important='!')" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "69cdef07-6c0d-472a-8e3c-99ce0cb6c1f3" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Function variable scope\n", "- Functions inherit the local scope" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "92b1df99-4a26-498d-8521-5c17974fe960" } }, "outputs": [], "source": [ "c = 123\n", "def sum_1(a):\n", " return c + a\n", "\n", "print(sum_1(1))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def sum_2(a):\n", " c = 14 # c is a local variable (different from c above)\n", " return c + a\n", "\n", "print(sum_2(1))\n", "print(c) # c, in the outer scope is unchanged" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def sum_3(a):\n", " c += 17 # no modification of variables from the outer scope\n", " return c + a\n", "\n", "print(sum_3(1))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "bb12d5e8-acf5-449a-af85-1c100801b007" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Anonymous functions\n", "- Also known as `lambda` functions\n", "- C.f. Matlabs anonymous functions `@(x) x^2`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "f049bfb2-c69e-46ba-955e-a5e8c38c9edb" } }, "outputs": [], "source": [ "def axpy(a, x, y): # trivia: axpy is a standard name for a*x + y (in linear algebra packages)\n", " return a*x + y\n", "\n", "print(axpy(2, 3, 4))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "a5d7e7ea-0fdd-4eba-b1f2-b60282bb2c83" } }, "outputs": [], "source": [ "axpy_lambda = lambda a, x, y : a*x + y\n", "print(axpy_lambda(2, 3, 4))" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "59bdd306-033a-41ff-a393-1dbd53d006e2" }, "slideshow": { "slide_type": "fragment" } }, "source": [ "- Both are functions\n", "- The only difference is the syntax" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "fb5cb1a9-9cde-439e-90b4-66ad98bedeef" }, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "print(type(axpy), type(axpy_lambda))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Everything is an object" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## Functions are objects!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "def add_me(a, b): return a + b\n", "def mul_me(a, b): return a * b\n", "def div_me(a, b): return a / b\n", "\n", "functions = [add_me, mul_me, div_me]\n", "\n", "for f in functions:\n", " print(f(1, 2))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# References and copies\n", "- Assignment of primitive types gives copies" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 10\n", "b = a # b is a new int variable\n", "b += 1\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Assignment of containers `list`, `dict` etc. are **references**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = [10]\n", "b = a # b is a reference to the list a\n", "b[0] += 1\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "d7614560-7c48-40e8-9a79-2c2f3dc097a2" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "- Important corner cases" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "675a2422-3452-4017-b03e-663001e5b7fb" }, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "x = [1, 2, 3] # Create a list object and binds x to that object.\n", "y = x # Binds y to that same object x\n", "y += [4, 5] # += for lists means \"append to list\"\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "7dfd6ab5-6ca3-41ae-bbd5-cd530121bdf0" }, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "x = [1, 2, 3] # Create a list object and bind x to that object.\n", "y = x # Bind y to that same object\n", "y = y + [4, 5] # Create a new object from the list, use + list operation and re-bind y to that new object\n", "print(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "2e339147-6d8b-4a8b-acf1-9ccbe014ba05" }, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "x = [1, 2, 3] # Create a list object and bind x to that object\n", "z = (x, x) # Create a tuple object which contains references which are bound to the same object\n", "print('1:', z)\n", "x += [4, 5] # Append to list\n", "print('2:', z)\n", "x = [7, 8] # Rebind name x to a new list\n", "print('3:', z)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ab4d260a-8b5a-4fe1-aab0-c4cad60d2082" } }, "source": [ "- Well, the variable `z` has actually not changed (tuples are immutable)\n", "- It's still pointing to the same two list-objects" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "5bf167fd-a4bb-42c6-ad49-80070e5d2a38" }, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "x = [1, 2, 3]\n", "y = [x, x, [7, 8, 9]]\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ec95a968-20d7-4d13-a4ee-f38b6f1338de" } }, "source": [ "What will happen if we do:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "08fa3aeb-0f82-4618-8835-02e07cdaf0ee" } }, "outputs": [], "source": [ "y[0] = [4, 5, 6]\n", "print(x)\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c726ef50-d436-4424-9dd5-5de735c7e682" }, "slideshow": { "slide_type": "-" } }, "source": [ "The equal sign is the \"rebind variable\" operation!" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "9f551a16-537c-44ec-8c70-8ed689b42e7e" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "To really make a copy, use the slice `:`, or the `.copy()` method" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "0da078a5-725f-4846-9b34-2bffd971796b" } }, "outputs": [], "source": [ "x = [1, 2, 3]\n", "y = x[:]\n", "y += [4, 5]\n", "print(x, y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = [1, 2, 3]\n", "z = x.copy()\n", "z += [6, 7]\n", "print(x, z)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0f5f7bc0-e0b9-4918-bd38-0760ed1629a1" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Functions and references\n", "- Same behavior with references when it comes to function arguments" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "d32c962a-6256-4530-80dd-37d3d67700cd" } }, "outputs": [], "source": [ "def foo(x):\n", " x[0] = 42\n", "\n", "y = [1, 2, 3]\n", "foo(y) # This means foo(x = y), and x = y behaves as described earlier\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "b12f28e3-d895-4f70-a459-b423341a8c15" }, "slideshow": { "slide_type": "fragment" } }, "source": [ "* The equal sign `=` is variable name rebinding,
it doesn't modify the object that `x` was bound to previously." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "6197656d-c880-4fb6-9ca2-73d390ae4611" } }, "outputs": [], "source": [ "def foo(x):\n", " x = [4, 5, 6] \n", "\n", "y = [1, 2, 3]\n", "foo(y)\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "302b5c67-99b3-44c4-ba47-a756322c4983" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# Modules" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- In Python have few functions in the global scope (namespace)\n", "- C.f. Matlab were everything is available\n", "- Import modules to access functionality \n", "- Even basic things in the Python standard library" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## Module namespace\n", "- Each module has its own namespace (defaults to the library name)\n", "- Namespaces are good, let's use them!\n", "- They avoid name-collisions between common function names" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "fa7116ee-d215-4cb6-8dee-1b354d6ea79c" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Importing modules" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "d79cc12d-afee-4340-a944-5b36b2a6beac" } }, "outputs": [], "source": [ "import numpy\n", "numpy.sqrt(5)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "272c57d3-9768-468b-9320-8bb611d4ca29" }, "slideshow": { "slide_type": "fragment" } }, "source": [ "## Abbreviating the namespace" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "1c5b6ba4-1cdb-4989-ab7c-2613353304dd" } }, "outputs": [], "source": [ "import numpy as np\n", "np.sqrt(5)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "061f28a6-8681-419f-9692-2844b85d530f" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Selective importing" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "Example: Solve $x^2 - 1 = 0$ numerically\n", "\n", "This is colloquially called: \"Root solving\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "b5d51509-cfcb-42a3-9b22-fc669414f2f6" }, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "from scipy.optimize import root\n", "\n", "root(lambda x: x**2 - 1, x0=0.1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "c87ed107-566d-489c-8df7-415f1e06f649" }, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "from scipy.optimize import root as scipy_root\n", "\n", "res = scipy_root(lambda x: x**2 - 1, x0=0.1)\n", "print(res.x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "be790436-f6ad-4428-a14d-c4d84f20c901" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "## Wildcards" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "981d7f5e-0052-4108-82c1-a4e46df8c1ad" } }, "source": [ "Using the wildcard, you import everything in that scope\n", "```python\n", "from numpy import *\n", "```\n", "but this practice is discouraged!! Why?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- The `numpy` module contains many functions, e.g. a function called `all`.\n", "- If `all` is defined in the program before the wildcard import, **it is lost!**\n", "- Very hard to debug..." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def all(): return 'Hi all!'\n", "print(all())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from numpy import *\n", "print(all())" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## The Python Standard Library\n", "- Python comes with \"batteries included\"\n", "- \n", "\n", "Examples:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "from datetime import datetime\n", "print(datetime.now())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "from itertools import permutations\n", "for pair in permutations(['A', 'B', 'C'], 2):\n", " print(pair, end=', ')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "from multiprocessing import Pool\n", "def my_calc(x): return x*x\n", "p = Pool(4)\n", "l = p.map(my_calc, [1, 2, 3, 4, 5, 6, 7, 8, 9])\n", "print(l)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Documentation" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Reference manuals\n", "PDF versions of the manuals for:\n", "- [Python 3](https://docs.python.org/3/),\n", "- [Numpy and SciPy](https://docs.scipy.org/doc/), and\n", "- [Matplotlib](https://matplotlib.org/contents.html), as well as\n", "- the [Lecture Notes](https://chalmers.instructure.com/courses/8757/modules)\n", "\n", "will be available on the exam. Check them out!" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "34e0513b-8ab8-4434-b110-86aaaa7310a3" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "# Built in `help`" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ca723da7-ad5f-49aa-8942-e4e9319272f9" } }, "source": [ "- `help` is a built in help function\n", "- You can run `help` on most things, functions, libraries, variables\n", "- Note that you need to pass the function or method (i.e. without parenthesis)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "725280c2-0232-4b47-bf89-d937f4874530" }, "slideshow": { "slide_type": "-" } }, "outputs": [], "source": [ "help(len)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Documenting your own functions\n", "- Document your functions using \"doc-strings\"\n", "- `help` will show this documentation\n", "- NumPy has a good [style guide]()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def my_sum(a, b):\n", " \"\"\"The sum of two numbers.\n", "\n", " Parameters\n", " ----------\n", " a : int\n", " First number\n", " b : int\n", " Second number\n", "\n", " Returns\n", " -------\n", " int\n", " Sum of a and b\n", " \"\"\"\n", " assert( type(a) == int )\n", " assert( type(b) == int )\n", " return a + b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "help(my_sum)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0d75eb41-2020-4b25-a8ed-75ab1e6d1922" }, "slideshow": { "slide_type": "slide" } }, "source": [ "# Errors\n", "- Many examples in this lecture\n", "- Syntax errors are probably going to be common" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "7f2c3522-5c8a-4523-b68a-ff876678985a" } }, "outputs": [], "source": [ "x = 123 + /34" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "c9f167c8-c002-493e-828d-2ba17b4b064e" } }, "outputs": [], "source": [ "132/0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "nbpresent": { "id": "26cdf0e4-c5cb-4228-a1d6-dad293792208" } }, "outputs": [], "source": [ "x = [1,2,3]\n", "x[8]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# The many ways of Python" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "There are many ways to use and interact with Python\n", "- Running `.py` on the command line, using the `python` interpreter\n", "- Interactively using the `python` interpreter\n", "- Interactively using the \"smart\" `ipython` interpreter\n", "\n", "Demo!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "- Interactively using the Jupyter notebook interface\n", "- Using a development GUI like `PyCharm`, perfect for developing GUI applications!\n", "\n", "We warmy recommend `PyCharm` for learning in this course! (the free version)
\n", "(It is possible to [apply](https://www.jetbrains.com/student/) for a \"full\" version as a student)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Lecture 2: The End" ] } ], "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.6" } }, "nbformat": 4, "nbformat_minor": 4 }