{ "metadata": { "name": "", "signature": "sha256:696250adbe2a8e911bbdeb01c9303fec2d0b6c5e48eb5eb3ca11b3a79fc9a1cb" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to / review of Python" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Why Python?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Clean and powerful language designed by people who highly value elegance and readability.\n", "* Strong set of 3rd party analysis tools that are professionally and actively developed.\n", " * In particular a lot of momentum behind use of Python to develop scientific tools over the last decade:\n", " If you analyze data from Chandra, LOFAR, Fermi, Herschel, HST, JWST, ALMA, EVLA (etc etc) you will likely end up using Python even if you didn\u2019t intend it. So learning to use Python for for Astronomy data analysis has a good chance of paying off.\n", "* Interfaces well with existing C, C++, and FORTRAN libraries, providing access to existing libraries, such as robust numerical libraries like BLAS, ATLAS, etc. but with an easier to use interface.\n", " * Easier then to write numerical code, while also interacting with databases, using data from the web, visualization,\n", " and other such tasks that a higher-level language makes easier, all without leaving Python.\n", "* Very active developer community.\n", "* Free as in open source, and \"free as in beer\". Anyone can run Python on almost any platform for free--neither you nor your collaborators will need to worry about having the proper licenses to run software written in Python (unless of course the software itself is proprietary, though that is uncommon).\n", "\n", "\n", "**Why not?**\n", "\n", "* Switching from a familiar analysis environment is NOT FREE (hours \\* dollars/hour \\* overhead_rate)\n", " * \u201cUgh, I could do this so much faster the old way.\u201d\n", " * \u201cI can't find the functions I need to do [insert favorite IDL function].\u201d\n", " * \u201cStupid Python, why isn\u2019t this working?!\u201d\n", " * \u201cThese plots look ugly.\u201d\n", " \n", "However, Python has been actively used in the astronomy community for 10+ years, and has even driven some of the development of Python." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Table of Contents" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* [1. Individual things](#1.-Individual-things)\n", "* [2. Commands that operate on things](#2.-Commands-that-operate-on-things)\n", " * [EXERCISE 1 - Introducing logistic growth](#EXERCISE-1---Introducing-logistic-growth)\n", "* [3. Collections of things](#3.-Collections-of-things)\n", " * [EXERCISE 2 - Storing population size in a list](#EXERCISE-2---Storing-population-size-in-a-list)\n", " * [EXERCISE 3 - Storing data in arrays](#EXERCISE-3---Storing-data-in-arrays)\n", "* [4. Repeating yourself](#4.-Repeating-yourself)\n", " * [EXERCISE 4 - Using loops to repeat calculations](#EXERCISE-4---Using-loops-to-repeat-calculations)\n", "* [5. Making choices](#5.-Making-choices)\n", " * [EXERCISE 5 - Making the model stochastic with an if statement](#EXERCISE-5---Making-the-model-stochastic-with-an-if-statement)\n", "* [6. Creating chunks with functions and modules](#6.-Creating-chunks-with-functions-and-modules)\n", " * [EXERCISE 6 - Creating a logistic growth function](#EXERCISE-6---Creating-a-logistic-growth-function)\n", " * [EXERCISE 7 - Putting the growth function(s) in a module](#EXERCISE-7---Putting-the-growth-functions-in-a-module)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "1. Individual things" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The most basic component of any programming language are \"things\", also called objects.\n", "\n", "The most common basic \"things\" in Python are integers, floats, strings, booleans, and\n", "some special objects of various types. We'll meet many of these as we go through the lesson." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__TIP:__ To run the code in a cell quickly, press Ctrl-Enter." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__TIP:__ To quickly create a new cell below an existing one, hit the ESC key to go into the notebook's \"command mode\" and then hit the 'b' key.\n", "Other shortcuts for making, deleting, and moving cells are in the menubar at the top of the\n", "screen." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# A thing\n", "2" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 1, "text": [ "2" ] } ], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "# Use print to show multiple things in the same cell\n", "# Note that you can use single or double quotes for strings\n", "print 2\n", "print 'hello'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2\n", "hello\n" ] } ], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "# Things can be stored as variables\n", "a = 2\n", "b = 'hello'\n", "c = True # This is case sensitive\n", "print a, b, c" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2 hello True\n" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "# The type function tells us the type of thing we have\n", "print type(a)\n", "print type(b)\n", "print type(c)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "\n", "\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^Back to top](#Table-of-Contents)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "2. Commands that operate on things" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Just storing data in variables isn't much use to us. Right away, we'd like to start performing\n", "operations and manipulations on data and variables.\n", "\n", "There are three very common means of performing an operation on a thing." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "2.1 Use an operator" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All of the basic math operators work like you think they should for numbers. They can also\n", "do some useful operations on other things, like strings. There are also boolean operators that\n", "compare quantities and give back a `bool` variable as a result." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Standard math operators work as expected in numerical expressions\n", "print 2 + 3\n", "print 2 * 3\n", "print 2 ** 3" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "5\n", "6\n", "8\n" ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "# We can also assign numbers to named variables for use in expressions\n", "a = 2\n", "b = 3\n", "print a + b\n", "print a * b\n", "print a ** b" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "5\n", "6\n", "8\n" ] } ], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "# But be careful with integer division\n", "# Also watch out for exponentiation - you want **, not ^\n", "print 2 / 3\n", "print 2 / 3.0\n", "\n", "print 2 ** 3\n", "print 2 ^ 3" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "0\n", "0.666666666667\n", "8\n", "1\n" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "# There are also operators for strings\n", "print 'hello' + 'world'\n", "print 'hello' * 3\n", "#print 'hello' / 3" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "helloworld\n", "hellohellohello\n" ] } ], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "# Boolean operators compare two things\n", "a = (1 > 3)\n", "b = (3 == 3)\n", "print a\n", "print b\n", "print a or b\n", "print a and b" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "False\n", "True\n", "True\n", "False\n" ] } ], "prompt_number": 9 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "2.2 Use a function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These will be very familiar to anyone who has programmed in any language, and work like you\n", "would expect." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# There are thousands of functions that operate on things\n", "print type(3)\n", "print len('hello')\n", "print round(3.3)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "5\n", "3.0\n" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "__TIP:__ To find out what a function does, you can type it's name and then a question mark to\n", "get a pop up help window. Or, to see what arguments it takes, you can type its name, an open\n", "parenthesis, and hit tab." ] }, { "cell_type": "code", "collapsed": false, "input": [ "#round?\n", "#round(\n", "round(3.14159, 2)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "3.14" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "__TIP:__ Many useful functions are not in the Python built in library, but are in external\n", "scientific packages. These need to be imported into your Python notebook (or program) before\n", "they can be used. Probably the most important of these are numpy and matplotlib." ] }, { "cell_type": "code", "collapsed": true, "input": [ "# Many useful functions are in external packages\n", "# Let's meet numpy\n", "import numpy as np" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "code", "collapsed": true, "input": [ "# To see what's in a package, type the name, a period, then hit tab\n", "#np?\n", "#np." ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "# Some examples of numpy functions and \"things\"\n", "print np.sqrt(4)\n", "print np.pi # Not a function, just a variable\n", "print np.sin(np.pi)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2.0\n", "3.14159265359\n", "1.22464679915e-16\n" ] } ], "prompt_number": 14 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "2.3 Use a method" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we get any farther into the Python language, we have to say a word about \"objects\". We\n", "will not be teaching object oriented programming in this workshop, but you will encounter objects\n", "throughout Python (in fact, even seemingly simple things like ints and strings are actually\n", "objects in Python).\n", "\n", "In the simplest terms, you can think of an object as a small bundled \"thing\" that contains within\n", "itself both data and functions that operate on that data. For example, strings in Python are\n", "objects that contain a set of characters and also various functions that operate on the set of\n", "characters. When bundled in an object, these functions are called \"methods\".\n", "\n", "Instead of the \"normal\" `function(arguments)` syntax, methods are called using the\n", "syntax `variable.method(arguments)`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# A string is actually an object\n", "a = 'hello, world'\n", "print type(a)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "# Objects have bundled methods\n", "#a.\n", "print a.capitalize()\n", "print a.replace('l', 'X')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Hello, world\n", "heXXo, worXd\n" ] } ], "prompt_number": 16 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 1 - Introducing logistic growth" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Throughout this lesson, we will successively build towards a program that will calculate the\n", "logistic growth of a population of bacteria in a petri dish (or bears in the woods, if you\n", "prefer). The exercises will build on each other - if at any time you get behind, you can open the\n", "notebook _python-full_ to review answers to the previous exercises and catch up.\n", "\n", "As a reminder, a commonly used discrete time equation for logistic population growth is\n", "\n", "$$\n", "n(t+1) = n(t) + r n(t) [1 - n(t) / K]\n", "$$\n", "\n", "where $ n(t)$ is the population size at time $ t $, $ r $ is the net per capita growth rate, and $ K $ is the\n", "carrying capacity of the dish/woods.\n", "\n", "To get started, write Python expressions that do the following:\n", "\n", "1. Create variables for `r`, `K`, and `n0`, setting these equal to 0.6, 100, and 10, respectively.\n", "1. Create the variable `n1` and calculate it's value. Do the same for `n2`.\n", "1. Check the type of `n2` - what is it?\n", "1. Modify your calculations for `n1` and `n2` so that these values are rounded to the nearest\n", "integer.\n", "\n", "__Bonus__\n", "\n", "1. Test whether `n2` is larger than 20, and print out a line that says \"n2 more than 20: \"\n", "followed by the answer (either True or False).\n", "1. Figure out how to test whether `n2` is an integer (a mathematical integer, not necessarily\n", "whether it is an integer type) (HINT: look at the methods of `n2` by typing `n2.` and pressing\n", "tab.)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "r = 0.6\n", "K = 100\n", "n0 = 10\n", "\n", "n1 = round(n0 + r*n0*(1 - n0/K))\n", "n2 = round(n1 + r*n1*(1 - n1/K))\n", "\n", "print n0, n1, n2\n", "print type(n2)\n", "\n", "print 'n2 more than 20: ', n2 > 20\n", "print 'n2 is an integer: ', n2.is_integer()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "10 16.0 24.0\n", "\n", "n2 more than 20: True\n", "n2 is an integer: True\n" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^Back to top](#Table-of-Contents)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "3. Collections of things" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once the number of variables that you are interested in starts getting large, working with them\n", "all individually starts to get unwieldy. To help stay organized, we can use collections of things.\n", "\n", "Probably 99% of your work in scientific Python will use one of four types of collections:\n", "lists, tuples, dictionaries, and numpy arrays. We'll look quickly at each of these and what\n", "they can do for you." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "3.1 Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists are probably the handiest and most flexible type of container. Lists are declared with\n", "square brackets `[]`. Individual elements of a list can be selected using the syntax `a[ind]`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Lists are created with square bracket syntax\n", "a = ['hi', 'hello', 'yo']\n", "print a, type(a)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['hi', 'hello', 'yo'] \n" ] } ], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "# Lists (and all collections) are also indexed with square brackets\n", "# NOTE: The first index is zero, not one\n", "print a[0]\n", "print a[1]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "hi\n", "hello\n" ] } ], "prompt_number": 19 }, { "cell_type": "code", "collapsed": false, "input": [ "# Lists can be sliced by putting a colon between indexes\n", "# NOTE: The end value is not inclusive\n", "print a[0:2]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['hi', 'hello']\n" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "# You can leave off the start or end if desired\n", "print a[:2]\n", "print a[2:]\n", "print a[:]\n", "print a[:-1]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['hi', 'hello']\n", "['yo']\n", "['hi', 'hello', 'yo']\n", "['hi', 'hello']\n" ] } ], "prompt_number": 21 }, { "cell_type": "code", "collapsed": false, "input": [ "# Lists are objects, like everything else, and have methods such as append\n", "a.append('hiya')\n", "print a\n", "\n", "a.append([1,2])\n", "print a\n", "\n", "a.pop()\n", "print a" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['hi', 'hello', 'yo', 'hiya']\n", "['hi', 'hello', 'yo', 'hiya', [1, 2]]\n", "['hi', 'hello', 'yo', 'hiya']\n" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "# A very common use of lists is to create a range of integers\n", "# This is easy in Python using the built-in range function like\n", "# range(start, end); note that like the 'slice' notation the end value\n", "# is *not* inclusive\n", "print range(0, 10)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n" ] } ], "prompt_number": 23 }, { "cell_type": "markdown", "metadata": {}, "source": [ "__TIP:__ A 'gotcha' for some new Python users is that many collections, including lists,\n", "actually store pointers to data, not the data itself. This means that you need to be careful with\n", "writing things `b = a` and then changing `a`, since this will also change `b`. Have a look at the \n", "`copy` module if you want to make copies of variables." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 2 - Storing population size in a list" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Copy your code from Exercise 1 into the box below, and do the following:\n", "\n", "1. Modify your code so that the values of `n0`, `n1`, and `n2` are stored in a list and not as\n", "separate individual variables. HINT: You can start off by declaring an empty list using the syntax\n", "`n = []`, and then append each new calculated value of `nt` to the list.\n", "1. Get the first and last values in the list, calculate their ratio, and print out \"Grew by a factor of \"\n", "followed by the result.\n", "\n", "__Bonus__\n", "\n", "1. Extract the last value in two different ways: first, by using the index for\n", "the last item in the list, and second, presuming that you do not know how long the list is.\n", "1. Change the values of `r` and `K` to make sure that your cell still runs correctly and gives\n", "reasonable answers." ] }, { "cell_type": "code", "collapsed": false, "input": [ "######################################\n", "# This code deletes our old variables\n", "try: del n0, n1, n2, r, K\n", "except: pass\n", "######################################\n", "\n", "r = 0.6\n", "K = 100\n", "n = []\n", "n.append(10) # Append n0 in the first location\n", "\n", "n.append(round(n[0] + r*n[0]*(1 - n[0]/K))) # Append n1\n", "n.append(round(n[1] + r*n[1]*(1 - n[1]/K))) # Append n2\n", "n.append(round(n[2] + r*n[2]*(1 - n[2]/K))) # Append n3\n", "\n", "print n\n", "\n", "print \"Grew by a factor of \", n[3]/n[0] # or n[-1]/n[0]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[10, 16.0, 24.0, 35.0]\n", "Grew by a factor of 3.5\n" ] } ], "prompt_number": 24 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "3.2 Dictionaries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dictionaries are the collection to use when you want to store and retrieve things by their names\n", "(or some other kind of key) instead of by their position in the collection. A good example is a set\n", "of model parameters, each of which has a name and a value. Dictionaries are declared using {}." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Make a dictionary of model parameters\n", "params = {'n0': 10, 'r': 0.5}\n", "print params\n", "print params['r']" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'n0': 10, 'r': 0.5}\n", "0.5\n" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": [ "params['K'] = 200\n", "print params" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "{'n0': 10, 'K': 200, 'r': 0.5}\n" ] } ], "prompt_number": 26 }, { "cell_type": "code", "collapsed": true, "input": [ "#print params['c']" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": [ "K = 200\n", "locals()['K']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 28, "text": [ "200" ] } ], "prompt_number": 28 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "3.3 Tuples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We won't say a whole lot about tuples except to mention that they basically work just like lists, with\n", "two major exceptions:\n", "\n", "1. You declare tuples using `()` instead of `[]`\n", "1. Once you make a tuple, you can't change what's in it\n", "\n", "You'll see tuples come up throughout the Python language, and over time you'll develop a feel for when\n", "to use them. In general, they're often used instead of lists to group items when the position in the\n", "collection is critical to understanding the item's meaning, such as `(x,y)`, and when you want to make\n", "sure that you don't accidentally modify any of the items later." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "3.4 Numpy arrays (ndarrays)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Even though numpy arrays (often written as ndarrays, for n-dimensional arrays) are not part of the\n", "core Python libraries, they are so useful in scientific Python that we'll include them here in the \n", "core lesson. Numpy arrays are collections of things, all of which must be the same type, that work\n", "similarly to lists (as we've described them so far). The most important are:\n", "\n", "1. You can easily perform elementwise operations (and matrix algebra) on arrays\n", "1. Arrays can be n-dimensional\n", "1. Arrays must be pre-allocated (ie, there is no equivalent to append)\n", "\n", "Arrays can be created from existing collections such as lists, or instantiated \"from scratch\" in a \n", "few useful ways.\n", "\n", "When getting started with scientific Python, you will probably want to try to use ndarrays whenever\n", "possible, saving the other types of collections for those cases when you have a specific reason to use\n", "them." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Make an array from a list\n", "alist = [2, 3, 4]\n", "blist = [5, 6, 7]\n", "a = np.array(alist)\n", "b = np.array(blist)\n", "print a, type(a)\n", "print b, type(b)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2 3 4] \n", "[5 6 7] \n" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "# Do arithmetic on arrays\n", "print a**2\n", "print np.sin(a)\n", "print a * b\n", "print a.dot(b), np.dot(a, b)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[ 4 9 16]\n", "[ 0.90929743 0.14112001 -0.7568025 ]\n", "[10 18 28]\n", "56 56\n" ] } ], "prompt_number": 30 }, { "cell_type": "code", "collapsed": false, "input": [ "# Boolean operators work on arrays too, and they return boolean arrays\n", "print a > 2\n", "print b == 6\n", "\n", "c = a > 2\n", "print c\n", "print type(c)\n", "print c.dtype" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[False True True]\n", "[False True False]\n", "[False True True]\n", "\n", "bool\n" ] } ], "prompt_number": 31 }, { "cell_type": "code", "collapsed": false, "input": [ "# Indexing arrays\n", "print a[0:2]\n", "\n", "c = np.random.rand(3,3)\n", "print c\n", "print '\\n'\n", "print c[1:3,0:2]\n", "\n", "c[0,:] = a\n", "print '\\n'\n", "print c" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2 3]\n", "[[ 0.00299407 0.48646273 0.87493591]\n", " [ 0.66697541 0.4409932 0.38805807]\n", " [ 0.29620557 0.3936714 0.02729212]]\n", "\n", "\n", "[[ 0.66697541 0.4409932 ]\n", " [ 0.29620557 0.3936714 ]]\n", "\n", "\n", "[[ 2. 3. 4. ]\n", " [ 0.66697541 0.4409932 0.38805807]\n", " [ 0.29620557 0.3936714 0.02729212]]\n" ] } ], "prompt_number": 32 }, { "cell_type": "code", "collapsed": false, "input": [ "# Arrays can also be indexed with other boolean arrays\n", "print a\n", "print b\n", "print a > 2\n", "print a[a > 2]\n", "print b[a > 2]\n", "\n", "b[a == 3] = 77\n", "print b" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[2 3 4]\n", "[5 6 7]\n", "[False True True]\n", "[3 4]\n", "[6 7]\n", "[ 5 77 7]\n" ] } ], "prompt_number": 33 }, { "cell_type": "code", "collapsed": false, "input": [ "# ndarrays have attributes in addition to methods\n", "#c.\n", "print c.shape\n", "print c.prod()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "(3, 3)\n", "0.00871794394549\n" ] } ], "prompt_number": 34 }, { "cell_type": "code", "collapsed": false, "input": [ "# There are handy ways to make arrays full of ones and zeros\n", "print np.zeros(5), '\\n'\n", "print np.ones(5), '\\n'\n", "print np.identity(5), '\\n'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[ 0. 0. 0. 0. 0.] \n", "\n", "[ 1. 1. 1. 1. 1.] \n", "\n", "[[ 1. 0. 0. 0. 0.]\n", " [ 0. 1. 0. 0. 0.]\n", " [ 0. 0. 1. 0. 0.]\n", " [ 0. 0. 0. 1. 0.]\n", " [ 0. 0. 0. 0. 1.]] \n", "\n" ] } ], "prompt_number": 35 }, { "cell_type": "code", "collapsed": false, "input": [ "E = np.empty(5)\n", "E.fill(2)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 36 }, { "cell_type": "code", "collapsed": false, "input": [ "# You can also easily make arrays of number sequences\n", "print np.arange(0, 10, 2)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0 2 4 6 8]\n" ] } ], "prompt_number": 37 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 3 - Storing data in arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " \n", "Copy your code from Exercise 2 into the box below, and do the following:\n", "\n", "1. Modify your code to store the calculation results in an array instead of a list. HINT: \n", "Make sure to pre-allocate space for the array using `np.zeros()` or something similar. Pre-allocate an\n", "array of length 100, as if we were going to fill in 100 time steps, including n0.\n", "2. Imagine that each discrete time step actually represents 0.25 of an hour. Create an array `t` storing\n", "the time, in hours, of each step of the calculations (for example, t0 is 0, t1 is 0.25, t2 is 0.5, etc.)\n", "up to 100 time steps (the final time will thus be 24.75).\n", "3. Use boolean indexing to extract the value of `n` corresponding to a `t` of 0.5." ] }, { "cell_type": "code", "collapsed": false, "input": [ "r = 0.6\n", "K = 100\n", "n = np.zeros(100)\n", "n[0] = 10\n", "\n", "n[1] = round(n[0] + r*n[0]*(1 - n[0]/K))\n", "n[2] = round(n[1] + r*n[1]*(1 - n[1]/K))\n", "n[3] = round(n[2] + r*n[2]*(1 - n[2]/K))\n", "\n", "print n\n", "\n", "t = np.arange(0, 25, 0.25)\n", "t = np.linspace(0, 25, 100, endpoint=False)\n", "print t\n", "\n", "print n[t == 0.5]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[ 10. 15. 23. 34. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", " 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", " 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", " 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", " 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", " 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.\n", " 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n", "[ 0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. 2.25\n", " 2.5 2.75 3. 3.25 3.5 3.75 4. 4.25 4.5 4.75 5.\n", " 5.25 5.5 5.75 6. 6.25 6.5 6.75 7. 7.25 7.5\n", " 7.75 8. 8.25 8.5 8.75 9. 9.25 9.5 9.75 10. 10.25\n", " 10.5 10.75 11. 11.25 11.5 11.75 12. 12.25 12.5 12.75 13.\n", " 13.25 13.5 13.75 14. 14.25 14.5 14.75 15. 15.25 15.5\n", " 15.75 16. 16.25 16.5 16.75 17. 17.25 17.5 17.75 18. 18.25\n", " 18.5 18.75 19. 19.25 19.5 19.75 20. 20.25 20.5 20.75 21.\n", " 21.25 21.5 21.75 22. 22.25 22.5 22.75 23. 23.25 23.5\n", " 23.75 24. 24.25 24.5 24.75]\n", "[ 23.]\n" ] } ], "prompt_number": 38 }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^Back to top](#Table-of-Contents)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "4. Repeating yourself" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far, everything that we've done could, in principle, be done by hand calculation. In this section\n", "and the next, we really start to take advantage of the power of programming languages to do things\n", "for us automatically.\n", "\n", "We start here with ways to repeat yourself. The two most common ways of doing this are known as for\n", "loops and while loops. For loops in Python are useful when you want to cycle over all of the items\n", "in a collection (such as all of the elements of an array), and while loops are useful when you want to\n", "cycle for an indefinite amount of time until some condition is met.\n", "\n", "The basic examples below will work for looping over lists, tuples, and arrays. Looping over dictionaries\n", "is a bit different, since there is a key and a value for each item in a dictionary. Have a look at the\n", "Python docs for more information." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# A basic for loop - don't forget the white space!\n", "wordlist = ['hi', 'hello', 'bye']\n", "for word in wordlist:\n", " print word + '!'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "hi!\n", "hello!\n", "bye!\n" ] } ], "prompt_number": 39 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note on indentation**: Notice the indentation once we enter the for loop. Every idented statement after the for loop declaration is part of the for loop. This rule holds true for while loops, if statements, functions, etc. Required identation is one of the reasons Python is such a beautiful language to read.\n", "\n", "If you do not have consistent indentation you will get an `IndentationError`. Fortunately, most code editors will ensure your indentation is correction." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Indentation error: Fix it!\n", "for word in wordlist:\n", " new_word = word.capitalize()\n", " print new_word + '!' # Bad indent" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "IndentationError", "evalue": "unindent does not match any outer indentation level (, line 4)", "output_type": "pyerr", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m4\u001b[0m\n\u001b[1;33m print new_word + '!' # Bad indent\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unindent does not match any outer indentation level\n" ] } ], "prompt_number": 40 }, { "cell_type": "code", "collapsed": false, "input": [ "# Sum all of the values in a collection using a for loop\n", "numlist = [1, 4, 77, 3]\n", "\n", "total = 0\n", "for num in numlist:\n", " total = total + num\n", " \n", "print \"Sum is\", total" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Sum is 85\n" ] } ], "prompt_number": 41 }, { "cell_type": "code", "collapsed": false, "input": [ "# Often we want to loop over the indexes of a collection, not just the items\n", "print wordlist\n", "\n", "wordrange = np.arange(len(wordlist))\n", "print wordrange\n", "\n", "for i in wordrange:\n", " print i, wordlist[i]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['hi', 'hello', 'bye']\n", "[0 1 2]\n", "0 hi\n", "1 hello\n", "2 bye\n" ] } ], "prompt_number": 42 }, { "cell_type": "code", "collapsed": false, "input": [ "# While loops are useful when you don't know how many steps you will need,\n", "# and want to stop once a certain condition is met.\n", "step = 0\n", "prod = 1\n", "while prod < 100:\n", " step = step + 1\n", " prod = prod * 2\n", " print step, prod\n", " \n", "print 'Reached a product of', prod, 'at step number', step" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 2\n", "2 4\n", "3 8\n", "4 16\n", "5 32\n", "6 64\n", "7 128\n", "Reached a product of 128 at step number 7\n" ] } ], "prompt_number": 43 }, { "cell_type": "markdown", "metadata": {}, "source": [ "__TIP:__ Once we start really generating useful and large collections of data, it becomes unwieldy to\n", "inspect our results manually. The code below shows how to make a very simple plot of an array.\n", "We'll do more plotting later on, this is just to get started." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Load up pylab, a useful plotting library\n", "%matplotlib inline\n", "from matplotlib import pyplot as plt\n", "\n", "# Make some x and y data and plot it\n", "y = np.arange(100)**2\n", "plt.plot(y)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 45, "text": [ "[]" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 45 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 4 - Using loops to repeat calculations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "FINALLY, let's get smart about our calculations of `nt`. Copy your code from Exercise 3 into the box\n", "below, and do the following:\n", "\n", "1. Write a for loop to fill in the values of `nt` for 100 time steps. HINT: You will need to \n", "create an array of the step numbers using a command like `step = range(1, 100)`. (Why does\n", "this list start at 1 and not at 0?). Then, loop over the values of the step list,\n", "and use each step value to index the array `n`.\n", "1. Plot the array `n`.\n", "1. Play around with the values of `r` and `K` and see how it changes the plot. What happens if you set\n", "`r` to 1.9 or 3?\n", "\n", "__Bonus__\n", "\n", "1. Modify your code to use a while loop that will stop your calculation once the population size is\n", "greater than 90. HINT: Start a step counter `i` at 1, and check that the value in `n[i-1]` is less than 90\n", "each time around the loop. Increment the step counter within the loop so that you have a record\n", "of what step the calculation stopped at." ] }, { "cell_type": "code", "collapsed": false, "input": [ "r = 0.6\n", "K = 100\n", "n = np.zeros(100, dtype=float)\n", "n[0] = 10\n", "\n", "steps = range(1, 100)\n", "for i in steps:\n", " n[i] = round(n[i-1] + r*n[i-1]*(1 - n[i-1]/K))\n", " \n", "plt.plot(n)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 47, "text": [ "[]" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nGwyGSqfTqc3Pz99tsViKb/VZtHAAAEJPVNjff//9XyUnJ3tvfM1utxtZluWIiFiW5Ww2m+lWn0XY\nAwCEgd/vF7XV19drcnJyjgb+nJSU5A183d3drbjxz4GNiPzYsGHDhm3wm9isDmzxNAQUCoVfoVD4\nb3492Hs7AACAOJKdjcMwDO/xeNRERG63O0WlUrVINTYAAARHsrA3Go12juNYIiKO41iTyWSTamwA\nAAiOqFscFxYWfrB3794F58+fH8cwDP/aa6/96yOPPPKJ2Wy2NjQ0TNRoNC6r1WpOSkryDUHNAAAw\nWME2/Qe6ff755w9lZmaenDx58imLxfJyqPYrh62hoSFdr9f/XafTHc/Ozj5WXl7+G7/fT62trcpF\nixZVTpkyxWkwGCq8Xm9SuGsN1dbZ2Rk3c+bM2iVLlnway3Ph9XqTVqxY8besrKwTU6dOrTtw4MC8\nWJ2L0tLS9Tqd7nhOTs7RwsLCv167du3OWJmL1atXb1OpVPyNJ73c7mcvLS1dP3ny5FOZmZknv/ji\ni4KB7CMkP0hnZ2dcRkbG9/X19Zr29vaEGTNmHK6rq5sa7gkO1eZ2u9W1tbUz/X4/Xbp0abRWq/2u\nrq5u6osvvvjHDRs2vOT3+8lisbz88ssvW8Jda6i2jRs3/o9Vq1b9ZenSpXa/30+xOhdPPPEEt3Xr\n1jV+v586OjrifT5fYizORX19vWbSpEk/XLt27U6/309ms/nD9957j42Vufjyyy/vr6mpyb0x7Pv6\n2Y8fP66bMWPG4fb29oT6+npNRkbG911dXcP620dIfpB9+/bNX7x48a7An8vKyorLysqKwz3B4doe\neeQRW2Vl5aLMzMyTHo+H8ft7fiFkZmaeDHdtodgaGxvT8vPzq/bs2fNgYGUfi3Ph8/kSJ02a9MPN\nr8fiXLS2tiq1Wu13giAkd3R0xC9ZsuTTiooKQyzNxc2ns/f1s5eWlq6/sTuyePHiXfv377+nv/FD\ncm+cpqam1PT09MbAn9PS0s42NTWlhmLfcuNyuTS1tbW58+bNO8jzPMMwDE/UczYTz/NMuOsLheef\nf37T66+//uKwYcO6A6/F4lzU19dPGj9+/LnVq1e/O2vWrJqnnnrq7StXroyKxblQKpXCCy+8sHHi\nxIkNEyZMaE5KSvIZDIbKWJyLgL5+9ubm5glpaWlnA+8baJ6GJOxvdc59LLp8+fLoFStWfFReXv7c\nmDFjLt34vb6uTYg2n3322RKVStWSm5tb6+/juotYmYvOzs74mpqaWc8888xbNTU1s0aNGnXl5tuM\nxMpcnD59OmPz5s3rXC6Xprm5ecLly5dHv//++/9y43tiZS5upb+ffSDzEpKwT01NbWpsbEwP/Lmx\nsTH9xt9MsaCjoyNhxYoVHxUVFW0PnJYai9cm7Nu371673W6cNGlSfWFh4Qd79uxZWFRUtD0W5yIt\nLe1sWlra2Tlz5nxNRLRy5cq/1dTUzFKr1Z5Ym4tDhw7l3XvvvfvGjh3bGh8f37l8+fKP9+/fPz8W\n5yKgr78TN+fp2bNn01JTU5v6Gy8kYZ+Xl3fo1KlTU1wul6a9vf2ODz/88FGj0WgPxb7lwO/3K9au\nXbtVp9PVrVu3bnPg9Vi8NqG0tPSVxsbG9Pr6+kk7dux4bOHChXu2b99eFItzoVarPenp6Y1Op1NL\nRFRVVbUoOzv7+NKlSz+NtbnIyso6eeDAgXuuXr06wu/3K6qqqhbpdLq6WJyLgL7+ThiNRvuOHTse\na29vv6O+vn7SqVOnpsydO7e63wFDdfBh586d/6zVar/LyMj4vrS0dH24D4aEcvvqq6/uUygU3TNm\nzDg8c+bM2pkzZ9Z+/vnnD7W2tirz8/Orov20sr42h8OxIHA2TqzOxeHDh2fk5eV9PX369CPLli37\n2OfzJcbqXGzYsOGlwKmXTzzxBNfe3p4QK3Px2GOPfZCSktKckJDQnpaW1rht27bVt/vZ//CHP7yS\nkZHxfWZm5sldu3YtHsg+RF1UBQAAkSUsjyUEAIDQQtgDAMQAhD0AQAxA2AMAxACEPQBADEDYAwDE\ngP8PK4OP7HRLT40AAAAASUVORK5CYII=\n", "text": [ "" ] } ], "prompt_number": 47 }, { "cell_type": "code", "collapsed": false, "input": [ "r = 0.6\n", "K = 100\n", "n = np.zeros(100)\n", "n[0] = 10\n", "\n", "i = 1\n", "while n[i-1] < 90:\n", " n[i] = round(n[i-1] + r*n[i-1]*(1 - n[i-1]/K))\n", " print i, n[i]\n", " i = i + 1\n", " \n", "print 'Ended with a population size of', n[i-1], 'at step', i-1\n", "print 'Population sizes to this step were', n[0:i]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1 15.0\n", "2 23.0\n", "3 34.0\n", "4 47.0\n", "5 62.0\n", "6 76.0\n", "7 87.0\n", "8 94.0\n", "Ended with a population size of 94.0 at step 8\n", "Population sizes to this step were [ 10. 15. 23. 34. 47. 62. 76. 87. 94.]\n" ] } ], "prompt_number": 48 }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^Back to top](#Table-of-Contents)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "5. Making choices" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often we want to check if a condition is True and take one action if it is, and another action if the\n", "condition is False. We can achieve this in Python with an if statement.\n", "\n", "__TIP:__ You can use any expression that returns a boolean value (`True` or `False`) in an if statement.\n", "Common boolean operators are `==`, `!=`, `<`, `<=`, `>`, `>=`. You can also use `is` and `is not` if you want to\n", "check if two variables are identical in the sense that they are stored in the same location in memory." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# A simple if statement\n", "x = 3\n", "if x > 0:\n", " print 'x is positive'\n", "elif x < 0:\n", " print 'x is negative'\n", "else:\n", " print 'x is zero'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "x is positive\n" ] } ], "prompt_number": 49 }, { "cell_type": "code", "collapsed": true, "input": [ "# If statements can rely on boolean variables\n", "x = -1\n", "test = (x > 0)\n", "print type(test); print test\n", "\n", "if test:\n", " print 'Test was true'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "False\n" ] } ], "prompt_number": 50 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 5 - Making the model stochastic with an if statement" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Deterministic models are boring, so let's introduce some element of randomness into our logistic\n", "growth model. We'll model a simple \"catastrophe\" process, in which a catastrophe happens in 10% of the\n", "time steps that reduces the population back down to the size at n0. Copy your code from Exercise 4\n", "into the box below, and do the following:\n", "\n", "1. Inside your for loop, add a variable called `cata`, for catastrophe, that will be `True` if a catastrophe\n", "has occurred, and `False` if it hasn't. A simple way to do this is to generate a random number using\n", "`np.random.rand()`, which will give you a pseudorandom number between 0 and 1. Check whether this number\n", "is less than 0.1 - this check will be True 10% of the time.\n", "1. Using your boolean variable `cata`, add an if statement to your for loop that checks whether `cat` is\n", "true in each time step. If it is true, set the population back to the size at n[0]. Otherwise, perform\n", "the usual logistic growth calculation.\n", "1. Plot your results. Run the cell again to see a different random population growth path.\n", "\n", "__Bonus__\n", "\n", "1. Now that you have the array `n`, count the number of time steps in which the population was above 50.\n", "Although you can do this with a for loop (loop through each value of `nt`, check if it is > 50, and if so\n", "increment a counter), you can do this in one line with a simple boolean operation.\n", "HINT: If you take the sum of a boolean array (using `np.sum()`), it will give you the number of\n", "`True` values (since a `True` is considered to be a 1, and `False` is a 0)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Set up initial model parameters\n", "r = 0.6\n", "K = 100\n", "n = np.zeros(100)\n", "n[0] = 10\n", "\n", "# Loop through all time steps\n", "steps = np.arange(1, 100)\n", "for i in steps:\n", " cata = (np.random.rand() < 0.1) # Random catastrophe 10% of time\n", " if cata:\n", " n[i] = n[0]\n", " else:\n", " n[i] = round(n[i-1] + r*n[i-1]*(1 - n[i-1]/K))\n", " \n", "plt.plot(n)\n", "\n", "print 'Population was above 50 in', np.sum(n > 50), 'out of 100 steps'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Population was above 50 in 65 out of 100 steps\n" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\n", "text": [ "" ] } ], "prompt_number": 52 }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^Back to top](#Table-of-Contents)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "6. Creating chunks with functions and modules" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One way to write a program is to simply string together commands, like the ones described above, in a long\n", "file, and then to run that file to generate your results. This may work, but it can be cognitively difficult\n", "to follow the logic of programs written in this style. Also, it does not allow you to reuse your code\n", "easily - for example, what if we wanted to run our logistic growth model for several different choices of\n", "initial parameters?\n", "\n", "The most important ways to \"chunk\" code into more manageable pieces is to create functions and then\n", "to gather these functions into modules, and eventually packages. Below we will discuss how to create\n", "functions and modules. A third common type of \"chunk\" in Python is classes, but we will not be covering\n", "object-oriented programming in this workshop." ] }, { "cell_type": "code", "collapsed": false, "input": [ "# We've been using functions all day\n", "x = 3.333333\n", "print round(x, 2)\n", "print np.sin(x)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "3.33\n", "-0.190567635651\n" ] } ], "prompt_number": 53 }, { "cell_type": "code", "collapsed": true, "input": [ "# It's very easy to write your own functions\n", "def multiply(x, y):\n", " return x*y" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 54 }, { "cell_type": "code", "collapsed": false, "input": [ "# Once a function is \"run\" and saved in memory, it's available just like any other function\n", "print type(multiply)\n", "print multiply(4, 3)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "\n", "12\n" ] } ], "prompt_number": 55 }, { "cell_type": "code", "collapsed": true, "input": [ "# It's useful to include docstrings to describe what your function does\n", "def say_hello(time, people):\n", " '''\n", " Function says a greeting. Useful for engendering goodwill\n", " '''\n", " return 'Good ' + time + ', ' + people" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 56 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Docstrings**: A docstring is a special type of comment that tells you what a function does. You can see them when you ask for help about a function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "say_hello('afternoon', 'friends')" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 57, "text": [ "'Good afternoon, friends'" ] } ], "prompt_number": 57 }, { "cell_type": "code", "collapsed": true, "input": [ "# All arguments must be present, or the function will return an error\n", "#say_hello('afternoon')" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 58 }, { "cell_type": "code", "collapsed": true, "input": [ "# Keyword arguments can be used to make some arguments optional by giving them a default value\n", "# All mandatory arguments must come first, in order\n", "def say_hello(time, people='friends'):\n", " return 'Good ' + time + ', ' + people" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 59 }, { "cell_type": "code", "collapsed": false, "input": [ "say_hello('afternoon')" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 60, "text": [ "'Good afternoon, friends'" ] } ], "prompt_number": 60 }, { "cell_type": "code", "collapsed": false, "input": [ "say_hello('afternoon', 'students')" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 61, "text": [ "'Good afternoon, students'" ] } ], "prompt_number": 61 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 6 - Creating a logistic growth function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, let's turn our logistic growth model into a function that we can use over and over again. \n", "Copy your code from Exercise 5 into the box below, and do the following:\n", "\n", "1. Turn your code into a function called `logistic_growth` that takes four arguments: `r`, `K`, `n0`,\n", "and `p` (the probability of a catastrophe). Make `p` a keyword argument with a default value of 0.1.\n", "Have your function return the `n` array.\n", "1. Write a nice docstring describing what your function does.\n", "1. In a subsequent cell, call your function with different values of the parameters to make sure it works.\n", "Store the returned value of `n` and make a plot from it.\n", "\n", "__Bonus__\n", "\n", "1. Refactor your function by pulling out the line that actually performs the calculation of the new\n", "population given the old population. Make this line another function called `grow_one_step` that takes\n", "in the old population, `r`, and `K`, and returns the new population. Have your `logistic_growth` function\n", "use the `grow_one_step` function to calculate the new population in each time step." ] }, { "cell_type": "code", "collapsed": true, "input": [ "def logistic_growth(r, K, n0, p=0.1):\n", " '''\n", " Function to simulate discrete time stochastic logistic growth\n", "\n", " Arguments\n", " ---------\n", " r : float\n", " Reproductive rate of population\n", " K : float\n", " Carrying capacity\n", " n0 : float\n", " Initial population\n", " p : float\n", " Probability of a catastrophe resetting the population to n0\n", "\n", " Returns\n", " -------\n", " n : ndarray\n", " Array of 100 time steps of population values\n", " '''\n", " \n", " # Set up population array\n", " n = np.zeros(100, dtype=float)\n", " n[0] = n0\n", "\n", " # Loop through all time steps\n", " steps = np.arange(1, 100)\n", " for i in steps:\n", " cat = (np.random.rand() < p) # Random catastrophe 10% of time\n", " if cat:\n", " n[i] = 10\n", " else:\n", " n[i] = grow_one_step(n[i-1], r, K)\n", " \n", " return n\n", "\n", "def grow_one_step(nold, r, K):\n", " '''Calculate new population from old one.'''\n", " return round(nold + r*nold*(1 - nold/K))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 62 }, { "cell_type": "code", "collapsed": false, "input": [ "a1 = logistic_growth(0.6, 100, 10)\n", "a2 = logistic_growth(0.6, 100, 10)\n", "a3 = logistic_growth(0.6, 100, 10)\n", "\n", "plt.hold(True)\n", "plt.plot(a1)\n", "plt.plot(a2)\n", "plt.plot(a3)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 64, "text": [ "[]" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nAElFTkSuQmCC\n", "text": [ "" ] } ], "prompt_number": 64 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "EXERCISE 7 - Putting the growth functions in a module" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can make our functions more easily reusable by placing them into modules that we can import, just\n", "like we have been doing with `numpy`. It's pretty simple to do this.\n", "\n", "1. Copy your function(s) from Exercise 6 into a new text file, in the same directory as this notebook,\n", "called `pop.py`.\n", "1. In the cell below, type `import pop` to import the module. Type `pop.` and hit tab to see the available\n", "functions in the module. Try running the logistic growth function that was imported from the module with\n", "a few different parameter values." ] }, { "cell_type": "code", "collapsed": true, "input": [ "# import pop\n", "# reload(pop) # This line forces the re-import of pop if you make changes and run this cell again\n", "# plot(pop.logistic_growth(0.6, 100, 10))" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^Back to top](#Table-of-Contents)" ] } ], "metadata": {} } ] }