{ "metadata": { "name": "", "signature": "sha256:0a6cfc11318d603a61b465e861ca2bb3699d3c4635a75e76644dcbda4ea5bacb" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "code", "collapsed": false, "input": [ "%pylab inline" ], "language": "python", "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Populating the interactive namespace from numpy and matplotlib\n" ] } ], "prompt_number": 2 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Brief Python Language Tutorial" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "P.D. Nation and J.R. Johansson\n", "\n", "For more information about QuTiP see [http://qutip.org](http://qutip.org)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Using Python For Simple Calculations" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "As a first step, lets try to use the interactive Python command line tool **iPython** as a basic calculator. Addition, subtraction, and multiplication, all work in the same way as you would write the equations down on paper" ] }, { "cell_type": "code", "collapsed": false, "input": [ "10+5" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 3, "text": [ "15" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "10-157" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 4, "text": [ "-147" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "4/3" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ "1.3333333333333333" ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "(50-4)*10/5" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "92.0" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "However, things like raising a number to a power, $4^{4}$, are written differently." ] }, { "cell_type": "code", "collapsed": false, "input": [ "4**4" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ "256" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We could also express this in the mathematically equivalent way as $4^{4.0}$. However, inside of the computer, the result is not treated the same as the above answer." ] }, { "cell_type": "code", "collapsed": false, "input": [ "4**4.0" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "256.0" ] } ], "prompt_number": 8 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Integers vs. Floating Point Numbers" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "All information stored in a computer must be represented in a binary format consisting of zeros and ones (e.g. $461\\rightarrow 111001101$). Each zero or one is called a **bit**, and given $N$ bits, one can store all of the integers in the range $[0,2^{N-1}]$, where the $-1$ is due to the fact that the first bit is reserved for defining if a number is positive or negative \n", "\n", "However, given a fixed number of bits, it is impossible to store an arbitrary number exactly. Therefore, if one is given a random number, unless the number is exactly divisible by a factor of two, the conversion between the random number and the binary bit representation ultimately leads to a loss of precision, and what is known as **roundoff error**.\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "When dealing with numbers inside a computer there are two distinct types of numbers to consider:\n", "\n", "\n", "- **Integers** - (1,2,4,-586,..) Are what are called **fixed-point numbers**, where the term fixed-point means that there is a fixed number of decimal places in the number (zero for integers). These numbers can be stored exactly in a computer.\n", "\n", "\n", "- **Doubles/Floats** - (3.141,0.21,-0.1,..) These are **floating-point numbers** that are the binary equivalent to scientific notation $c=2.99792458\\times 10^{8}$. Doubles (also called double-precision numbers) are floating point numbers that are written using 64-bits and, in general, are only accurate to the 15th or 16th decimal place. Floats (or single-precision numbers) use 32-bits, and are good to 6-7 decimal places. **Serious scientific calculations always require a combination of integers and double (64-bit) numbers**." ] }, { "cell_type": "code", "collapsed": false, "input": [ "7+0.000000000000001" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "7.000000000000001" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "7+0.0000000000000001" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 10, "text": [ "7.0" ] } ], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "0.1+0.2" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "0.30000000000000004" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "This last example clearly highlights the fact that the computer does not store decimal (floating-point) numbers exactly. The loss of precision in floating-point numbers can be characterized by the **machine precision**, $\\epsilon_{\\rm m}$, that is defined to be the smallest positive number such that \n", "\n", "$$1_{\\rm c}+\\epsilon_{\\rm m}\\neq 1_{\\rm c}$$\n", "\n", "where the subscript on $1_{\\rm c}$ is meant to remind you that this is a computer number. Therefore, for any arbitrary number $N$ is related to its floating-point equivalent $N_{\\rm c}$ by\n", "\n", "$$N_{\\rm c}=N\\pm \\epsilon, \\ \\ \\forall~|\\epsilon|< \\epsilon_{\\rm m}.$$\n", "\n", "**Take Home Message** - All double-precision decimal numbers that are not factors of two will have error in the 15th decimal place. This can lead to errors in your numerical solutions if you are not careful." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Making Python Smarter Using NumPy" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Python itself as limited support for mathematics outside of simple arithmetic. Therefore, we will use the functions in the NumPy module to do more impressive, and faster, calculations. To load many, but not all, of the functions in NumPy we run the following command" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from numpy import *" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Here we are asking Python to get all of the basic functions (this is what * means) from the NumPy module. We can now do more impressive calculations:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "exp(2.34)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "10.381236562731843" ] } ], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "sqrt(5)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 14, "text": [ "2.2360679774997898" ] } ], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "sinc(0.5)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 15, "text": [ "0.63661977236758138" ] } ], "prompt_number": 15 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Variables" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "If we want to be able to store the numbers and results from our calculations then we must define variables using the \"=\" sign:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "radius=5\n", "area=pi*radius**2\n", "area" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 16, "text": [ "78.53981633974483" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We see that our variables name is defined on the left of the = sign and the value its given is defined on the right. Here we have also used the pi variable that has been predefined by NumPy. Variables can then be used in other expressions. \n", "\n", "If a predefined variable is again used on the left side of = then its original value is replaced." ] }, { "cell_type": "code", "collapsed": false, "input": [ "x=10\n", "x=(x**2+25)/10\n", "x" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 17, "text": [ "12.5" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "This is different than the mathematical equation $10x=x^{2}+25$ which has the solution $x=5$. Therefore, it is important to remember that the = sign in a computer program is **not** equivalent to the mathematical equality. " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "What happens if you try to use a variable without first defining it? Lets try it:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "weight" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "ename": "NameError", "evalue": "name 'weight' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\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[0mweight\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'weight' is not defined" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Python gives us an error that \"weight\" is not defined. In addition, there are several words that are reserved by the Python language and cannot be used as variables:\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", "Other than the above reserved words, your variables can be anything that starts with a letter or the underscore character \"$\\_$\" preceded by any combination of alphanumeric characters and \"$\\_$\". Note that using upper or lower case letters will give you two different variables." ] }, { "cell_type": "code", "collapsed": false, "input": [ "_freq = 8\n", "Oscillator_Energy = 10\n", "_freq*Oscillator_Energy" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 23, "text": [ "80" ] } ], "prompt_number": 23 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Some Rules About Variables" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Although there are many ways to define variables in Python, it is best to try to define your variables in all the same way. In this class, all of our variables will use only lower case characters. \n" ] }, { "cell_type": "code", "collapsed": false, "input": [ "speed_of_light = 2.9979*10**8\n", "spring_constant = sqrt(2/5)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "prompt_number": 24 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "It is also good practice to use variable names that correspond to the physical quantity that the variable represents." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Strings" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Often times we want to print some text along with our variables, ask the user for input, or actually use the words and letters themselves as variables (e.g. in DNA analysis). All of these can be accomplished using **strings**. We have already seen one string already in this class: " ] }, { "cell_type": "code", "collapsed": false, "input": [ "'Hello Class'" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 22, "text": [ "'Hello Class'" ] } ], "prompt_number": 22 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We can also use double quotes" ] }, { "cell_type": "code", "collapsed": false, "input": [ "\"Hello Class\"" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 21, "text": [ "'Hello Class'" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "If we want to use the quote symbol in the string itself then we need to mix the two types " ] }, { "cell_type": "code", "collapsed": false, "input": [ "\"How was Hwajung's birthday party?\"" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 20, "text": [ "\"How was Hwajung's birthday party?\"" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Just like we did with integers and doubles, we can assign a string to a variable, and we can even add two strings together." ] }, { "cell_type": "code", "collapsed": false, "input": [ "a = \"I like \" # There is a blank space at the end of this string.\n", "b = \"chicken and HOF\"\n", "a+b" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "'I like chicken and HOF'" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Notice the blank space at the end of the string in variable \"a\" provides spacing between \"like\" and \"chicken\"." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "If we want to print out stuff, including strings and integers or doubles together, then we can use the builtin print function to accomplish this" ] }, { "cell_type": "code", "collapsed": false, "input": [ "temp=23\n", "text=\"The temperature right now is\"\n", "print(text,temp)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "The temperature right now is 23\n" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Notice how the print function automatically puts a space between the the two input arguments. The print function automatically takes any number of string, integer, double, or other variables, converts them into strings, and then prints them for the user." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Lists" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Often times we will want to group many variables together into one object. In Python this is accomplished by using a **list** datatype variable." ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list=['eggs', 'bread', 'milk', 'bananas']" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "prompt_number": 26 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "If we want to access a single variable inside of the list, then we need to use the **index** that corresponds to the variable inside of square brackets." ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[2]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 27, "text": [ "'milk'" ] } ], "prompt_number": 27 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We see that the \"milk\" string can be accessed using the index number $2$. However, we can see that this variable is actually the third string in the list. This discrepancy is due to the fact that Python (like C-code) considers the first element in a list, or other multivariable data structures, to be at index $0$." ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[0]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 28, "text": [ "'eggs'" ] } ], "prompt_number": 28 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "This is important to remember, and will take some getting used to before it becomes natural. If we want to access the elements of the list from back to front, we can use negative indices" ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[-1]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 29, "text": [ "'bananas'" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[-2]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 30, "text": [ "'milk'" ] } ], "prompt_number": 30 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "If we are given a list variable and we want to known how many elements are inside of the list, then we can use the len function that returns an integer giving the length of the list." ] }, { "cell_type": "code", "collapsed": false, "input": [ "len(shopping_list)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 31, "text": [ "4" ] } ], "prompt_number": 31 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "If we want to change the length of the list by adding or removing elements, then we can use append and remove, respectively." ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list.append('apples')\n", "shopping_list" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 32, "text": [ "['eggs', 'bread', 'milk', 'bananas', 'apples']" ] } ], "prompt_number": 32 }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list.remove('bread')\n", "shopping_list" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 33, "text": [ "['eggs', 'milk', 'bananas', 'apples']" ] } ], "prompt_number": 33 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Note that lists to not have to have the same type of data in each element! You can mix any data types you want." ] }, { "cell_type": "code", "collapsed": false, "input": [ "various_things=[1, \"hello\", -1.234, [-1, -2, -3]]\n", "various_things" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 34, "text": [ "[1, 'hello', -1.234, [-1, -2, -3]]" ] } ], "prompt_number": 34 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "All of these elements can be accessed in the usual way" ] }, { "cell_type": "code", "collapsed": false, "input": [ "various_things[0]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 35, "text": [ "1" ] } ], "prompt_number": 35 }, { "cell_type": "code", "collapsed": false, "input": [ "various_things[-1]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 36, "text": [ "[-1, -2, -3]" ] } ], "prompt_number": 36 }, { "cell_type": "code", "collapsed": false, "input": [ "various_things[3][1]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 37, "text": [ "-2" ] } ], "prompt_number": 37 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Iterating Through Lists and Python Indention Rules" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "One of the most important reasons for using lists is because one often wants to do the same type of manipulation on each of the elements one at a time. Going through a list in this fashion is called **iteration** and is accomplished in Python using the for command: " ] }, { "cell_type": "code", "collapsed": false, "input": [ "items=['four calling birds', 'three french hens', \n", " 'two turtle doves', 'a partridge in a pear tree']\n", "for thing in items:\n", " print(thing)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "four calling birds\n", "three french hens\n", "two turtle doves\n", "a partridge in a pear tree\n" ] } ], "prompt_number": 38 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Here, \"thing\" is a variable that takes the value of each item in the list \"items\" and then gets sent to the print function. We are free to call this variable anything we want. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "for variable in items:\n", " print(variable)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "four calling birds\n", "three french hens\n", "two turtle doves\n", "a partridge in a pear tree\n" ] } ], "prompt_number": 39 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "The next important thing to notice is that after the colon \":\" the print statement is indented. This indention after a colon is required in the Python programming langage and represents a section of the code called a **block**. If we did not intent the print function then Python would yell at us. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "for variable in items:\n", "print(variable)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "ename": "IndentationError", "evalue": "expected an indented block (, line 2)", "output_type": "pyerr", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m print(variable)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n" ] } ], "prompt_number": 40 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Blocks are a standard part of any programming language and are used for organization and flow-control in computer code. Anything that is indented in the above example will be run for each item in the list" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for variable in items:\n", " print(\"My true love gave to me\", variable)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "My true love gave to me four calling birds\n", "My true love gave to me three french hens\n", "My true love gave to me two turtle doves\n", "My true love gave to me a partridge in a pear tree\n" ] } ], "prompt_number": 41 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Slicing Lists" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "If we want to grab certain elements from a list we can make use of **slicing** to conveniently access the elements. Slicing can be used on any **sequence** such as lists, strings, and as we will see shortly, arrays. Consider our shopping_list list:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list=['eggs', 'bread', 'milk', 'bananas', 'apples']" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [], "prompt_number": 42 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "To get the first element we used a single index" ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[0]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 43, "text": [ "'eggs'" ] } ], "prompt_number": 43 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "But if we want to get the first three elements in the list we can use: " ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[0:3]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 44, "text": [ "['eggs', 'bread', 'milk']" ] } ], "prompt_number": 44 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We could also grab the last two elements using:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[-2:]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 45, "text": [ "['bananas', 'apples']" ] } ], "prompt_number": 45 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Or, we can get even more complex and grab all of the even number elements by using a third argument in the brackets that tells use the step size:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "shopping_list[0::2]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 46, "text": [ "['eggs', 'milk', 'apples']" ] } ], "prompt_number": 46 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Conditional Statements" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We have now seen a collection of data types (integers, doubles/floats, lists, strings) but we have yet to discuss how to compare two different variables. For example, how do we check if two different integers $a$ and $b$ are equal? Or how do we know if $a\\ge b$? This is accomplished using **conditional statements**. The basic operations in boolean logic are \"equal\" (==), \"not equal\" (!=), \"greater than\" (>), \"greater than or equal\" (>=), \"less than\" (<), and \"less than or equal\" (<=). All of these conditionals operate on two variables and return a simple boolean True or False answer. For example" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a=5 ; b=8\n", "a>b" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 47, "text": [ "False" ] } ], "prompt_number": 47 }, { "cell_type": "code", "collapsed": false, "input": [ "c=0\n", "c<=0,c>=0" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 48, "text": [ "(True, True)" ] } ], "prompt_number": 48 }, { "cell_type": "code", "collapsed": false, "input": [ "a=5;b=6\n", "a==b,a!=b" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 49, "text": [ "(False, True)" ] } ], "prompt_number": 49 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "It is important to point out that in Python 1 and 0 are the same as True and False, respectively." ] }, { "cell_type": "code", "collapsed": false, "input": [ "True==1,False==0" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 50, "text": [ "(True, True)" ] } ], "prompt_number": 50 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We can also combine multiple conditional statements" ] }, { "cell_type": "code", "collapsed": false, "input": [ "a=-1;b=4;c=10;d=11\n", "a=[4,5,7]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 52, "text": [ "False" ] } ], "prompt_number": 52 }, { "cell_type": "code", "collapsed": false, "input": [ "[4,5,6]<=[4,5,7]" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 53, "text": [ "True" ] } ], "prompt_number": 53 }, { "cell_type": "code", "collapsed": false, "input": [ "'today'=='Today'" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 54, "text": [ "False" ] } ], "prompt_number": 54 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Conditional Statements and Flow Control" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "The main purpose of these conditional statements is to control the flow of a Python program. The result of a conditional statement can be used to control a program using if/else and while statements." ] }, { "cell_type": "code", "collapsed": false, "input": [ "today='friday'\n", "if today=='friday':\n", " print('We have class today :(') # this is a code block\n", "else:\n", " print('No class today :)') # this is also a code block" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "We have class today :(\n" ] } ], "prompt_number": 55 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "The code block below the if statement is run only if the conditional today=='friday' returns True. If the conditional is False then the code block inside the else statement is run. We can also check multiple conditions by using the elif statement after if:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "today='thursday'\n", "if today=='friday':\n", " print('We have class today :(')\n", "elif today=='thursday':\n", " print('Our assignment is due today :(')\n", "else:\n", " print('No class today :)')" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Our assignment is due today :(\n" ] } ], "prompt_number": 56 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "The other important flow control expression is the **while loop** that executes a block of code repeatedly until the conditional statement at the start of the loop is False." ] }, { "cell_type": "code", "collapsed": false, "input": [ "n=0\n", "while n<=10: #evaluate code block until n>10\n", " print('The current value of n is:',n)\n", " n=n+1 #increase the value of n by 1" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "The current value of n is: 0\n", "The current value of n is: 1\n", "The current value of n is: 2\n", "The current value of n is: 3\n", "The current value of n is: 4\n", "The current value of n is: 5\n", "The current value of n is: 6\n", "The current value of n is: 7\n", "The current value of n is: 8\n", "The current value of n is: 9\n", "The current value of n is: 10\n" ] } ], "prompt_number": 57 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "When using a while loop you must make sure the conditional is not True forever. Otherwise your program will be in an **infinite loop** that never ends." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Example: Even and Odd Numbers" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Let us determine whether a given number between [1,10] is an even or odd number." ] }, { "cell_type": "code", "collapsed": false, "input": [ "for n in [1,2,3,4,5,6,7,8,9,10]:\n", " if remainder(n,2)==0:\n", " print(n,'is even')\n", " else:\n", " print(n,'is odd')" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 is odd\n", "2 is even\n", "3 is odd\n", "4 is even\n", "5 is odd\n", "6 is even\n", "7 is odd\n", "8 is even\n", "9 is odd\n", "10 is even\n" ] } ], "prompt_number": 58 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Typing lists with a long sequence of integers is quite annoying. Fortunately, Python has a builtin function called range that makes creating sequences of integers very easy. For instance, the above example becomes" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for n in range(1,11):\n", " if remainder(n,2)==0:\n", " print(n,'is even')\n", " else:\n", " print(n,'is odd')" ], "language": "python", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 is odd\n", "2 is even\n", "3 is odd\n", "4 is even\n", "5 is odd\n", "6 is even\n", "7 is odd\n", "8 is even\n", "9 is odd\n", "10 is even\n" ] } ], "prompt_number": 59 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "Notice how the range function only counts to $10$ even though the range goes to $11$. The endpoint is *never* part of the generated sequence when using range. If we wanted the range function to start at zero instead of one we could simply write range(11). We can also make sequences that go in arbitrary steps:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for n in range(0,11,2):\n", " print(n)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "2\n", "4\n", "6\n", "8\n", "10\n" ] } ], "prompt_number": 60 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "The range function does not return a list of integers but is something called a **generator**. In general, the range function should only be used in combination with the for command." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Example: Fibonacci Sequence" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Let us follow the Python documentation and calculate the first ten numbers in the Fibonacci sequence:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "n = 10\n", "fib = [0,1]\n", "for i in range(2,n):\n", " fib.append(fib[i-1]+fib[i-2])\n", "print(fib)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\n" ] } ], "prompt_number": 61 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We can also write this using a while loop if we wanted to." ] }, { "cell_type": "code", "collapsed": false, "input": [ "n = 2\n", "fib = [0,1]\n", "while n<10:\n", " fib.append(fib[n-1]+fib[n-2])\n", " n = n+1\n", "print(fib)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\n" ] } ], "prompt_number": 62 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Writing Scripts and Functions" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Up until now we have been running little code snippets but have not really been doing any real programming. Recall that Python is a scripting language. Therefore, most of the time, we want to write **scripts** that contain a collection of constants, variables, data structures, functions, comments, etc., that perform various complicated tasks. " ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ " Scripts" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "A Python script file is nothing but a text file containing Python code that ends with a **.py** extension. Python scripts are also called Python **programs**. If we open up any editor, then we are given a blank window that we can enter our Python commands in." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Before we begin to write our scripts, lets first discuss the best format for writing your scripts." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# This is an example script for the P461 class\n", "# Here we will calculate the series expansion\n", "# for sin(x) up to an arbitrary order N.\n", "#\n", "# Paul Nation, 02/03/2014\n", "\n", "from numpy import *\n", "from scipy.misc import factorial\n", "\n", "N = 5 # The order of the series expansion\n", "x = pi/4. # The point at which we want to evaluate sine\n", "\n", "ans = 0.0\n", "for k in range(N+1):\n", " ans = ans+(-1)**k*x**(1+2*k)/factorial(1+2*k)\n", "print(\"Series approximation:\",ans)\n", "print(\"Error:\",sin(x)-ans)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Series approximation: 0.70710678118\n", "Error: 6.92801371827e-12\n" ] } ], "prompt_number": 63 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "We can see that the script has four main parts: First, we have a section of **comments** that describe what the script does and when it was created. In python all comments start with the **#** symbol. Everything after this symbol is ignored by the computer. Second, we have the section of the scripts that load the necessary functions that we need from other packages. Third is a section where we define all of the constants that are going to be used in the script. You should also add comments here that tell us what the constants are. Finally, your main body of code goes after these sections." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Functions" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We are finally in a position to look at one of the most important parts of any programming language **functions**. Functions are blocks of code that accomplish a specific task. Functions usually take \"input arguments\", perform operations on these inputs, and then \"return\" one or more results. Functions can be used over and over again, and can also be \"called\" from the inside of other functions. Let us rewrite our script for $sin(x)$ using a function and then describe each part." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from numpy import *\n", "from scipy.misc import factorial\n", "\n", "N=5 # The order of the series expansion\n", "x=pi/4. # The point at which we want to evaluate sine\n", "\n", "def sine_series(x,N):\n", " ans=0.0\n", " for k in range(N+1):\n", " ans=ans+(-1)**k*x**(1+2*k)/factorial(1+2*k)\n", " return ans\n", "\n", "result = sine_series(x,N)\n", "print(\"Series approximation:\",result)\n", "print(\"Error:\",sin(x)-result)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Series approximation: 0.70710678118\n", "Error: 6.92801371827e-12\n" ] } ], "prompt_number": 64 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "We see see that a function is created using the keyword def which is short \"define\", then the name of the function followed by the input arguments in parentheses. After the block of code called by the function, the return keyword specifies what variable(s) and/or data structure(s) are given as the output. So a general functions call is" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def function_name(arg1,arg2):\n", " \"Block of code to run\"\n", " \"...\"\n", " return result" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, everything after the colon (:) that is inside the function must be indented. The beauty of using functions is that we can use the same code over and over, just by changing the constants near the top of our Python script.\n", "\n", "Variables that are defined inside of a function are called **local variables** and only defined for the block of code inside of the function. In our previous example, k was a local variable. The input arguments and return arguments are *not* local variables. Once a function is done running, the local variables are erased from memory. Therefore, if you want get something out of a function, your must return the value when your done." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "If we want to return more than one thing at the end of the function then we just need to separate the different items by a comma." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from numpy.random import random\n", "from pylab import *\n", "\n", "N=100 # Number of points to generate\n", "\n", "def random_coordinates(N):\n", " x_coords=[]\n", " y_coords=[]\n", " for n in range(N):\n", " xnew,ynew=random(2)\n", " x_coords.append(xnew)\n", " y_coords.append(ynew)\n", " return x_coords,y_coords\n", "\n", "xc,yc=random_coordinates(N)\n", "plot(xc,yc,'ro',markersize=8)\n", "show()" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "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\n7UU+a/EgGwAAAABJRU5ErkJggg==\n", "text": [ "" ] } ], "prompt_number": 65 }, { "cell_type": "code", "collapsed": false, "input": [ "from numpy.random import random\n", "from pylab import *\n", "\n", "N = 20 # Number of points to generate\n", "\n", "def random_coordinates(N):\n", " x_coords = []\n", " y_coords = []\n", " for n in range(N):\n", " xnew,ynew = random(2)\n", " x_coords.append(xnew)\n", " y_coords.append(ynew)\n", " return x_coords,y_coords\n", "\n", "def dist2d(x1,y1,x2,y2):\n", " return sqrt((x1-x2)**2+(y1-y2)**2)\n", "\n", "def max_dist(xc,yc):\n", " max_dist = 0.0\n", " num_points = len(xc)\n", " for ii in range(num_points):\n", " for jj in range(num_points):\n", " dist = dist2d(xc[ii],yc[ii],xc[jj],yc[jj])\n", " if dist > max_dist:\n", " max_dist = dist\n", " xvals = [xc[ii],xc[jj]]\n", " yvals = [yc[ii],yc[jj]]\n", " return max_dist, xvals, yvals\n", "\n", "xc,yc = random_coordinates(N)\n", "max_dist,pnt1,pnt2 = max_dist(xc,yc)\n", "plot(xc,yc,'ro',markersize=8)\n", "plot(pnt1,pnt2,'b-',lw=2)\n", "show()" ], "language": "python", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 66 }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Obvious this last example is more complex, and in particular, it is hard to understand what the functions. Even for your own functions, you may often forget what your functions do unless you provide some documentation and comments in your scripts. Here we will see how to properly document a function in Python by looking at the max_dist function:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def max_dist(xc,yc):\n", " \"\"\"\n", " Finds the maximum distance between any two points\n", " in a collection of 2D points. The points corresponding \n", " to this distance are also returned.\n", " \n", " Parameters\n", " ----------\n", " xc : list\n", " List of x-coordinates\n", " yc : list\n", " List of y-coordinates\n", " \n", " Returns\n", " -------\n", " max_dist : float\n", " Maximum distance\n", " xvals : list\n", " x-coodinates of two points\n", " yvals : list\n", " y-coordinates of two points\n", " \n", " \"\"\"\n", " max_dist=0.0 #initialize max_dist\n", " num_points=len(xc) #number of points in collection\n", " for ii in range(num_points):\n", " for jj in range(num_points):\n", " dist=dist2d(xc[ii],yc[ii],xc[jj],yc[jj])\n", " if dist>max_dist:\n", " max_dist=dist\n", " xvals=[xc[ii],xc[jj]]\n", " yvals=[yc[ii],yc[jj]]\n", " return max_dist, xvals, yvals" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 67 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Everything inbetween the \"\"\"...\"\"\" is called a **docstring** and it gives a tells someone who is not familiar with a partiular functions a detailed explaination as to what the function does, what parameters it takes as inputs, and what values it returns. It is also good practice to put some comments next to your local variables so the user knows what each of these is for. Although it seems like a lot of work at first, writing docstrings will make you a much better programmer in the future." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "