"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Introduction \n",
"**Camilo Garcia Trillos - 2020**"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"## In this notebook\n",
"\n",
"In this notebook we will deal mainly with syntax and semantics in Python\n",
"- we explore some basic *expressions* in Python\n",
"- we introduce some *types*\n",
"- we introduce some of the most important *control flow* statements\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"\n",
"## Jupyter Notebooks\n",
"\n",
"This is a Jupyter notebook. It is an interface allowing us to combine code (in this case Python) and formatted text in a unified way.\n",
"\n",
"The basic unit in a notebook is a *cell*. You are right now reading the content of a \"Markdown\" cell, designed to input formatted text. There are also 'Code' cells, designed to input executable code. \n",
"\n",
"- You can **add** a new cell by clicking on the + button on the lower toolbar. Alternatively, press A (for inserting a cell above or B for inserting a cell below).\n",
"- Click on the cell to start **editing** it. Alternatively, you can move between cells with your arrows (note the blue highlighter on the right), and click **Enter** to edit one cell.\n",
"- To change the type of cell (from 'code' to 'markdown', use the choice tab on toolbar while on the cell.\n",
"- To run the code on a cell (or to format the text you input) you can either click on the 'play' button on the lower toolbar, or hit Ctrl+Enter\n",
"- You can also cut, paste and move cells. Hover your mouse over the buttons on the lower toolbar to know more. \n",
"\n",
"To familiarise yourself with the interface:\n",
"- On the upper toolbar, click on *Help> User Interface tour*, and follow the instructions to get an overview of this interface.\n",
"- For more information on the Python notebook in general, click on *Help> Notebook help*\n",
"- To know more about the keyboard shortcuts, go to *Help> Keyboard shortcuts*\n",
"\n",
"\n",
"**Short Exercise:** Add a cell, write '1+1' and execute this program. Then, select the cell again and change its type to Markdown You can finally delete this cell."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"---\n",
"\n",
"\n",
"## Basic expressions\n",
"\n",
"Having briefly reviewed the interface, let us start our review of Python. We will introduce different commands and explain their use: please run the commands as we learned above, and understand their function. \n",
"\n",
"We start by saying hi...."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"hello world!!!\n"
]
}
],
"source": [
"print (\"hello world!!!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"The above line has a statement that asks Python to execute the method/function *print* receives a 'string' and then shows the string as an output. Strings in Python can be denoted by either double or single quotations. To verify this, let us ask Python to *compare* if a string with single quotations is the same as a string with double quotations.\n",
"\n",
"The comparison operator is *==*\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 2,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"\"hello world!!!\"=='hello world!!!'"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The output of this comparison is *True*, which means that the two values are the same. Let me remark that in general Python compares 'values' and not 'references'. This is an important distinction from other programming languages."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The operator *=*, with a single equal, is used to make an assignment:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"hello again!!!\n"
]
}
],
"source": [
"message = 'hello again!!!' # This is an assignment\n",
"print(message)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Above we are creating an object that is initialised to contain a *string*. There is no need to declare the type of the object *message*. It will be then treated as a string, which is why the function *print* works. \n",
"\n",
"Note in passing that we can make comments on a code cell by preceding the comment by *#*\n",
"\n",
"Python is an object-oriented programming language. Objects of a given type or class have associated a certain number of methods that act on them. Take for example the following code"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"HELLO AGAIN!!!\n"
]
}
],
"source": [
"print(message.upper())"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The method *upper* is available for string objects and turns every character in their uppercase version. Here is another one "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"'now to lowercase'"
]
},
"execution_count": 5,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"'NOW TO LOWERCASE'.lower()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Note that we did not need to use *print* above. By default the result of the last command of a cell that returns a value is displayed. Let us finally remark that we can use the triple quotes to write text in several lines."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"now\n",
"with\n",
"several\n",
"lines\n"
]
},
{
"data": {
"text/plain": [
"'now\\nwith\\nseveral\\nlines'"
]
},
"execution_count": 6,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"print(\"\"\"NOW\n",
"WITH\n",
"SEVERAL\n",
"LINES\"\"\".lower())\n",
"\"\"\"NOW\n",
"WITH\n",
"SEVERAL\n",
"LINES\"\"\".lower()"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Compare the versions with and without print."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"\n",
"## Main numeric data types\n",
"\n",
"Having introduced the string data type, let us look now at the main numerical types: *Integer, complex, float, bool*\n",
"\n",
"Let us introduce them while we do some numerical calculations: adding, substracting, division, multiplication, modulo, power"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"0.30000000000000004"
]
},
"execution_count": 7,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"0.1+0.2"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The operation is performed using 'floats', that is numerical representation of real numbers. Digital computers have only a finite number of digits to represent a real, and so there are roundup errors. The above code shows that operations that for us are simple to do 'without roundup' must be done only approximately by a computer.\n",
"\n",
"We can also have operations with complex numbers. In Python, the imaginary number $\\sqrt{-1}$ is denoted by *j*"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(3+2j)\n",
"\n",
"\n"
]
}
],
"source": [
"a=1+1j\n",
"b=2\n",
"print(2*a+b-1)\n",
"print(type(a))\n",
"print(type(b))"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The above operation is executed in the complex numbers (or more appropriately the float version of the complex numbers). The precedence in executing the operations follows the usual convention: first, parentheiss are solved from inner to outer ones, then, for common mathematical operators de precedence is: power, then division and multiplication, then sum and substraction."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Also, note the function 'type': it returns the type of a given object. While we are at it, let us check the name of other types we have encountered before"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"print(type('Hello'), type(2), type(0.2), type(True))"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Division is a bit special. Observe the result of the following operations:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2.857142857142857\n",
"2\n"
]
}
],
"source": [
"print(20/7)\n",
"print(20//7)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Indeed, the double slash */* signals integer division. Note that we can use it also with float numbers "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2.857142857142857\n",
"2.0\n"
]
}
],
"source": [
"print(2.0/0.7)\n",
"print(2.0//0.7)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The *modulo* operator, that allow us to obtain the residual of a division, is also included:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"6"
]
},
"execution_count": 12,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"20 % 7"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Powers are defined using the operator double star '**'"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.5 1 2 4\n",
"0.5 1.0 2.0 4.0\n"
]
}
],
"source": [
"print(2**-1, 2**0, 2**1, 2**2)\n",
"print(2**-1, 2.**0, 2.**1, 2.**2)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"**Short exercise:** Remark the difference between the two instructions above. What can you say?"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"\n",
"\n",
"## Main structured types\n",
"\n",
"Python comes pre-loaded with some structured types to keep collections of objects. The main ones are: *List, tuple, dictionary, set*\n",
"\n",
"**It is very important to learn about the features of each one of these structured types, as many errors in programming come from misunderstanding them**"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"\n",
"\n",
"### Lists\n",
"\n",
"\n",
"*Lists* are created using the squared brackets []. They are a mutable collection of objects, i.e., after created we can modify the state of the object.\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5, 6]\n"
]
}
],
"source": [
"number_list = [1,2,3,4,5,6]\n",
"print(number_list)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Any element on a list can be accessed trough the square bracket operator. The indexation on the vector starts from zero"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The first element: 1 \n",
" the third element: 3 \n",
" the last element: 6\n"
]
}
],
"source": [
"print(\"The first element:\", number_list[0], \"\\n the third element:\", \n",
" number_list[2], \"\\n the last element:\", number_list[-1])"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"As shown above, we can provide negative numbers to the position. It simply access the position as counted from the end. Try with some other positions until you are sure how it works.\n",
"\n",
"It is also possible to get slices of a vector, by using *[m,n]*: this returns all elements in the vector starting from position *m* and ending in position *n-1*"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2, 3, 4]\n",
"[5]\n"
]
}
],
"source": [
"# The slicing operator works like a closed-open interval [ , )\n",
"\n",
"print(number_list[1:4])\n",
"print(number_list[4:5])\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"In the above, if no number is entered, the corresponding extreme is implicitly understood. Take a look at these examples:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4]\n",
"[5, 6]\n",
"[1, 2, 3, 4, 5, 6]\n"
]
}
],
"source": [
"print(number_list[:4])\n",
"print(number_list[4:])\n",
"print(number_list[:])"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Slices can also be used to run over the elements of a list in inverse order, or following a sequence"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Odd numbers: [1, 3, 5]\n",
"Multiples of 3: [3, 6]\n",
"Even numbers between 2 and 5: [2, 4]\n",
"Inverse order: [6, 5, 4, 3, 2, 1]\n"
]
}
],
"source": [
"print('Odd numbers:',number_list[::2])\n",
"print('Multiples of 3:',number_list[2::3])\n",
"print('Even numbers between 2 and 5:',number_list[1:5:2])\n",
"print('Inverse order:',number_list[::-1])"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Lists can also be extended."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
]
}
],
"source": [
"number_list.extend([7,8,9])\n",
"print(number_list)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"List assignments are passed by **reference**. This means that when we assign them to another variable, we only copy an adress to access them in memory. Here is an example"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
"[1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
]
}
],
"source": [
"another_list=number_list\n",
"print(number_list)\n",
"print(another_list)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
],
"source": [
"another_list[0]=-1 # This asigns -1 to the first position"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false,
"scrolled": true,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
"[-1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
]
}
],
"source": [
"print(number_list)\n",
"print(another_list)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Hence, despite the name, *another_list* points to the **same** list. However, lists are compared by **value**, as seen in this example:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Checks if both lists are equal (they are not): False\n",
"Checks if both lists are equal (they are): True\n"
]
}
],
"source": [
"list1=[1,2,3]\n",
"list2=[-1,2,3]\n",
"print('Checks if both lists are equal (they are not):',list1==list2)\n",
"list2[0]=1\n",
"print('Checks if both lists are equal (they are):',list1==list2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Lists can be concatenated with the operator *+*"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[1, 2, 3, 1, 2, 3]"
]
},
"execution_count": 24,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"list1+list2"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Note in particular that this does not add up elements in a list. In particular, we cannot concatenate an integer to a list."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [
{
"ename": "TypeError",
"evalue": "can only concatenate list (not \"int\") to list",
"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[0mlist1\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m \u001b[0;31m# This command generates an error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: can only concatenate list (not \"int\") to list"
]
}
],
"source": [
"list1+1 # This command generates an error"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"But we can do as follows"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"[1, 2, 3, 1]"
]
},
"execution_count": 26,
"metadata": {
},
"output_type": "execute_result"
}
],
"source": [
"list1 + [1]"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Also, note that concatenation does not modify the original list but creates a new one: i.e., the original list does not change."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3]\n"
]
}
],
"source": [
"print(list1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"The * operator repeats a list formation"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3, 1, 2, 3, 1, 2, 3]\n",
"[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]\n"
]
}
],
"source": [
"list3 = 3*[1,2,3]\n",
"print(list3)\n",
"print(2*list3)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"We can also have lists of lists (but they are not matrices!) and lists with different types and lengths"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n",
"5\n"
]
}
],
"source": [
"multilist = [[1,2,3],[4,5,6],[7,8,9]]\n",
"print(multilist)\n",
"print(multilist[1][1])"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1, 2, 3], 1, 'a', (1+2j)]\n",
"1\n"
]
}
],
"source": [
"mixed_list = [[1,2,3],1,'a',1+2j]\n",
"print(mixed_list)\n",
"print(mixed_list[1])"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"We end up our overview of *lists* by looking at some of the *methods* associated with it. The best method to discover them is to write a list and put a dot and the end and click TAB (might not work depending on your browser and OS)\n",
"\n",
"Some of the more relevant are shown below"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The list: [4, 3, 2, 1, 4]\n",
"Ordered list: [1, 2, 3, 4, 4]\n",
"Size: 5\n",
"List with additional 4: [1, 2, 3, 4, 4, 4]\n",
"Element and list after pop: 4 [1, 2, 3, 4, 4]\n"
]
}
],
"source": [
"list_a = [4,3,2,1,4]\n",
"print(\"The list:\",list_a)\n",
"list_a.sort() # This sorts the elements of the list\n",
"print(\"Ordered list:\",list_a)\n",
"\n",
"print(\"Size:\", len(list_a)) # Getting the size, i.e. number of elements of the list\n",
"list_a.append(4) # Adding a new element at the end of the list\n",
"print(\"List with additional 4:\",list_a) \n",
"elem = list_a.pop() # Take out the last element of the list\n",
"print(\"Element and list after pop:\",elem, list_a)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"\n",
"\n",
"### Strings\n",
"\n",
"We have enconuntered **strings** before. They can be manipulated in a way closed to lists.\n"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello again!\n",
"ello\n",
"!niaga olleH\n",
"12\n"
]
}
],
"source": [
"message = 'Hello again!'\n",
"print(message)\n",
"print(message[1:5])\n",
"print(message[-1::-1])\n",
"print(len(message))"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Some methods are different and specific of strings"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello again!\n",
"HELLO AGAIN!\n",
"Hello Again!\n",
"['Hello', 'again!']\n",
"Hello again?\n",
"6\n",
"-1\n"
]
}
],
"source": [
"print(message)\n",
"print(message.upper()) #Turn to pper case \n",
"print(message.title()) #Capitalise initial words\n",
"print(message.split(' ')) #Suubstrings separated by a space \n",
"print(message.replace('!','?')) #Replace ! with ?\n",
"print(message.find('aga')) # returns the first position where the sub-stringg\n",
"print(message.find('opo')) # returns -1 if no position is found"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"\n",
"\n",
"### Sets, tuples and dictionaries\n",
"\n",
"Finally, let us look at some of the other structures available on Python."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"A *set* is a structure where elements are unique. They are created with curly braces *{ }*\n",
"\n",
"We can add elements, remove elements, and perform mathematical operations like union, intersection, symmetric difference."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{1, 2, 3}\n",
"{1, 2, 3, 'aa'}\n"
]
}
],
"source": [
"set1 = {1,2,3,3}\n",
"print(set1)\n",
"set1.add('aa')\n",
"print(set1)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"set2: {8, 1, 2, 10}\n",
"set1 union set2 {1, 2, 3, 8, 10, 'aa'}\n",
"set1 intersection set2 {1, 2}\n",
"set1 minus set2 {3, 'aa'}\n",
"set2 minus set1 {8, 10}\n"
]
}
],
"source": [
"set2 = set([1,2,8,10]) # You can turn lists into sets\n",
"print(\"set2:\",set2)\n",
"print(\"set1 union set2\", set1|set2)\n",
"print(\"set1 intersection set2\", set1&set2)\n",
"print(\"set1 minus set2\", set1-set2)\n",
"print(\"set2 minus set1\", set2-set1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Note that sets do not have indices, so the following code does not make sense"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"outputs": [
{
"ename": "TypeError",
"evalue": "'set' object is not subscriptable",
"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[0mset1\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# this generates an error\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: 'set' object is not subscriptable"
]
}
],
"source": [
"set1[1] # this generates an error"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"A *tuple* can be created using round braces.\n",
"\n",
"Tuples are similar to a list *except that* elements cannot be changed once created: they are an example of an immutable structure"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1, 2, 3)\n",
"2\n"
]
}
],
"source": [
"tuple1 = (1,2,3)\n",
"print(tuple1)\n",
"print(tuple1[1])"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"collapsed": false
},
"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[0mtuple1\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m3\u001b[0m \u001b[0;31m#this generates an error ... tuples are immutable\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": [
"tuple1[1]=3 #this generates an error ... tuples are immutable"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Finally, a dictionary is a structure to connect keys and outputs. It is defined also using the curly braces *{ }*, but instead of simply listing the elements, we list couples of the form *key:value*. Keys can be any other immutable object (like numbers and basic strings).\n",
"\n",
"The key element is a generalisation of an index. Here are some examples:"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{50: 2, 'key2': 'aa', 'a': 1}\n"
]
}
],
"source": [
"mydict = {50:2,'key2':'aa', 'a':1}\n",
"print(mydict)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"aa\n",
"2\n",
"3\n"
]
}
],
"source": [
"print(mydict['key2'])\n",
"print(mydict[50])\n",
"print(mydict[50]+mydict['a'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"Here are some examples of methods for dictionaries"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{50: 10, 'key2': 'aa', 'a': 1}\n",
"{'key2': 'aa', 'a': 1}\n",
"{'key2': 'aa', 'a': 1, 2: 'c'}\n"
]
}
],
"source": [
"mydict[50]=10 #Changing the entry with key 50 to 10\n",
"print(mydict)\n",
"mydict.pop(50) # Taking out the entry with key 50\n",
"print(mydict)\n",
"mydict.update({2:'c'}) # Adding an entry with key the number 1 and value 'c'\n",
"print(mydict)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"\n",
"\n",
"## Basic control flow statements\n",
"\n",
"\n",
"To close this notebook, we will look at the essential control flow statements (i.e. commands to determine the flow of a program) in Python. The main ones are:\n",
"\n",
"- Conditionals: *if (condition): --- elif(condition): --- else:---*\n",
"- Conditional loops: *while (condition): --- else:---*\n",
"- Automatic loops: *for (iterative): --- \n",
"\n",
"The structure is determined by **indentation**\n",
"\n",
"Let us look at some examples: you are encouraged to change the inputs and modify the code until you undertstand how the flow of commands works.\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I am running the second case\n",
"5 is larger than 4\n"
]
}
],
"source": [
"#Determine the bigger between two numbers\n",
"\n",
"a=4\n",
"b=5\n",
"\n",
"if a > b:\n",
" print('I am running the first case')\n",
" print(str(a) +' is larger than ' + str(b))\n",
"elif b >a:\n",
" print('I am running the second case')\n",
" print(str(b) +' is larger than '+ str(a))\n",
"else:\n",
" print('I am running any other case')\n",
" print('Both are equal to '+str(a))\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"In the above code, the code indented after if is run only when the condition is satisfied. The code indented after elif is run only if a>b. The code indented after elif is run only if a>b is not satsified (i.e. a<=b) **and** b>a. Finally the code after else is run only if neither of the conditions is satsified (i.e. when a==b) "
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 is odd\n",
"5 is odd\n",
"6 is even\n",
"3 is odd\n",
"2 is even\n"
]
}
],
"source": [
"# Print if the numbers of a list are even or odd\n",
"\n",
"m_list =[1,5,6,3,2]\n",
"\n",
"for i in m_list:\n",
" if i%2 == 0:\n",
" print(str(i) + ' is even' )\n",
" else:\n",
" print(str(i) + ' is odd' )"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"We can modify the above example to act on the first n natural numbers. To do this, we introduce the command *range*"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 is even\n",
"1 is odd\n",
"2 is even\n",
"3 is odd\n",
"4 is even\n"
]
}
],
"source": [
"# Print if the numbers of a list are even or odd\n",
"\n",
"n=5\n",
"\n",
"for i in range(n):\n",
" if i%2 == 0:\n",
" print(str(i) + ' is even' )\n",
" else:\n",
" print(str(i) + ' is odd' )"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"In general, range can generate a pattern from a given start, to a given end with certain step: *range(start,end,step)*. If step is not given, step=1. \n",
"\n",
"Here is a version of the same code using *while* and avoiding *range*."
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 is even\n",
"1 is odd\n",
"2 is even\n",
"3 is odd\n",
"4 is even\n"
]
}
],
"source": [
"i = 0\n",
"n = 5\n",
"while i\n",
"## Exercises\n",
"\n",
"1. Write your own code to sort a list of numbers. Compare with the method sort() we introduced before (for example on the list [5,5,1,2,1,5,10])"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4\n"
]
}
],
"source": [
"# Here is a simple example (known as bubble sort). Note that this sorts the list inline (ie. it sorts the list itself):\n",
"\n",
"mlist = [5,5,1,2,1,5,10]\n",
"\n",
"for j in range(len(mlist)):\n",
" for k in range(j+1, len(mlist)):\n",
" if mlist[j]>mlist[k]:\n",
" mlist[j], mlist[k] = mlist[k], mlist[j]\n",
"\n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"2. Write a code that, for a given tuple $(a,b,c)$, returns the roots (possibly complex) of the equation\n",
"$$ a x^2 + b x + c = 0 $$\n",
"\n",
"*Note*: if there is a double root, only one number must be returned."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The solution for tuple (1, 2, 1) is -1.0\n"
]
}
],
"source": [
"\n",
"#mtuple = (1,0,-1)\n",
"#mtuple = (1,0,1)\n",
"#mtuple = (0,1,1)\n",
"#mtuple = (0,0,1)\n",
"mtuple = (1,2,1)\n",
"\n",
"if mtuple[0]==0:\n",
" if mtuple[1]!= 0:\n",
" sol = -mtuple[2]/mtuple[1] \n",
" else:\n",
" sol = None\n",
"elif mtuple[1]**2==4*mtuple[0]*mtuple[2]:\n",
" sol = - mtuple[1]/(2*mtuple[0])\n",
"else:\n",
" sol = ( (- mtuple[1] - (mtuple[1]**2-4*mtuple[0]*mtuple[2])**0.5)/(2*mtuple[0]), \n",
" (- mtuple[1] + (mtuple[1]**2-4*mtuple[0]*mtuple[2])**0.5)/(2*mtuple[0]))\n",
"\n",
"print('The solution for tuple ', mtuple, ' is ', sol)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"3. Starting from two integers, $a,b$, and an initial value integer $0