{ "metadata": { "name": "", "signature": "sha256:ad0d0df1d0c10070519526eea1a39d399e365a0e3712671f346a064ce27fc1af" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 6, "metadata": {}, "source": [ "Content provided under a Creative Commons Attribution license, CC-BY 4.0; code under MIT License. (c)2014 [David I. Ketcheson](http://davidketcheson.info)" ] }, { "cell_type": "heading", "level": 5, "metadata": {}, "source": [ "version 0.1 - May 2014" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "A Brief Introduction to Python" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This lesson is a preamble to the HyperPython short course, in which you will learn some basic theory of hyperbolic conservation laws and how to solve them numerically.\n", "\n", "In this lesson, we'll learn about the [Python programming language](https://www.python.org/) and the [IPython notebook](http://ipython.org/notebook.html), as well as the Python packages [numpy](http://www.numpy.org/) and [matplotlib](http://matplotlib.org/). If you're already familiar with these, you may skip to [Lesson 1](Lesson_01_Advection.ipynb), where the real fun begins.\n", "\n", "This isn't a very thorough introduction -- we'll just learn the things that are essential for the course. Some resources for learning more about Python and its use in scientific computing are linked [at the end of this notebook](#Further-resources)." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Prerequisites" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Knowledge" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get through the course, you need not have used Python or studied hyperbolic PDEs before. But it is assumed that you have programmed in *some* language and that you are familiar with basic differential equations and numerical methods." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Software" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To run the code in this course, you'll need an installation of Python, numpy, matplotlib, and Clawpack. The easiest way to get them all is to use [SageMathCloud](http://cloud.sagemath.org) -- just create a free account, start a new project, open a terminal, and type\n", " \n", " git clone git@github.com:ketch/HyperPython.git\n", " \n", "Open this notebook there and you're off.\n", "\n", "You can also use [Wakari](http://wakari.io), or install everything locally on your own machine. For local installation, [Anaconda](https://store.continuum.io/cshop/anaconda/) is convenient, or you can just use pip. All of these are free." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Python and the IPython Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The code for this course is written in Python, which is a programming language designed to promote code that is easy to read and write. Python has become one of the most important languages in scientific computing. It is high-level like MATLAB, but unlike MATLAB it is free and is intended as a general-purpose language." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[IPython](http://www.ipython.org) is a collection of tools for interactive programming in Python. Most importantly for us, IPython includes an interactive shell and a browser-based notebook. The notebook (which you are using now) allows you to run Python code in your web browser; just click on a cell with code and hit shift+enter. Try it with the cell below." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print \"The best conservation laws are hyperbolic!\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Try changing the message in the box and running it again.\n", "\n", "The box of code above is called a *cell*. You can use the menu and toolbar near the top of your browser to insert or delete cells or save the notebook. The text you're reading is also in a cell, which you can edit (just double-click on this text). You'll also see math in these cells; the math is written using LaTeX. For example:\n", "\n", "$$e^{i \\pi} = -1.$$\n", "\n", "The menu bar above also has buttons to run cells or to stop code running." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can find a huge collection of interesting IPython notebooks on a wide range of topics [here](https://github.com/ipython/ipython/wiki/A-gallery-of-interesting-IPython-Notebooks#table-of-contents). Since notebooks combine text, mathematics, and executable code, they're a great way to learn." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Running the code cell below will reformat the notebook to make things a bit easier to read, and will also help you keep track of running code later on. The same cell appears at the top of each of the later lessons in the course." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.core.display import HTML\n", "css_file = './custom.css'\n", "HTML(open(css_file, \"r\").read())" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we'll get into the meat of Python. For this first lesson, I recommend that you open an IPython session in a terminal and type the code yourself, rather than just executing the code here in the notebook." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Python basics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python has many built-in functions, like `print`, but most functions are inside *modules*, which aren't loaded unless you `import` them:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from math import sqrt\n", "print sqrt(2)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also import a whole module:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import math\n", "print math.sqrt(2)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What else is in the `math` module? You can find out using IPython's tab completion. Just put your cursor at the end of the line below and hit `tab`:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "math." ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What does `math.atan2` do, for instance? You can find out with IPython's magic help function, invoked by using the question mark after a function name. When you're done reading the help, you can close the pager below by clicking on the \"x\"." ] }, { "cell_type": "code", "collapsed": false, "input": [ "math.atan2?" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A *list* is an ordered collection of values or objects." ] }, { "cell_type": "code", "collapsed": false, "input": [ "x = [1,2,3,4]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can ask for one or more items from a list as follows:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print x[0]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "print x[1:3]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two important things to remember:\n", "1. Python lists are indexed starting from zero.\n", "2. When you ask for a range of things, you don't get the last one." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can quickly make lists of numbers using the `range` function:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "y = range(1,5)\n", "print y" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Loops" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for i in range(5):\n", " print i\n", " print 'in the loop'\n", " \n", "print 'finished'" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A *for loop* just iterates over a list. Notice how the contents of the loop are indented. Python knows the loop has ended when it finds a line that is not indented. \n", "\n", "To nest loops, indent again:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "for i in range(5):\n", " print i\n", " for j in range(2):\n", " print 'in the inner loop'\n", " \n", "print 'finished'" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Don't forget the colon!" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Functions" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def square(x):\n", " return x**2\n", "\n", "print square(5)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice how the contents of the function are indented (just like the for loop). Python knows the function has ended when it finds a line that is not indented." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numpy\n", "Python includes a package for numerical computation called numpy, which will be an essential tool in this course. To get started, we import the numpy module. We will also tell Python that we want to refer to numpy by the short abbreviation \"np\":" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import numpy as np" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Arrays\n", "\n", "The most important Numpy class is the `array`. You can make arrays just like you would in MATLAB:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "x = np.linspace(0, 1, 5)\n", "print x" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "y = np.arange(0, 1, 0.2)\n", "print y" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like `range`, `arange` omits the final value." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Arrays are like lists, except that you can perform math with them in an easier and faster way:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print x+y" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "print x*y" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The syntax for creating a multidimensional array in numpy is also similar to Matlab:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "A = np.array([[1,2,3],[4,5,6],[7,8,9]])\n", "print A" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Indexing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can slice numpy arrays just as in Fortran 90 or Matlab, but (as with lists) the arrays are indexed from zero and you don't get the last element of a slice." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print A[0,0]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "print A[1:3,0:2]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can index in some slightly fancier ways, too:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print A[:,1:]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "print A[-1,:]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can do lots of other things with arrays. Type \"A.\" (notice the period!) and press `tab` to see some of them:" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Matplotlib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For plotting we will use the [matplotlib](http://matplotlib.org/) package. It works a lot like MATLAB's plotting functions." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The line beginning with a \"%\" is referred to as a magic function. It makes plots appear in the browser, rather than in a separate window. If you want to know about all of IPython's magic functions, just type \"%magic\".\n", "\n", "Now for a very simple example. Suppose we want to plot the function $\\sin(\\exp(x))$ on the interval $x\\in(0,4)$. We'll use the numpy versions of the sine and exponential functions, which operate on arrays (the math module versions operate only on scalars): " ] }, { "cell_type": "code", "collapsed": false, "input": [ "x=np.linspace(0,4,1000)\n", "f=np.sin(np.exp(x))\n", "plt.plot(x,f)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll also see later how to make animations with Matplotlib and IPython." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A note about speed\n", "\n", "Like MATLAB, Python is relatively slow -- especially when using **loops** with many iterations, nested loops, or deeply nested function calls. For the exercises in this course, Python will be sufficiently fast, but you should use numpy slicing whenever possible.\n", "\n", "We will often need to compute the difference of each pair of successive entries of an array. Here are two ways to do it. Which is faster? We can find out using another \"magic\" function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "N = 1000000\n", "a = np.random.rand(N)\n", "b = np.zeros(N-1)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "%%timeit\n", "for i in range(len(b)):\n", " b[i] = a[i+1]-a[i]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "%%timeit\n", "b = a[1:]-a[:-1]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For large-scale computational problems, you shouldn't use Python for any code that needs to be fast. Instead, you can write/generate code in C or Fortran and use weave, [cython](http://cython.org/), [f2py](http://www.f2py.com/), or other similar packages to automatically incorporate that code into your Python program. \n", "\n", "Toward the end of the course, we'll use the PyClaw package, which includes Fortran code and is built using f2py." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A warning about division" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Be careful when dividing numbers in Python. If you divide with integers, Python may not do what you expect. In scientific computing, you usually want to use floating point numbers." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print 1/2\n", "print 1.0/2.0" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Why use Python?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hopefully this brief adventure has convinced you that Python is a worthwhile programming language. Some of the reasons I chose Python as the language for this course (and other courses I teach) are:\n", "- Compared to lower-level languages like C, C++, and Fortran, Python code is easier to write and read (meaning fewer bugs!)\n", "- A huge number of available libraries means it is easy to get things done in Python without writing a lot of code yourself\n", "- Python is a general-purpose programming language, with features (like optional arguments with defaults) that lead to more elegant, maintainable code than what you can write with specialized languages like MATLAB.\n", "- Python is free and comes installed on most systems. You can run this whole course with only a web browser and access to the internet.\n", "- It's easy to incorporate code written in other languages into your Python programs.\n", "- It's often easy to [parallelize existing scientific codes](http://numerics.kaust.edu.sa/papers/pyclaw-sisc/pyclaw-sisc.html) using Python.\n", "\n", "For a longer discussion with links to some scientific studies of the value of Python, see [this blog post by Lorena Barba](http://lorenabarba.com/blog/why-i-push-for-python/)." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Further resources" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Python, numpy, and matplotlib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We've only scratched the surface of Python here. You'll learn more in the rest of the course -- and it's great to learn by doing. But if you want a really solid foundation, you may want to take a look at these:\n", "\n", "- http://www.learnpython.org/ (free)\n", "- http://www.codecademy.com/tracks/python (free)\n", "- http://www.diveintopython.net/ (free)\n", "- [A Primer on Scientific Programming with Python](http://www.amazon.com/Scientific-Programming-Computational-Science-Engineering/dp/3642302920) (book; not free)\n", "- [Matplotlib tutorial](http://www.loria.fr/~rougier/teaching/matplotlib/) (free)\n", "- [Numpy tutorial](http://wiki.scipy.org/Tentative_NumPy_Tutorial) (free)" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Other Python packages for science" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Besides numpy and matplotlib, there are many other useful Python packages for scientific computing. Here is a short list: \n", "\n", "- [scipy](http://www.scipy.org/) - optimization, ODEs, sparse linear algebra, etc.\n", "- [sympy](http://sympy.org/) - symbolic computation\n", "- Visualization: [yt](http://yt-project.org/), [vispy](http://vispy.org/), [Bokeh](http://bokeh.pydata.org/)\n", "- [pandas](http://pandas.pydata.org/) - data analysis\n", "- [mpi4py](http://mpi4py.scipy.org/) - parallel computing\n", "- [petsc4py](http://code.google.com/p/petsc4py/), [pytrilinos](http://trilinos.sandia.gov/packages/pytrilinos/) - Python bindings for the \"big 2\" parallel scientific libraries\n", "- [pyCUDA](http://mathema.tician.de/software/pycuda), [pyOpenCL](http://mathema.tician.de/software/pyopencl) - GPGPU computing\n", "- [FENiCS](http://fenicsproject.org/), [FiPy](http://www.ctcms.nist.gov/fipy/), [PyClaw](http://clawpack.github.io/doc/pyclaw/) - solve complicated PDEs with very sophisticated numerical methods\n", "- [networkX](http://networkx.github.com/), [pygraphviz](http://networkx.lanl.gov/pygraphviz/) - graphs\n", "- [astropy](http://www.astropy.org/), [biopython](http://biopython.org/wiki/Main_Page), [pychem](http://pychem.sourceforge.net/) - discipline-specific tools" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }