{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

\n", "\n", "\n", "

\n", "\n", "

IRIS-EarthScope Short Course

\n", "
Bloomington/IN, August 2015
\n", "
\n", "

Python/ObsPy Introduction

\n", "
\n", "\n", "
\n", "
image by Matthias Meschede
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## How to Use Python\n", "\n", "There are different ways to use Python..\n", " * write a `my_program.py` Python file (e.g. using a text editor of choice, or an IDE), run the file with `$ python my_program.py`\n", " * easy to give the file to somebody else, basic human readable text file\n", " * use the interactive IPython shell\n", " * code can be executed line-by-line, results immediately visible\n", " * quick interactive playing around / prototyping (tab completion etc.)\n", " * in browser using the IPython/Jupyter notebook\n", " * code can be nicely mixed with images, formulas, text, exercise instructions.. good for teaching!\n", " * current state of variables can be a bit confusing sometimes\n", "\n", "## The IPython/Jupyter Notebook\n", "\n", "The [IPython/Jupyter notebook](http://www.nature.com/news/interactive-notebooks-sharing-the-code-1.16261) is a good way to combine text/formulas/images/diagrams with executable Python code cells, making it ideal for teaching Python tutorials.\n", "\n", "Most Important:\n", " - on previously assigned variables (after the cell was executed), use tab completion for introspection!\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = \"Hello World!\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " * use question mark for help on functions/methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x.lower?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Quick Toolbar Reference\n", "\n", "\n", "\n", "\n", "* `Shift + Enter`: Execute cell and jump to the next cell\n", "* `Ctrl + Enter`: Execute cell and don't jump to the next cell\n", "* If code execution is not responding anymore: *Restart kernel* (cache of previously assigned variables gets emptied!)\n", "\n", "\n", "---\n", "\n", "\n", "First things first: you will find these six lines in every notebook. **Always execute them!** They do three things:\n", "* Make plots appear in the browser (otherwise a window pops up)\n", "* Printing things works like this: \n", "\n", "```python\n", "print(\"Hello\")\n", "```\n", "\n", "* Plots look quite a bit nicer (this is optional).\n", "\n", "This essentially makes the notebooks work under Python 2 and Python 3." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline\n", "from __future__ import print_function\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "plt.style.use('ggplot')\n", "plt.rcParams['figure.figsize'] = 12, 8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Useful Links\n", "\n", "Here is collection of resources to introduce you the scientific Python ecosystem. They cover a number of different packages and topics; way more than we will manage today.\n", "\n", "If you have any question regarding some specific Python functionality you can consult the official [Python documentation](https://docs.python.org/).\n", " \n", "Furthermore a large number of Python tutorials, introduction, and books are available online. Here are some examples for those interested in learning more.\n", " \n", "* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com/)\n", "* [Dive Into Python 3](http://www.diveintopython3.net/)\n", "* [The Official Python Tutorial](https://docs.python.org/3/tutorial/index.html)\n", "* [Think Python Book, 2nd Edition](http://www.greenteapress.com/thinkpython2/)\n", " \n", "Some people might be used to Matlab - this helps:\n", " \n", "* [NumPy for Matlab Users Introdution](https://wiki.scipy.org/NumPy_for_Matlab_Users)\n", "* [NumPy for Matlab Users Cheatsheet](http://mathesaurus.sourceforge.net/matlab-numpy.html)\n", " \n", " \n", "Additionally there is an abundance of resources introducing and teaching parts of the scientific Python ecosystem.\n", " \n", "* [NumPy Tutorial](https://wiki.scipy.org/Tentative_NumPy_Tutorial)\n", "* [Python Scientific Lecture Notes](https://scipy-lectures.github.io/): Introduces the basics of scientific Python with lots of examples.\n", "* [Python for Signal Processing](https://python-for-signal-processing.blogspot.de/): Free blog which is the basis of a proper book written on the subject.\n", "* [Another NumPy Tutorial](https://www.loria.fr/~rougier/teaching/numpy/numpy.html), [Matplotlib Tutorial](https://www.loria.fr/~rougier/teaching/matplotlib/matplotlib.html)\n", " \n", "If you need to create a plot in Python/ObsPy, the quickest way to success is to start from some example that is similar to what you want to achieve. These websites are good starting points:\n", " \n", "* [Matplotlib Gallery](http://matplotlib.org/gallery.html)\n", "* [ObsPy Gallery](https://docs.obspy.org/gallery.html)\n", "* [Basemap Gallery](http://matplotlib.org/basemap/users/examples.html)\n", "\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# A) Python Crash Course\n", "\n", "This course is fairly non-interactive and just serves to get you up to speed. Nonetheless feel free to play around.\n", "\n", "### 1. Numbers\n", "\n", "Python is dynamically typed and assigning something to a variable will give it that type." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Three basic types of numbers\n", "a = 1 # Integers\n", "b = 2.0 # Floating Point Numbers\n", "c = 3.0 + 4j # Complex Numbers\n", "\n", "# Arithmetics work more or less as expected\n", "d = a + b # (int + float = float)\n", "e = c ** 2 # c to the second power" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Boolean values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "current_state = True\n", "next_state = not current_state\n", "print(next_state)\n", "\n", "print(b > 100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3. Strings" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# You can use single or double quotes to create strings.\n", "location = \"Bloomington\"\n", "\n", "# Concatenate strings with plus.\n", "where_am_i = \"I am in \" + location\n", "\n", "# Print things with the print() function.\n", "print(location)\n", "print(where_am_i)\n", "\n", "# In Python everything is an object..\n", "# Strings have a lot of attached methods for common manipulations.\n", "print(location.upper())\n", "\n", "# Access single items with square bracket. Negative indices are from the back.\n", "print(location[0], location[-1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4. Lists" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Lists use square brackets and are simple ordered collections of items (of arbitrary type).\n", "everything = [a, c, location, 1, 2, 3, \"hello\"]\n", "print(everything)\n", "\n", "# Access elements with the same slicing/indexing notation as strings.\n", "# Note that Python indices are zero based!\n", "print(everything[0])\n", "print(everything[:3])\n", "print(everything[2:-2])\n", "print(everything[-3:])\n", "\n", "# Append things with the append method.\n", "# (Other helper methods are available for lists as well)\n", "everything.append(\"you\")\n", "print(everything)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5. Dictionaries" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Dictionaries have named fields and no inherent order. As is\n", "# the case with lists, they can contain items of any type.\n", "information = {\n", " \"name\": \"John\",\n", " \"surname\": \"Doe\",\n", " \"age\": 48,\n", " \"kids\": [\"Johnnie\", \"Janie\"]\n", "}\n", "\n", "# Acccess items by using the key in square brackets.\n", "print(information[\"kids\"])\n", "\n", "# Add new things by just assigning to a key.\n", "print(information)\n", "information[\"music\"] = \"jazz\"\n", "print(information)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### 6. Functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Functions are defined using the \"def\" keyword.\n", "# The body of the function is the indented block following the\n", "# call syntax definition and usually ends with a \"return\" statement.\n", "def do_stuff(a, b):\n", " return a * b\n", "\n", "# Functions calls are denoted by round brackets.\n", "print(do_stuff(2, 3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Arguments to functions can have a default value..\n", "def traveltime(distance, speed=80.0):\n", " return distance / speed\n", "\n", "# If not specified otherwise, the default value is used..\n", "print(traveltime(1000))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7. Imports\n", "\n", "To use functions and objects not part of the default namespace, you have to import them. You will have to do this a lot so its worth to learn how to do it." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Import the math module, and use it's contents with the dot accessor.\n", "import math\n", "\n", "a = math.cos(4 * math.pi)\n", "\n", "# You can also selectively import specific things.\n", "from math import pi\n", "\n", "b = 2.0 * pi\n", "\n", "# And even rename them if you don't like their name.\n", "from math import cos as cosine\n", "c = cosine(b)\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 8. Control Flow\n", "\n", "Loops and conditionals are needed for any non-trivial task. Please note that **whitespace matters in Python**. Everything that is indented at the same level is part of the same block!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "temp = [\"a\", \"b\", \"c\"]\n", "\n", "# The typical Python loop is a for-each loop, e.g.\n", "for item in temp:\n", " print(item)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Useful to know is the range() function.\n", "for i in range(5):\n", " print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# If/else works as expected.\n", "age = 77\n", "\n", "if age >= 0 and age < 10:\n", " print(\"Younger than ten.\")\n", "elif age >= 10:\n", " print(\"Older than ten.\")\n", "else:\n", " print(\"wait.. what??\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# List comprehensions are a nice way to write compact loops.\n", "\n", "a = list(range(10))\n", "print(a)\n", "b = [i ** 2 for i in a]\n", "print(b)\n", "\n", "# Equivalent for-loop to generate b.\n", "b = []\n", "for i in a:\n", " b.append(i ** 2)\n", "print(b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# while-loops get executed over and over again,\n", "# as long as the condition evaluates to \"True\"..\n", "\n", "happy = False\n", "candies = 0\n", "print(candies)\n", "\n", "while not happy:\n", " candies += 1\n", " if candies >= 100:\n", " happy = True\n", "\n", "print(candies)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 9. Exceptions\n", "\n", "In automated processing scripts, sometimes unexpected things happen at runtime and Python stops code execution by **raising an Exception** (think of it as an \"Error\"). Sometimes we want to continue the program, nevertheless." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "for earthquake in my_earthquake_list:\n", " try:\n", " download_data(event)\n", " except:\n", " print(\"Warning: Failed to download data for event:\", event)\n", " continue" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But beware, just catching any type of Exception can mask errors in the code:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "for earthquake in my_earthquake_list:\n", " try:\n", " donwload_daat(event)\n", " except:\n", " print(\"Warning: Failed to download data for event:\", event)\n", " continue" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 10. NumPy\n", "\n", "Large parts of the scientific Python ecosystem use NumPy. The heart of NumPy is the \"ndarray\" type (n-dimensional array, in our course usually 1-D arrays). Operations on NumPy arrays are both economical in memory use and computationally fast (internally computations are done in C)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "\n", "# Create a large array with with 1 million samples, equally spaced from 0 to 100\n", "x = np.linspace(0, 100, 1E6)\n", "\n", "# Most operations work per-element.\n", "y = x ** 2\n", "\n", "# Uses C and Fortran under the hood for speed.\n", "print(y.sum())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 11. Plotting\n", "\n", "Plotting is (most often) done using matplotlib. It has an interface that essentially works like Matlab." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "x = np.linspace(0, 2 * np.pi, 2000)\n", "y = np.sin(x)\n", "\n", "plt.plot(x, y, color=\"green\", label=\"sine wave\")\n", "plt.legend()\n", "plt.ylim(-1.1, 1.1)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercises\n", "\n", "#### Functions, NumPy, and Matplotlib\n", "\n", "a) Write a function that takes a NumPy array `x` and three float values `a`, `b`, and `c` as arguments and returns\n", "\n", "$$\n", "f(x) = a x^2 + b x + c\n", "$$\n", "\n", "b) Use the function and plot its graph using matplotlib, for an arbitrary choice of parameters for x values between -3 and +3." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 99 Bottles of Beer\n", "\n", "*(stolen from http://www.ling.gu.se/~lager/python_exercises.html)*\n", "\n", "\n", "\"99 Bottles of Beer\" is a traditional song in the United States and Canada. It is popular to sing on long trips, as it has a very repetitive format which is easy to memorize, and can take a long time to sing. The song's simple lyrics are as follows:\n", "\n", "```\n", "99 bottles of beer on the wall, 99 bottles of beer.\n", "Take one down, pass it around, 98 bottles of beer on the wall.\n", "```\n", "\n", "The same verse is repeated, each time with one fewer bottle. The song is completed when the singer or singers reach zero.\n", "\n", "Your task here is to write a Python program capable of generating all the verses of the song.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Caesar Cipher\n", "\n", "*(stolen from http://www.ling.gu.se/~lager/python_exercises.html)*\n", "\n", "In cryptography, a Caesar cipher is a very simple encryption techniques in which each letter in the plain text is replaced by a letter some fixed number of positions down the alphabet. For example, with a shift of 3, A would be replaced by D, B would become E, and so on. The method is named after Julius Caesar, who used it to communicate with his generals. ROT-13 (\"rotate by 13 places\") is a widely used example of a Caesar cipher where the shift is 13. In Python, the key for ROT-13 may be represented by means of the following dictionary:\n", "\n", "```python\n", "key = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', \n", " 'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', \n", " 'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k',\n", " 'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', \n", " 'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', \n", " 'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', \n", " 'W':'J', 'X':'K', 'Y':'L', 'Z':'M'}\n", "```\n", "\n", "Your task in this exercise is to implement an decoder of ROT-13. Once you're done, you will be able to read the following secret message:\n", "\n", "```\n", "Pnrfne pvcure? V zhpu cersre Pnrfne fnynq!\n", "```\n", "\n", "**BONUS:** Write an encoder!" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "key = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', \n", " 'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', \n", " 'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k',\n", " 'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', \n", " 'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', \n", " 'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', \n", " 'W':'J', 'X':'K', 'Y':'L', 'Z':'M'}\n", "\n", "message = \"Pnrfne pvcure? V zhpu cersre Pnrfne fnynq!\"\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }