<jupyter_start><jupyter_text>2.18 Programming for Geoscientists class test - 14:00-16:00 18th December 2014  Test instructions* This test contains **5** questions each of which should be answered.* Write your program in a Python cell just under each question.* You can write an explanation of your solution as comments in your code.* In each case your solution program must fulfil all of the instructions - please check the instructions carefully and double check that your program fulfils all of the given instructions.* Save your work regularly.* At the end of the test you should email your IPython notebook document (i.e. this document) to [<NAME>](http://www.imperial.ac.uk/people/g.gorman) at <EMAIL> **Question 1** * Correct the 5 errors in the following program.* In each case add a comment explaining the error and the fix.* To verify your answer remember that $sin ^2( x ) + cos ^2( x ) = 1$.<jupyter_code>from math import sin, cos
x = pi /4
1_val = sin^2( x ) + cos^2( x )
print 1_VAL
# Fix 1: pi needs to be imported from the math module before it can be used in the line below.
from math import sin, cos, pi

x = pi /4

# Fix 2: 1_val is not a valid variable name - it cannot start with a number
# Fix 3: raising something to a power is done using **, not ^
# Fix 4: when calling sin or cos, it's name must be followed by the arguments in brackets. If we want to represent $\sin^2(x)$
# in Python, we have to write it like $\sin(x)^2$, i.e. sin(x)**2.
val = sin(x)**2 + cos(x)**2

# Fix 5: variable names are case-sensitive in Python. val is not the same as VAL.
print val<jupyter_output>1.0<jupyter_text>**Question 2*** Create a python list containing 101 evenly spaced values between -1.0 and 1.0.* Show how this could be more efficently done using NumPy.* Print out the values using a formatted print statement.<jupyter_code>n = 101 # The number of values
start = -1.0
end = 1.0
dx = (end-start)/(n-1) # The distance between each value

values = [start + i*dx for i in range(n)]
print values

from numpy import linspace
values_numpy = linspace(start, end, n)

for v in values_numpy:
    print "%.2f" % (v)<jupyter_output>[-1.0, -0.98, -0.96, -0.94, -0.92, -0.9, -0.88, -0.86, -0.84, -0.8200000000000001, -0.8, -0.78, -0.76, -0.74, -0.72, -0.7, -0.6799999999999999, -0.6599999999999999, -0.64, -0.62, -0.6, -0.5800000000000001, -0.56, -0.54, -0.52, -0.5, -0.48, -0.45999999999999996, -0.43999999999999995, -0.42000000000000004, -0.4, -0.38, -0.36, -0.33999999999999997, -0.31999999999999995, -0.29999999999999993, -0.28, -0.26, -0.24, -0.21999999999999997, -0.19999999999999996, -0.17999999999999994, -0.16000000000000003, -0.14, -0.12, -0.09999999999999998, -0.07999999999999996, -0.05999999999999994, -0.040000000000000036, -0.020000000000000018, 0.0, 0.020000000000000018, 0.040000000000000036, 0.06000000000000005, 0.08000000000000007, 0.10000000000000009, 0.1200000000000001, 0.14000000000000012, 0.15999999999999992, 0.17999999999999994, 0.19999999999999996, 0.21999999999999997, 0.24, 0.26, 0.28, 0.30000000000000004, 0.32000000000000006, 0.3400000000000001, 0.3600000000000001, 0.3800000000000001, 0.40000000000000[...]<jupyter_text>**Question 3*** a. Write a python function that evaluates the equation below for input variables $x$ and $t$: $$f(x, t) = e^{-(x-3t)^2} \sin \left( 3\pi \left( x-t \right) \right)$$* b. Generate an array of $x$ values in the range $[-3.0, 10]$.* c. Using this array of x values, plot the function for $t=0.0$, $t=1.0$ and $t=2.0$.<jupyter_code>from numpy import *
from pylab import *
%pylab inline
def f(x, t):
    return exp(-(x-3*t)**2)*sin(3*pi*(x-t))

n = 1000
xarray = linspace(-3, 10, n)

for t in [0, 1, 2]:
    plot(xarray, f(xarray, t), label=r"$t$ = %.1f" % (t))
xlabel(r"$x$")
ylabel(r"$f(x,t)$")
legend(loc="best")
show()<jupyter_output>Populating the interactive namespace from numpy and matplotlib<jupyter_text>**Question 4*** Write a program to read the data file *seismic.dat* and store the magnitude of the earthquakes (*i.e.* the last column) in an numpy array.* How many earthquakes are there above magnitude 6.0?<jupyter_code>from numpy import *
f = open("seismic.dat", "r")

magnitude = []
for line in f:
    s = line.split()
    magnitude.append(float(s[-1])) # The last column is the "magnitude"
magnitude = array(magnitude)

f.close()

print magnitude

count = 0
for m in magnitude:
    if m > 6.0:
        count += 1
print "There are %d earthquakes above magnitude 6.0" % (count)<jupyter_output>[ 6.6  6.1  5.2  5.   5.1  7.3  5.2  5.4  5.4  5.7  5.2  5.6  7.6  5.7  5.4
  5.4  5.5  5.2  6.1  6.1  6.2  6.   5.2  5.6  5.1  5.5  5.2  5.2  6.7  5.5
  6.5  5.6  6.   5.7  6.3  5.5  5.5  5.6  6.4  5.2  5.5  5.4  5.7  5.8  5.3
  5.4  5.6  5.3  5.6  5.5  5.7  5.9  5.1  5.7  7.   6.4  5.6  5.2  6.1  6.7
  5.9  5.4  5.9  5.6  5.8  6.1  5.   5.3  5.4  5.2  5.2  5.9  5.4  5.2  5.7
  6.1  5.6  5.3  5.3  6.1  5.4  5.3  5.5  5.4  5.5  5.8  5.4  5.1  5.3  5.2
  7.2  5.4  5.5  5.   5.   5.6  6.4  5.2  7.1  5.2  5.1  5.3  5.1  5.4  5.2
  4.9  5.4  5.   5.1  5.4  5.1  5.2  5.3  5.   5.1  7.5  6.6  5.1  5.1  5.1
  5.3  5.5  6.8  6.1  5.   5.3  5.3  6.6  5.6  5.9  5.2  5.4  5.3  5.1  5.1
  5.1  4.9  7.8  5.4  5.1  5.8  5.2  5.1  5.5  5.3  5.   6.1  5.   5.2  5.1
  5.3  5.6  5.3  5.   5.2  7.   4.8  4.9  5.   5.   5.   5.6  6.1  5.5  5.6
  4.9  5.   5.   5.1  5.2  6.   4.9  5.2  5.6  5.5  4.8  5.2  5.7  5.4  5.8
  4.9  5.2  4.9  6.   5.2  5.4  4.9  5.1  6.3  5.   5.   5.7  4.9  6.4  5.5
  5.7  6.5  [...]<jupyter_text>**Question 5** The file *human_evolution.txt* holds information about various human species and their hight, weight, and brain volume. * Write a program that reads this file and stores the data in a python dictionary humans.* The dictionary key should correspond to the specie name (e.g., “homo erectus”), and the value should be a list containing the corresponding data. For example, humans["<NAME>"] should give ["2.2 - 1.6", "1.0 - 1.5", "33 - 55", "660"].* Write out the humans dictionary in a formatted tabular form.<jupyter_code>f = open("human_evolution.txt", "r")

humans = {}

for line in f:
    # Ignore lines that don't start with "H."
    if(line[0:2] != "H."):
        continue
    
    # Get each column and strip out leading and trailing whitespace
    name = line[0:21].strip()
    lived = line[21:37].strip()
    height = line[37:50].strip()
    mass = line[50:62].strip()
    brain_volume = line[62:].strip()
    
    # Add to dictionary
    humans[name] = [lived, height, mass, brain_volume]
f.close()

# Test
print humans["H. habilis"]

print "%25s %25s %25s %25s %25s" % ("Species", "Lived when (M. years)", "Adult height (m)", "Adult mass (kg)", "Brain volume (cm**3)")
for human in humans:
    data = humans[human]
    print "%25s %25s %25s %25s %25s" % (human, data[0], data[1], data[2], data[3])<jupyter_output>['2.2 - 1.6', '1.0 - 1.5', '33 - 55', '660']
                  Species     Lived when (M. years)          Adult height (m)           Adult mass (kg)      Brain volume (cm**3)
      H. neanderthalensis               0.35 - 0.03                       1.6                   55 - 70               1200 - 1700
       H. sapiens sapiens             0.2 - present                 1.4 - 1.9                  50 - 100               1000 - 1850
       H. heidelbergensis                0.6 - 0.35                       1.8                        60               1100 - 1400
               H. erectus                 1.4 - 0.2                       1.8                        60 850 (early) - 1100 (late)
          H. floresiensis              0.10 - 0.012                       1.0                        25                       400
              H. ergaster                 1.9 - 1.4                       1.9                                           700 - 850
               H. habilis                 2.2[...]
{'fraction_non_alphanumeric': 0.14025012761613068, 'fraction_numerical': 0.1762378764675855, 'mean_word_length': 2.143602085840353, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 36, 'word_list_counts': {'cursed_substrings.json': 25, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '582805', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 3729, 'n_tokens_neox': 3023, 'n_words': 1012, 'path': 'notebook/python_class_test_2014_solutions.ipynb', 'repo_name': 'navjotk/test', 'size': '7866'}