Skip to content

Instantly share code, notes, and snippets.

@mr-eyes
Last active October 14, 2019 15:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mr-eyes/a6b62dc47c9ce86a497a9b29cae283d4 to your computer and use it in GitHub Desktop.
Save mr-eyes/a6b62dc47c9ce86a497a9b29cae283d4 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p align=\"center\">\n",
" <a href=\"http://bioinfo.edu.eg/\">\n",
" <img src=\"https://nu.edu.eg/wp-content/uploads/2017/02/nu_logo.png\" alt=\"mlLAB1\" width=\"150\" height=\"150\">\n",
" </a>\n",
" <h2 align=\"center\">Machine Learning - LAB01</h2>\n",
"\n",
"</p>\n",
"\n",
"[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gist/mr-eyes/a6b62dc47c9ce86a497a9b29cae283d4/master)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## IPython notebooks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This file - an IPython notebook - does not follow the standard pattern with Python code in a text file. Instead, an IPython notebook is stored as a file in the [JSON](http://en.wikipedia.org/wiki/JSON) format. The advantage is that we can mix formatted text, Python code and code output. It requires the IPython notebook server to run it though, and therefore isn't a stand-alone Python program as described above. Other than that, there is no difference between the Python code that goes into a program file or an IPython notebook."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Modules"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most of the functionality in Python is provided by *modules*. The Python Standard Library is a large collection of modules that provides *cross-platform* implementations of common facilities such as access to the operating system, file I/O, string management, network communication, and much more."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import math"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This includes the whole module and makes it available for use later in the program. For example, we can do:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.0\n"
]
}
],
"source": [
"import math\n",
"\n",
"x = math.cos(2 * math.pi)\n",
"\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, we can chose to import all symbols (functions and variables) in a module to the current namespace (so that we don't need to use the prefix \"`math.`\" every time we use something from the `math` module:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.0\n"
]
}
],
"source": [
"from math import *\n",
"\n",
"x = cos(2 * pi)\n",
"\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This pattern can be very convenient, but in large programs that include many modules it is often a good idea to keep the symbols from each module in their own namespaces, by using the `import math` pattern. This would elminate potentially confusing problems with name space collisions.\n",
"\n",
"As a third alternative, we can chose to import only a few selected symbols from a module by explicitly listing which ones we want to import instead of using the wildcard character `*`:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.0\n"
]
}
],
"source": [
"from math import cos, pi\n",
"\n",
"x = cos(2 * pi)\n",
"\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Looking at what a module contains, and its documentation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once a module is imported, we can list the symbols it provides using the `dir` function:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']\n"
]
}
],
"source": [
"import math\n",
"\n",
"print(dir(math))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And using the function `help` we can get a description of each function (almost .. not all functions have docstrings, as they are technically called, but the vast majority of functions are documented this way). "
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on built-in function log in module math:\n",
"\n",
"log(...)\n",
" log(x[, base])\n",
" \n",
" Return the logarithm of x to the given base.\n",
" If the base not specified, returns the natural logarithm (base e) of x.\n",
"\n"
]
}
],
"source": [
"help(math.log)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2.302585092994046"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"log(10)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3.3219280948873626"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"log(10, 2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also use the `help` function directly on modules: Try\n",
"\n",
" help(math) \n",
"\n",
"Some very useful modules form the Python standard library are `os`, `sys`, `math`, `shutil`, `re`, `subprocess`, `multiprocessing`, `threading`. \n",
"\n",
"A complete lists of standard modules for Python 2 and Python 3 are available at http://docs.python.org/2/library/ and http://docs.python.org/3/library/, respectively."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Variables and types"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Symbol names "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Variable names in Python can contain alphanumerical characters `a-z`, `A-Z`, `0-9` and some special characters such as `_`. Normal variable names must start with a letter. \n",
"\n",
"By convention, variable names start with a lower-case letter, and Class names start with a capital letter. \n",
"\n",
"In addition, there are a number of Python keywords that cannot be used as variable names. These keywords are:\n",
"\n",
" and, as, assert, break, class, continue, def, del, elif, else, except, \n",
" exec, finally, for, from, global, if, import, in, is, lambda, not, or,\n",
" pass, print, raise, return, try, while, with, yield\n",
"\n",
"Note: Be aware of the keyword `lambda`, which could easily be a natural variable name in a scientific program. But being a keyword, it cannot be used as a variable name."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Assignment"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"The assignment operator in Python is `=`. Python is a dynamically typed language, so we do not need to specify the type of a variable when we create one.\n",
"\n",
"Assigning a value to a new variable creates the variable:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# variable assignments\n",
"x = 1.0\n",
"my_variable = 12.2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Although not explicitly specified, a variable does have a type associated with it. The type is derived from the value that was assigned to it."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"float"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we assign a new value to a variable, its type can change."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"x = 1"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"int"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we try to use a variable that has not yet been defined we get an `NameError`:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'y' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-16-d9183e048de3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'y' is not defined"
]
}
],
"source": [
"print(y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Fundamental types"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"int"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# integers\n",
"x = 1\n",
"type(x)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"float"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# float\n",
"x = 1.0\n",
"type(x)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"bool"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# boolean\n",
"b1 = True\n",
"b2 = False\n",
"\n",
"type(b1)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"complex"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# complex numbers: note the use of `j` to specify the imaginary part\n",
"x = 1.0 - 1.0j\n",
"type(x)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1-1j)\n"
]
}
],
"source": [
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.0 -1.0\n"
]
}
],
"source": [
"print(x.real, x.imag)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Type validation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 1.0\n",
"\n",
"# check if the variable x is a float\n",
"type(x) is float"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# check if the variable x is an int\n",
"type(x) is int"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also use the `isinstance` method for testing types of variables:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"isinstance(x, float)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Type casting"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.5 <class 'float'>\n"
]
}
],
"source": [
"x = 1.5\n",
"\n",
"print(x, type(x))"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 <class 'int'>\n"
]
}
],
"source": [
"x = int(x)\n",
"\n",
"print(x, type(x))"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1+0j) <class 'complex'>\n"
]
}
],
"source": [
"z = complex(x)\n",
"\n",
"print(z, type(z))"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "can't convert complex to float",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-29-19c840f40bd8>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mz\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: can't convert complex to float"
]
}
],
"source": [
"x = float(z)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Complex variables cannot be cast to floats or integers. We need to use `z.real` or `z.imag` to extract the part of the complex number we want:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.0 -> True <class 'bool'>\n",
"0.0 -> False <class 'bool'>\n"
]
}
],
"source": [
"y = bool(z.real)\n",
"\n",
"print(z.real, \" -> \", y, type(y))\n",
"\n",
"y = bool(z.imag)\n",
"\n",
"print(z.imag, \" -> \", y, type(y))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Operators and comparisons"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most operators and comparisons in Python work as one would expect:\n",
"\n",
"* Arithmetic operators `+`, `-`, `*`, `/`, `//` (integer division), '**' power\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3, -1, 2, 0.5)"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1 + 2, 1 - 2, 1 * 2, 1 / 2"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3.0, -1.0, 2.0, 0.5)"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.0"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Integer division of float numbers\n",
"3.0 // 2.0"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Note! The power operators in python isn't ^, but **\n",
"2 ** 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note: The `/` operator always performs a floating point division in Python 3.x.\n",
"This is not true in Python 2.x, where the result of `/` is always an integer if the operands are integers.\n",
"to be more specific, `1/2 = 0.5` (`float`) in Python 3.x, and `1/2 = 0` (`int`) in Python 2.x (but `1.0/2 = 0.5` in Python 2.x)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* The boolean operators are spelled out as the words `and`, `not`, `or`. "
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True and False"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"not False"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"True or False"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* Comparison operators `>`, `<`, `>=` (greater or equal), `<=` (less or equal), `==` equality, `is` identical."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(True, False)"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 > 1, 2 < 1"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(False, False)"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 > 2, 2 < 2"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(True, True)"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 >= 2, 2 <= 2"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# equality\n",
"[1,2] == [1,2]"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# objects identical?\n",
"l1 = l2 = [1,2]\n",
"\n",
"l1 is l2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Compound types: Strings, List and dictionaries"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Strings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Strings are the variable type that is used for storing text messages. "
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"str"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = \"Hello world\"\n",
"type(s)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"11"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# length of the string: the number of characters\n",
"len(s)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello test\n"
]
}
],
"source": [
"# replace a substring in a string with something else\n",
"s2 = s.replace(\"world\", \"test\")\n",
"print(s2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can index a character in a string using `[]`:"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'H'"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can extract a part of a string using the syntax `[start:stop]`, which extracts characters between index `start` and `stop` -1 (the character at index `stop` is not included):"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Hello'"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[0:5]"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'o'"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[4:5]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we omit either (or both) of `start` or `stop` from `[start:stop]`, the default is the beginning and the end of the string, respectively:"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Hello'"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[:5]"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'world'"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[6:]"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Hello world'"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also define the step size using the syntax `[start:end:step]` (the default value for `step` is 1, as we saw above):"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Hello world'"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[::1]"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Hlowrd'"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s[::2]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### String formatting examples \"fstrings\""
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [],
"source": [
"a = \"Hello\"\n",
"b = 1000\n",
"c = 9.5"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"variable a = Hello \n",
"variable b = 1000 \n",
"variable c = 9.5\n"
]
}
],
"source": [
"print(f\"variable a = {a} \\nvariable b = {b} \\nvariable c = {c}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### List"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lists are very similar to strings, except that each element can be of any type.\n",
"\n",
"The syntax for creating lists in Python is `[...]`:"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'list'>\n",
"[1, 2, 3, 4]\n"
]
}
],
"source": [
"l = [1,2,3,4]\n",
"\n",
"print(type(l))\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can use the same slicing techniques to manipulate lists as we could use on strings:"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4]\n",
"[2, 3]\n",
"[1, 3]\n"
]
}
],
"source": [
"print(l)\n",
"\n",
"print(l[1:3])\n",
"\n",
"print(l[::2])"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"l[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Elements in a list do not all have to be of the same type:"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 'a', 1.0, (1-1j)]\n"
]
}
],
"source": [
"l = [1, 'a', 1.0, 1-1j]\n",
"\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python lists can be inhomogeneous and arbitrarily nested:"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, [2, [3, [4, [5]]]]]"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"nested_list = [1, [2, [3, [4, [5]]]]]\n",
"\n",
"nested_list"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lists play a very important role in Python. For example they are used in loops and other flow control structures (discussed below). There are a number of convenient functions for generating lists of various types, for example the `range` function:"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"range(10, 30, 2)"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"start = 10\n",
"stop = 30\n",
"step = 2\n",
"\n",
"range(start, stop, step)"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# in python 3 range generates an iterator, which can be converted to a list using 'list(...)'.\n",
"# It has no effect in python 2\n",
"list(range(start, stop, step))"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(range(-10, 10))"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"s = \"hello world\""
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# convert a string to a list by type casting:\n",
"s2 = list(s)\n",
"\n",
"s2"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[' ', 'd', 'e', 'h', 'l', 'l', 'l', 'o', 'o', 'r', 'w']\n"
]
}
],
"source": [
"# sorting lists\n",
"s2.sort()\n",
"\n",
"print(s2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Adding, inserting, modifying, and removing elements from lists"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['A', 'd', 'd']\n"
]
}
],
"source": [
"# create a new empty list\n",
"l = []\n",
"\n",
"# add an elements using `append`\n",
"l.append(\"A\")\n",
"l.append(\"d\")\n",
"l.append(\"d\")\n",
"\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can modify lists by assigning new values to elements in the list. In technical jargon, lists are *mutable*."
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['A', 'p', 'p']\n"
]
}
],
"source": [
"l[1] = \"p\"\n",
"l[2] = \"p\"\n",
"\n",
"print(l)"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['A', 'd', 'd']\n"
]
}
],
"source": [
"l[1:3] = [\"d\", \"d\"]\n",
"\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Insert an element at an specific index using `insert`"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['i', 'n', 's', 'e', 'r', 't', 'A', 'd', 'd']\n"
]
}
],
"source": [
"l.insert(0, \"i\")\n",
"l.insert(1, \"n\")\n",
"l.insert(2, \"s\")\n",
"l.insert(3, \"e\")\n",
"l.insert(4, \"r\")\n",
"l.insert(5, \"t\")\n",
"\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remove first element with specific value using 'remove'"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['i', 'n', 's', 'e', 'r', 't', 'd', 'd']\n"
]
}
],
"source": [
"l.remove(\"A\")\n",
"\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remove an element at a specific location using `del`:"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['i', 'n', 's', 'e', 'r', 't']\n"
]
}
],
"source": [
"del l[7]\n",
"del l[6]\n",
"\n",
"print(l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See `help(list)` for more details, or read the online documentation "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Tuples"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tuples are like lists, except that they cannot be modified once created, that is they are *immutable*. \n",
"\n",
"In Python, tuples are created using the syntax `(..., ..., ...)`, or even `..., ...`:"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(10, 20) <class 'tuple'>\n"
]
}
],
"source": [
"point = (10, 20)\n",
"\n",
"print(point, type(point))"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(10, 20) <class 'tuple'>\n"
]
}
],
"source": [
"point = 10, 20\n",
"\n",
"print(point, type(point))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can unpack a tuple by assigning it to a comma-separated list of variables:"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x = 10\n",
"y = 20\n"
]
}
],
"source": [
"x, y = point\n",
"\n",
"print(\"x =\", x)\n",
"print(\"y =\", y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we try to assign a new value to an element in a tuple we get an error:"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "'tuple' object does not support item assignment",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-76-9734b1daa940>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpoint\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
]
}
],
"source": [
"point[0] = 20"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Dictionaries"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dictionaries are also like lists, except that each element is a key-value pair. The syntax for dictionaries is `{key1 : value1, ...}`:"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'dict'>\n",
"{'parameter1': 1.0, 'parameter2': 2.0, 'parameter3': 3.0}\n"
]
}
],
"source": [
"params = {\"parameter1\" : 1.0,\n",
" \"parameter2\" : 2.0,\n",
" \"parameter3\" : 3.0,}\n",
"\n",
"print(type(params))\n",
"print(params)"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"parameter1 = 1.0\n",
"parameter2 = 2.0\n",
"parameter3 = 3.0\n"
]
}
],
"source": [
"print(\"parameter1 = \" + str(params[\"parameter1\"]))\n",
"print(\"parameter2 = \" + str(params[\"parameter2\"]))\n",
"print(\"parameter3 = \" + str(params[\"parameter3\"]))"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"parameter1 = A\n",
"parameter2 = B\n",
"parameter3 = 3.0\n",
"parameter4 = D\n"
]
}
],
"source": [
"params[\"parameter1\"] = \"A\"\n",
"params[\"parameter2\"] = \"B\"\n",
"\n",
"# add a new entry\n",
"params[\"parameter4\"] = \"D\"\n",
"\n",
"print(\"parameter1 = \" + str(params[\"parameter1\"]))\n",
"print(\"parameter2 = \" + str(params[\"parameter2\"]))\n",
"print(\"parameter3 = \" + str(params[\"parameter3\"]))\n",
"print(\"parameter4 = \" + str(params[\"parameter4\"]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Control Flow"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Conditional statements: if, elif, else"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Python syntax for conditional execution of code uses the keywords `if`, `elif` (else if), `else`:"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"statement1 and statement2 are False\n"
]
}
],
"source": [
"statement1 = False\n",
"statement2 = False\n",
"\n",
"if statement1:\n",
" print(\"statement1 is True\")\n",
" \n",
"elif statement2:\n",
" print(\"statement2 is True\")\n",
" \n",
"else:\n",
" print(\"statement1 and statement2 are False\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For the first time, here we encounted a peculiar and unusual aspect of the Python programming language: Program blocks are defined by their indentation level. \n",
"\n",
"Compare to the equivalent C code:\n",
"\n",
" if (statement1)\n",
" {\n",
" printf(\"statement1 is True\\n\");\n",
" }\n",
" else if (statement2)\n",
" {\n",
" printf(\"statement2 is True\\n\");\n",
" }\n",
" else\n",
" {\n",
" printf(\"statement1 and statement2 are False\\n\");\n",
" }\n",
"\n",
"In C blocks are defined by the enclosing curly brakets `{` and `}`. And the level of indentation (white space before the code statements) does not matter (completely optional). \n",
"\n",
"But in Python, the extent of a code block is defined by the indentation level (usually a tab or say four white spaces). This means that we have to be careful to indent our code correctly, or else we will get syntax errors. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Examples:"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"both statement1 and statement2 are True\n"
]
}
],
"source": [
"statement1 = statement2 = True\n",
"\n",
"if statement1:\n",
" if statement2:\n",
" print(\"both statement1 and statement2 are True\")"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"ename": "IndentationError",
"evalue": "expected an indented block (<ipython-input-82-ac4109c9123a>, line 4)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-82-ac4109c9123a>\"\u001b[0;36m, line \u001b[0;32m4\u001b[0m\n\u001b[0;31m print(\"both statement1 and statement2 are True\") # this line is not properly indented\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n"
]
}
],
"source": [
"# Bad indentation!\n",
"if statement1:\n",
" if statement2:\n",
" print(\"both statement1 and statement2 are True\") # this line is not properly indented"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [],
"source": [
"statement1 = False \n",
"\n",
"if statement1:\n",
" print(\"printed if statement1 is True\")\n",
" \n",
" print(\"still inside the if block\")"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"now outside the if block\n"
]
}
],
"source": [
"if statement1:\n",
" print(\"printed if statement1 is True\")\n",
" \n",
"print(\"now outside the if block\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Loops"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In Python, loops can be programmed in a number of different ways. The most common is the `for` loop, which is used together with iterable objects, such as lists. The basic syntax is:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **`for` loops**:"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n"
]
}
],
"source": [
"for x in [1,2,3]:\n",
" print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `for` loop iterates over the elements of the supplied list, and executes the containing block once for each element. Any kind of list can be used in the `for` loop. For example:"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n"
]
}
],
"source": [
"for x in range(4): # by default range start at 0\n",
" print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note: `range(4)` does not include 4 !"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-3\n",
"-2\n",
"-1\n",
"0\n",
"1\n",
"2\n"
]
}
],
"source": [
"for x in range(-3,3):\n",
" print(x)"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"scientific\n",
"computing\n",
"with\n",
"python\n"
]
}
],
"source": [
"for word in [\"scientific\", \"computing\", \"with\", \"python\"]:\n",
" print(word)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To iterate over key-value pairs of a dictionary:"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"parameter1 = A\n",
"parameter2 = B\n",
"parameter3 = 3.0\n",
"parameter4 = D\n"
]
}
],
"source": [
"for key, value in params.items():\n",
" print(key + \" = \" + str(value))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sometimes it is useful to have access to the indices of the values when iterating over a list. We can use the `enumerate` function for this:"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 -3\n",
"1 -2\n",
"2 -1\n",
"3 0\n",
"4 1\n",
"5 2\n"
]
}
],
"source": [
"for idx, x in enumerate(range(-3,3)):\n",
" print(idx, x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### List comprehensions: Creating lists using `for` loops:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A convenient and compact way to initialize lists:"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 1, 4, 9, 16]\n"
]
}
],
"source": [
"l1 = [x**2 for x in range(0,5)]\n",
"\n",
"print(l1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### `while` loops:"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n",
"done\n"
]
}
],
"source": [
"i = 0\n",
"\n",
"while i < 5:\n",
" print(i)\n",
" \n",
" i = i + 1\n",
" \n",
"print(\"done\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the `print(\"done\")` statement is not part of the `while` loop body because of the difference in indentation."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A function in Python is defined using the keyword `def`, followed by a function name, a signature within parentheses `()`, and a colon `:`. The following code, with one additional level of indentation, is the function body."
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [],
"source": [
"def func0(): \n",
" print(\"test\")"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"test\n"
]
}
],
"source": [
"func0()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Optionally, but highly recommended, we can define a so called \"docstring\", which is a description of the functions purpose and behaivor. The docstring should follow directly after the function definition, before the code in the function body."
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [],
"source": [
"def func1(s):\n",
" \"\"\"\n",
" Print a string 's' and tell how many characters it has \n",
" \"\"\"\n",
" \n",
" print(s + \" has \" + str(len(s)) + \" characters\")"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Help on function func1 in module __main__:\n",
"\n",
"func1(s)\n",
" Print a string 's' and tell how many characters it has\n",
"\n"
]
}
],
"source": [
"help(func1)"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"test has 4 characters\n"
]
}
],
"source": [
"func1(\"test\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Functions that returns a value use the `return` keyword:"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [],
"source": [
"def square(x):\n",
" \"\"\"\n",
" Return the square of x.\n",
" \"\"\"\n",
" return x ** 2"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"16"
]
},
"execution_count": 99,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"square(4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can return multiple values from a function using tuples (see above):"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [],
"source": [
"def powers(x):\n",
" \"\"\"\n",
" Return a few powers of x.\n",
" \"\"\"\n",
" return x ** 2, x ** 3, x ** 4"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(9, 27, 81)"
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"powers(3)"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"27\n"
]
}
],
"source": [
"x2, x3, x4 = powers(3)\n",
"\n",
"print(x3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Default argument and keyword arguments"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In a definition of a function, we can give default values to the arguments the function takes:"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [],
"source": [
"def myfunc(x, p=2, debug=False):\n",
" if debug:\n",
" print(\"evaluating myfunc for x = \" + str(x) + \" using exponent p = \" + str(p))\n",
" return x**p"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we don't provide a value of the `debug` argument when calling the the function `myfunc` it defaults to the value provided in the function definition:"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"25"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"myfunc(5)"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"evaluating myfunc for x = 5 using exponent p = 2\n"
]
},
{
"data": {
"text/plain": [
"25"
]
},
"execution_count": 105,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"myfunc(5, debug=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we explicitly list the name of the arguments in the function calls, they do not need to come in the same order as in the function definition. This is called *keyword* arguments, and is often very useful in functions that takes a lot of optional arguments."
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"evaluating myfunc for x = 7 using exponent p = 3\n"
]
},
{
"data": {
"text/plain": [
"343"
]
},
"execution_count": 106,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"myfunc(p=3, debug=True, x=7)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Assertions"
]
},
{
"cell_type": "code",
"execution_count": 120,
"metadata": {
"scrolled": false
},
"outputs": [
{
"ename": "AssertionError",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-120-154e0042d7b1>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mnum2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m45\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mget_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnum2\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mgolden_result\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mAssertionError\u001b[0m: "
]
}
],
"source": [
"def get_sum(x,y):\n",
" return x + y - 1\n",
"\n",
"golden_result = 90\n",
"\n",
"num1 = 45\n",
"num2 = 45\n",
"\n",
"assert get_sum(num1, num2) == golden_result"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr></hr>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p style=\"font-size:12\"> Modified from <i>jrjohansson</i> </p>"
]
}
],
"metadata": {
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment