#!/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!"