#!/usr/bin/env python # coding: utf-8 #
#

# # #

# #

IRIS-EarthScope Short Course

#
Bloomington/IN, August 2015
#
#

Python/ObsPy Introduction

#
# #
#
image by Matthias Meschede
# ## How to Use Python # # There are different ways to use Python.. # * 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` # * easy to give the file to somebody else, basic human readable text file # * use the interactive IPython shell # * code can be executed line-by-line, results immediately visible # * quick interactive playing around / prototyping (tab completion etc.) # * in browser using the IPython/Jupyter notebook # * code can be nicely mixed with images, formulas, text, exercise instructions.. good for teaching! # * current state of variables can be a bit confusing sometimes # # ## The IPython/Jupyter Notebook # # 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. # # Most Important: # - on previously assigned variables (after the cell was executed), use tab completion for introspection! # # # In[ ]: x = "Hello World!" # In[ ]: x. # * use question mark for help on functions/methods # In[ ]: get_ipython().run_line_magic('pinfo', 'x.lower') # #### Quick Toolbar Reference # # # # # * `Shift + Enter`: Execute cell and jump to the next cell # * `Ctrl + Enter`: Execute cell and don't jump to the next cell # * If code execution is not responding anymore: *Restart kernel* (cache of previously assigned variables gets emptied!) # # # --- # # # First things first: you will find these six lines in every notebook. **Always execute them!** They do three things: # * Make plots appear in the browser (otherwise a window pops up) # * Printing things works like this: # # ```python # print("Hello") # ``` # # * Plots look quite a bit nicer (this is optional). # # This essentially makes the notebooks work under Python 2 and Python 3. # In[ ]: get_ipython().run_line_magic('matplotlib', 'inline') from __future__ import print_function import numpy as np import matplotlib.pyplot as plt plt.style.use('ggplot') plt.rcParams['figure.figsize'] = 12, 8 # --- # # ## Useful Links # # 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. # # If you have any question regarding some specific Python functionality you can consult the official [Python documentation](https://docs.python.org/). # # Furthermore a large number of Python tutorials, introduction, and books are available online. Here are some examples for those interested in learning more. # # * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com/) # * [Dive Into Python 3](http://www.diveintopython3.net/) # * [The Official Python Tutorial](https://docs.python.org/3/tutorial/index.html) # * [Think Python Book, 2nd Edition](http://www.greenteapress.com/thinkpython2/) # # Some people might be used to Matlab - this helps: # # * [NumPy for Matlab Users Introdution](https://wiki.scipy.org/NumPy_for_Matlab_Users) # * [NumPy for Matlab Users Cheatsheet](http://mathesaurus.sourceforge.net/matlab-numpy.html) # # # Additionally there is an abundance of resources introducing and teaching parts of the scientific Python ecosystem. # # * [NumPy Tutorial](https://wiki.scipy.org/Tentative_NumPy_Tutorial) # * [Python Scientific Lecture Notes](https://scipy-lectures.github.io/): Introduces the basics of scientific Python with lots of examples. # * [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. # * [Another NumPy Tutorial](https://www.loria.fr/~rougier/teaching/numpy/numpy.html), [Matplotlib Tutorial](https://www.loria.fr/~rougier/teaching/matplotlib/matplotlib.html) # # 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: # # * [Matplotlib Gallery](http://matplotlib.org/gallery.html) # * [ObsPy Gallery](https://docs.obspy.org/gallery.html) # * [Basemap Gallery](http://matplotlib.org/basemap/users/examples.html) # # # --- # # A) Python Crash Course # # This course is fairly non-interactive and just serves to get you up to speed. Nonetheless feel free to play around. # # ### 1. Numbers # # Python is dynamically typed and assigning something to a variable will give it that type. # In[ ]: # Three basic types of numbers a = 1 # Integers b = 2.0 # Floating Point Numbers c = 3.0 + 4j # Complex Numbers # Arithmetics work more or less as expected d = a + b # (int + float = float) e = c ** 2 # c to the second power # ### 2. Boolean values # In[ ]: current_state = True next_state = not current_state print(next_state) print(b > 100) # ### 3. Strings # In[ ]: # You can use single or double quotes to create strings. location = "Bloomington" # Concatenate strings with plus. where_am_i = "I am in " + location # Print things with the print() function. print(location) print(where_am_i) # In Python everything is an object.. # Strings have a lot of attached methods for common manipulations. print(location.upper()) # Access single items with square bracket. Negative indices are from the back. print(location[0], location[-1]) # ### 4. Lists # In[ ]: # Lists use square brackets and are simple ordered collections of items (of arbitrary type). everything = [a, c, location, 1, 2, 3, "hello"] print(everything) # Access elements with the same slicing/indexing notation as strings. # Note that Python indices are zero based! print(everything[0]) print(everything[:3]) print(everything[2:-2]) print(everything[-3:]) # Append things with the append method. # (Other helper methods are available for lists as well) everything.append("you") print(everything) # ### 5. Dictionaries # In[ ]: # Dictionaries have named fields and no inherent order. As is # the case with lists, they can contain items of any type. information = { "name": "John", "surname": "Doe", "age": 48, "kids": ["Johnnie", "Janie"] } # Acccess items by using the key in square brackets. print(information["kids"]) # Add new things by just assigning to a key. print(information) information["music"] = "jazz" print(information) # ### 6. Functions # In[ ]: # Functions are defined using the "def" keyword. # The body of the function is the indented block following the # call syntax definition and usually ends with a "return" statement. def do_stuff(a, b): return a * b # Functions calls are denoted by round brackets. print(do_stuff(2, 3)) # In[ ]: # Arguments to functions can have a default value.. def traveltime(distance, speed=80.0): return distance / speed # If not specified otherwise, the default value is used.. print(traveltime(1000)) # ### 7. Imports # # 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. # In[ ]: # Import the math module, and use it's contents with the dot accessor. import math a = math.cos(4 * math.pi) # You can also selectively import specific things. from math import pi b = 2.0 * pi # And even rename them if you don't like their name. from math import cos as cosine c = cosine(b) print(c) # ### 8. Control Flow # # 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! # In[ ]: temp = ["a", "b", "c"] # The typical Python loop is a for-each loop, e.g. for item in temp: print(item) # In[ ]: # Useful to know is the range() function. for i in range(5): print(i) # In[ ]: # If/else works as expected. age = 77 if age >= 0 and age < 10: print("Younger than ten.") elif age >= 10: print("Older than ten.") else: print("wait.. what??") # In[ ]: # List comprehensions are a nice way to write compact loops. a = list(range(10)) print(a) b = [i ** 2 for i in a] print(b) # Equivalent for-loop to generate b. b = [] for i in a: b.append(i ** 2) print(b) # In[ ]: # while-loops get executed over and over again, # as long as the condition evaluates to "True".. happy = False candies = 0 print(candies) while not happy: candies += 1 if candies >= 100: happy = True print(candies) # ### 9. Exceptions # # 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. # In[ ]: for earthquake in my_earthquake_list: try: download_data(event) except: print("Warning: Failed to download data for event:", event) continue # But beware, just catching any type of Exception can mask errors in the code: # In[ ]: for earthquake in my_earthquake_list: try: donwload_daat(event) except: print("Warning: Failed to download data for event:", event) continue # ### 10. NumPy # # 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). # In[ ]: import numpy as np # Create a large array with with 1 million samples, equally spaced from 0 to 100 x = np.linspace(0, 100, 1E6) # Most operations work per-element. y = x ** 2 # Uses C and Fortran under the hood for speed. print(y.sum()) # ### 11. Plotting # # Plotting is (most often) done using matplotlib. It has an interface that essentially works like Matlab. # In[ ]: import matplotlib.pyplot as plt x = np.linspace(0, 2 * np.pi, 2000) y = np.sin(x) plt.plot(x, y, color="green", label="sine wave") plt.legend() plt.ylim(-1.1, 1.1) plt.show() # ## Exercises # # #### Functions, NumPy, and Matplotlib # # a) Write a function that takes a NumPy array `x` and three float values `a`, `b`, and `c` as arguments and returns # # $$ # f(x) = a x^2 + b x + c # $$ # # b) Use the function and plot its graph using matplotlib, for an arbitrary choice of parameters for x values between -3 and +3. # In[ ]: # #### 99 Bottles of Beer # # *(stolen from http://www.ling.gu.se/~lager/python_exercises.html)* # # # "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: # # ``` # 99 bottles of beer on the wall, 99 bottles of beer. # Take one down, pass it around, 98 bottles of beer on the wall. # ``` # # The same verse is repeated, each time with one fewer bottle. The song is completed when the singer or singers reach zero. # # Your task here is to write a Python program capable of generating all the verses of the song. # # In[ ]: # #### Caesar Cipher # # *(stolen from http://www.ling.gu.se/~lager/python_exercises.html)* # # 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: # # ```python # key = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', # 'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', # 'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k', # 'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', # 'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', # 'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', # 'W':'J', 'X':'K', 'Y':'L', 'Z':'M'} # ``` # # 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: # # ``` # Pnrfne pvcure? V zhpu cersre Pnrfne fnynq! # ``` # # **BONUS:** Write an encoder! # In[ ]: key = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', 'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', 'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k', 'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', 'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', 'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', 'W':'J', 'X':'K', 'Y':'L', 'Z':'M'} message = "Pnrfne pvcure? V zhpu cersre Pnrfne fnynq!"