{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Python for Scientific Computing - Tutorial n°1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***Mohammed Ait Lahcen, Economic Theory Group, Faculty of Business and Economics, University of Basel***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This series of tutorials offers an introduction to Python for scientific computing. In this first tutorial we take a look at some of the basics of the core language.\n", "\n", "For a more detailed introduction to Python for scientific computing you are encouraged to refer to the lectures available at [QuantEcon.org](https://lectures.quantecon.org/py/learning_python.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Common data types in Python include:\n", "* String\n", "* Integer\n", "* Float\n", "* Boolean\n", "* ...\n", "\n", "The ones we will usually encounter in scientific programming are numbers (integers, floats,...).\n", "\n", "Python also offers data types for storing collections of objects. These are called container types and include:\n", "* Lists\n", "* Tuples\n", "* Dictionaries\n", "* ...\n", "\n", "We will have a look at container types a bit later.\n", "\n", "Non-native Python data types can be added by importing additionnal packages (e.g. array, dataframe, series, etc)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variable assignment" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can create a variable just by assigning a value to it. The assignment operator in Python is `=`" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "x = 1" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As opposed to languages such as C, Java and Fortran, Python is a dynamically typed language. This means that we do not need to specify the type of a variable when we create one. Python takes care of that by infering the type of the variable from the value that was assigned to it. This is very convenient in use but might slow down the code's performance during execution relative to static languages." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you try to use a variable that has not yet been defined you will get a `NameError`:" ] }, { "cell_type": "code", "execution_count": 4, "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\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\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": [ "type(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Strings are the variable type that is used for storing text." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = \"Hello world\"\n", "type(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the number of characters in a string variable you can use the function `len()`:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To replace a substring in a string with another substring;" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Basel\n" ] } ], "source": [ "s2 = s.replace(\"world\", \"Basel\")\n", "print(s2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numbers and Basic Math Operators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The two most common data types used to represent numbers are integers and floats. Integers are whole numbers without a fractional part (e.g. 2, 4, -20) and have type `int`. Numbers with a fractional part (e.g. 5.0, 1.6) have type `float`. " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n = -1\n", "type(n)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = -1.0\n", "type(m)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Basic math operators include +, -, * and / :" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 + 7" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-2" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 - 7" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "35" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 * 7" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.7142857142857143" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 / 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The order of operators is standard and parentheses `()` can be used for grouping:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5.0" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(50 - 5 * 6) / 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The division operator `/` returns a float. To do a division and get an integer result you can use the `//` operator which rounds down the result to the nearest integer. To calculate the remainder you can use `%`:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "7 // 5" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "7 % 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `**` operator is used to calculate powers:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "78125" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 ** 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As seen above, the equal sign `=` is used to assign a value to a variable:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "a = 5\n", "b = 7\n", "c = a / b" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.7142857142857143" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Booleans and Logical Operators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A data object of type Boolean can take the values `True` or `False`:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bool" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = True\n", "type(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When used in arithmetic operations, `True` is converted to 1 and `False` is converted 0." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = False\n", "a + b" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a * b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The logical operators are `and`, `not`, `or`:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True and True" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "not True" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "True or False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The standard comparison operators are >, <, >= (greater or equal), <= (less or equal), == equality. These operators return a value of type Boolean (`True` or `False`):" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a, b = 1, 2\n", "\n", "a < b" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a > b" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = 0\n", "\n", "c < a < b" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = 3\n", "\n", "d == 1" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d != a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above can be combined using the boolean operators:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a >= 0 and a != 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Container types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first container type we look at is `list`. Lists are native Python data structures used to group a collection of objects." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[1, 15, 'foo', True]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = [a, 15, 'foo', True]\n", "l" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "list" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(l)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To add elements to a list, use the list method `append`:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 15, 'foo', True, 'bar']" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l.append('bar')\n", "l" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To remove an element you can use the list method `remove` applied to the element value:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 15, 'foo', True]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l.remove('bar')\n", "l" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or the function `del()` combined with the element's position in the list:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[15, 'foo', True]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del(l[0])\n", "l" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Indexing in Python is zero based (starts from 0), similar to C, C++, Java, etc." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "15" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l[0]" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists are mutable:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[15, 'foo', 'foobar']" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l[2] = 'foobar'\n", "l" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tuples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples are similar to lists except they are immutable. Notice the use of round (or no) brackets for tuples as opposed to square brackets for lists:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 15, 'foo', True)" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = (a, 15, 'foo', True)\n", "t" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 15, 'foo', True)" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = a, 15, 'foo', True\n", "t" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tuple" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(t)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'foo'" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t[2]" ] }, { "cell_type": "code", "execution_count": 45, "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\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mt\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'foobar'\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": [ "t[0] = 'foobar'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tuples and lists can be unpacked as follows:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "15\n", "foo\n", "True\n" ] } ], "source": [ "a, b, c, d = t\n", "print(a)\n", "print(b)\n", "print(c)\n", "print(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dictionaries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries are similar to lists and tuples except that items are indexed by names:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'alpha': 0.8, 'beta': 0.96, 'tau': 0.3}" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {'beta':0.96,'alpha':0.8,'tau':0.30}\n", "d" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(d)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.96" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['beta']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding an entry to a dictionary is very intuitive:" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'alpha': 0.8, 'beta': 0.96, 'tau': 0.3, 'theta': 0.5}" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['theta'] = 0.5\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries are mutable:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'alpha': 0.8, 'beta': 0.99, 'tau': 0.3, 'theta': 0.5}" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['beta'] = 0.99\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In scientific computing, you can use lists to store results and dictionatries to store sets of parameters. Tuples are less used but still important to know since they are returned as output by many numerical functions as we will see later on." ] } ], "metadata": { "anaconda-cloud": {}, "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.4" } }, "nbformat": 4, "nbformat_minor": 4 }