Skip to content

Commit e40797f

Browse files
author
Christian Jacobs
committed
Removed the exercises for lecture 5 into the lecture notes.
1 parent 4200407 commit e40797f

File tree

1 file changed

+248
-10
lines changed

1 file changed

+248
-10
lines changed

notebook/Lecture-5-Introduction-to-programming-for-geoscientists.ipynb

Lines changed: 248 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
{
22
"metadata": {
3-
"name": ""
3+
"name": "Lecture-5-Introduction-to-programming-for-geoscientists"
44
},
55
"nbformat": 3,
66
"nbformat_minor": 0,
77
"worksheets": [
88
{
99
"cells": [
1010
{
11-
"cell_type": "heading",
12-
"level": 1,
11+
"cell_type": "markdown",
1312
"metadata": {},
1413
"source": [
15-
"Introduction to programming for Geoscientists (through Python)"
14+
"#Introduction to programming for Geoscientists (through Python)\n",
15+
"###[Gerard Gorman](http://www.imperial.ac.uk/people/g.gorman), [Christian Jacobs](http://www.imperial.ac.uk/people/c.jacobs10)"
1616
]
1717
},
1818
{
@@ -21,13 +21,11 @@
2121
"source": [
2222
"#Lecture 5: Files, strings, and dictionaries\n",
2323
"\n",
24-
"[Gerard J. Gorman](http://www.imperial.ac.uk/people/g.gorman) <g.gorman@imperial.ac.uk>\n",
25-
"\n",
2624
"Learning objectives: You will learn how to:\n",
2725
"\n",
28-
"1. Read data in from a file\n",
29-
"2. Parse strings to extract specific data of interest.\n",
30-
"3. Use dictionaries to index data using any type of key."
26+
"* Read data in from a file\n",
27+
"* Parse strings to extract specific data of interest.\n",
28+
"* Use dictionaries to index data using any type of key."
3129
]
3230
},
3331
{
@@ -259,6 +257,99 @@
259257
"You will notice in the above example that we used the *split()* string member function. This is a very useful function for grabbing individual words on a line. When called without any arguments it assumes that the [delimiter](http://en.wikipedia.org/wiki/Delimiter) is a blank space. However, you can use this to split a string with any delimiter, *e.g.*, *line.split(';')*, *line.split(':')*."
260258
]
261259
},
260+
{
261+
"cell_type": "markdown",
262+
"metadata": {},
263+
"source": [
264+
"## <span style=\"color:blue\">Exercise 1: Read a two-column data file</span>\n",
265+
"The file *data/xy.dat* contains two columns of numbers, corresponding to *x* and *y* coordinates on a curve. The start of the file looks like this:\n",
266+
"\n",
267+
"-1.0000 -0.0000</br>\n",
268+
"-0.9933 -0.0087</br>\n",
269+
"-0.9867 -0.0179</br>\n",
270+
"-0.9800 -0.0274</br>\n",
271+
"-0.9733 -0.0374</br>\n",
272+
"\n",
273+
"Make a program that reads the first column into a list *x* and the second column into a list *y*. Then convert the lists to arrays, and plot the curve. Print out the maximum and minimum y coordinates. (Hint: Read the file line by line, split each line into words, convert to float, and append to *x* and *y*.)</br>"
274+
]
275+
},
276+
{
277+
"cell_type": "code",
278+
"collapsed": false,
279+
"input": [],
280+
"language": "python",
281+
"metadata": {},
282+
"outputs": []
283+
},
284+
{
285+
"cell_type": "markdown",
286+
"metadata": {},
287+
"source": [
288+
"## <span style=\"color:blue\">Exercise 2: Read a data file</span>\n",
289+
"The files data/density_water.dat and data/density_air.dat contain data about the density of water and air (respectively) for different temperatures. The data files have some comment lines starting with # and some lines are blank. The rest of the lines contain density data: the temperature in the first column and the corresponding density in the second column. The goal of this exercise is to read the data in such a file and plot the density versus the temperature as distinct (small) circles for each data point. Let the program take the name of the data file via raw_input. Apply the program to both files."
290+
]
291+
},
292+
{
293+
"cell_type": "code",
294+
"collapsed": false,
295+
"input": [],
296+
"language": "python",
297+
"metadata": {},
298+
"outputs": []
299+
},
300+
{
301+
"cell_type": "markdown",
302+
"metadata": {},
303+
"source": [
304+
"## <span style=\"color:blue\">Exercise 3: Read acceleration data and find velocities</span>\n",
305+
"A file data/acc.dat contains measurements $a_0, a_1, \\ldots, a_{n-1}$ of the acceleration of an object moving along a straight line. The measurement $a_k$ is taken at time point $t_k = k\\Delta t$, where $\\Delta t$ is the time spacing between the measurements. The purpose of the exercise is to load the acceleration data into a program and compute the velocity $v(t)$ of the object at some time $t$.\n",
306+
"\n",
307+
"In general, the acceleration $a(t)$ is related to the velocity $v(t)$ through $v^\\prime(t) = a(t)$. This means that\n",
308+
"\n",
309+
"$$\n",
310+
"v(t) = v(0) + \\int_0^t{a(\\tau)d\\tau}\n",
311+
"$$\n",
312+
"\n",
313+
"If $a(t)$ is only known at some discrete, equally spaced points in time, $a_0, \\ldots, a_{n-1}$ (which is the case in this exercise), we must compute the integral above numerically, for example by the Trapezoidal rule:\n",
314+
"\n",
315+
"$$\n",
316+
"v(t_k) \\approx \\Delta t \\left(\\frac{1}{2}a_0 + \\frac{1}{2}a_k + \\sum_{i=1}^{k-1}a_i \\right), \\ \\ 1 \\leq k \\leq n-1. \n",
317+
"$$\n",
318+
"\n",
319+
"We assume $v(0) = 0$ so that also $v_0 = 0$.\n",
320+
"Read the values $a_0, \\ldots, a_{n-1}$ from file into an array, plot the acceleration versus time, and use the Trapezoidal rule to compute one $v(t_k)$ value, where $\\Delta t$ and $k \\geq 1$ are specified using raw_input."
321+
]
322+
},
323+
{
324+
"cell_type": "code",
325+
"collapsed": false,
326+
"input": [],
327+
"language": "python",
328+
"metadata": {},
329+
"outputs": []
330+
},
331+
{
332+
"cell_type": "markdown",
333+
"metadata": {},
334+
"source": [
335+
"## <span style=\"color:blue\">Exercise 4: Read acceleration data and plot velocities</span>\n",
336+
"The task in this exercise is the same as the one above, except that we now want to compute $v(t_k)$ for all time points $t_k = k\\Delta t$ and plot the velocity versus time. Repeated use of the Trapezoidal rule for all $k$ values is very inefficient. A more efficient formula arises if we add the area of a new trapezoid to the previous integral:\n",
337+
"\n",
338+
"$$\n",
339+
"v(t_k) = v(t_{k-1}) + \\int_{t_{k-1}}^{t_k}a(\\tau)\\ d\\tau \\approx v(t_{k-1}) + \\Delta t \\frac{1}{2}\\left(a_{k-1} + a_k\\right), \n",
340+
"$$\n",
341+
"\n",
342+
"for $k = 1, 2, \\ldots, n-1$, while $v_0 = 0$. Use this formula to fill an array *v* with velocity values. Now only $\\Delta t$ is given on via raw_input, and the $a_0, \\ldots, a_{n-1}$ values must be read from file as in the previous exercise."
343+
]
344+
},
345+
{
346+
"cell_type": "code",
347+
"collapsed": false,
348+
"input": [],
349+
"language": "python",
350+
"metadata": {},
351+
"outputs": []
352+
},
262353
{
263354
"cell_type": "markdown",
264355
"metadata": {},
@@ -588,6 +679,90 @@
588679
],
589680
"prompt_number": 227
590681
},
682+
{
683+
"cell_type": "markdown",
684+
"metadata": {},
685+
"source": [
686+
"## <span style=\"color:blue\">Exercise 5: Make a dictionary from a table</span>\n",
687+
"The file *data/constants.txt* contains a table of the values and the dimensions of some fundamental constants from physics. We want to load this table into a dictionary *constants*, where the keys are the names of the constants. For example, *constants['gravitational constant']* holds the value of the gravitational constant (6.67259 $\\times$ 10$^{-11}$) in Newton's law of gravitation. Make a function that that reads and interprets the text in the file, and thereafter returns the dictionary."
688+
]
689+
},
690+
{
691+
"cell_type": "code",
692+
"collapsed": false,
693+
"input": [],
694+
"language": "python",
695+
"metadata": {},
696+
"outputs": []
697+
},
698+
{
699+
"cell_type": "markdown",
700+
"metadata": {},
701+
"source": [
702+
"## <span style=\"color:blue\">Exercise 6: Explore syntax differences: lists vs. dictionaries</span>\n",
703+
"Consider this code:"
704+
]
705+
},
706+
{
707+
"cell_type": "code",
708+
"collapsed": false,
709+
"input": [
710+
"t1 = {}\n",
711+
"t1[0] = -5\n",
712+
"t1[1] = 10.5"
713+
],
714+
"language": "python",
715+
"metadata": {},
716+
"outputs": []
717+
},
718+
{
719+
"cell_type": "markdown",
720+
"metadata": {},
721+
"source": [
722+
"Explain why the lines above work fine while the ones below do not:"
723+
]
724+
},
725+
{
726+
"cell_type": "code",
727+
"collapsed": false,
728+
"input": [
729+
"t2 = []\n",
730+
"t2[0] = -5\n",
731+
"t2[1] = 10.5"
732+
],
733+
"language": "python",
734+
"metadata": {},
735+
"outputs": []
736+
},
737+
{
738+
"cell_type": "markdown",
739+
"metadata": {},
740+
"source": [
741+
"What must be done in the last code snippet to make it work properly?"
742+
]
743+
},
744+
{
745+
"cell_type": "markdown",
746+
"metadata": {},
747+
"source": [
748+
"## <span style=\"color:blue\">Exercise 7: Compute the area of a triangle</span>\n",
749+
"An arbitrary triangle can be described by the coordinates of its three vertices: $(x_1, y_1), (x_2, y_2), (x_3, y_3)$, numbered in a counterclockwise direction. The area of the triangle is given by the formula:\n",
750+
"\n",
751+
"$A = \\frac{1}{2}|x_2y_3 - x_3y_2 - x_1y_3 + x_3y_1 + x_1y_2 - x_2y_1|.$\n",
752+
"\n",
753+
"Write a function *area(vertices)* that returns the area of a triangle whose vertices are specified by the argument vertices, which is a nested list of the vertex coordinates. For example, vertices can be [[0,0], [1,0], [0,2]] if the three corners of the triangle have coordinates (0, 0), (1, 0), and (0, 2).\n",
754+
"\n",
755+
"Then, assume that the vertices of the triangle are stored in a dictionary and not a list. The keys in the dictionary correspond to the vertex number (1, 2, or 3) while the values are 2-tuples with the x and y coordinates of the vertex. For example, in a triangle with vertices (0, 0), (1, 0), and (0, 2) the vertices argument becomes:"
756+
]
757+
},
758+
{
759+
"cell_type": "code",
760+
"collapsed": false,
761+
"input": [],
762+
"language": "python",
763+
"metadata": {},
764+
"outputs": []
765+
},
591766
{
592767
"cell_type": "markdown",
593768
"metadata": {},
@@ -1140,12 +1315,57 @@
11401315
],
11411316
"prompt_number": 255
11421317
},
1318+
{
1319+
"cell_type": "markdown",
1320+
"metadata": {},
1321+
"source": [
1322+
"## <span style=\"color:blue\">Exercise 8: Improve a program</span>\n",
1323+
"The file *data/densities.dat* contains a table of densities of various substances measured in g/cm$^3$. The following program reads the data in this file and produces a dictionary whose keys are the names of substances, and the values are the corresponding densities."
1324+
]
1325+
},
1326+
{
1327+
"cell_type": "code",
1328+
"collapsed": false,
1329+
"input": [
1330+
"def read_densities(filename):\n",
1331+
" infile = open(filename, 'r')\n",
1332+
" densities = {}\n",
1333+
" for line in infile:\n",
1334+
" words = line.split()\n",
1335+
" density = float(words[-1])\n",
1336+
" \n",
1337+
" if len(words[:-1]) == 2:\n",
1338+
" substance = words[0] + ' ' + words[1]\n",
1339+
" else:\n",
1340+
" substance = words[0]\n",
1341+
" \n",
1342+
" densities[substance] = density\n",
1343+
" \n",
1344+
" infile.close()\n",
1345+
" return densities\n",
1346+
"\n",
1347+
"densities = read_densities('densities.dat')"
1348+
],
1349+
"language": "python",
1350+
"metadata": {},
1351+
"outputs": []
1352+
},
1353+
{
1354+
"cell_type": "markdown",
1355+
"metadata": {},
1356+
"source": [
1357+
"One problem we face when implementing the program above is that the name of the substance can contain one or two words, and maybe more words in a more comprehensive table. The purpose of this exercise is to use string operations to shorten the code and make it more general. Implement the following two methods in separate functions in the same program, and control that they give the same result.\n",
1358+
"\n",
1359+
"1. Let *substance* consist of all the words but the last, using the join method in string objects to combine the words.\n",
1360+
"2. Observe that all the densities start in the same column file and use substrings to divide line into two parts. (Hint: Remember to strip the first part such that, e.g., the density of ice is obtained as *densities['ice']* and not *densities['ice ']*.)"
1361+
]
1362+
},
11431363
{
11441364
"cell_type": "markdown",
11451365
"metadata": {},
11461366
"source": [
11471367
"##File writing\n",
1148-
"\ufffc\ufffc\ufffc\ufffc\ufffcWriting a file in Python is simple. You just collect the text you want to write in one or more strings and, for each string, use a statement along the lines of"
1368+
"Writing a file in Python is simple. You just collect the text you want to write in one or more strings and, for each string, use a statement along the lines of"
11491369
]
11501370
},
11511371
{
@@ -1205,6 +1425,24 @@
12051425
"source": [
12061426
"And that's it - run the above cell and take a look at the file that was generated in the folder you run IPython from."
12071427
]
1428+
},
1429+
{
1430+
"cell_type": "markdown",
1431+
"metadata": {},
1432+
"source": [
1433+
"## <span style=\"color:blue\">Exercise 9: Write function data to a file</span>\n",
1434+
"We want to dump $x$ and $f(x)$ values to a file named function_data.dat, where the $x$ values appear in the first column and the $f(x)$ values appear in the second. Choose $n$ equally spaced $x$ values in the interval [-4, 4]. Here, the function $f(x)$ is given by:\n",
1435+
"\n",
1436+
"$f(x) = \\frac{1}{\\sqrt{2\\pi}}\\exp(-0.5x^2)$"
1437+
]
1438+
},
1439+
{
1440+
"cell_type": "code",
1441+
"collapsed": false,
1442+
"input": [],
1443+
"language": "python",
1444+
"metadata": {},
1445+
"outputs": []
12081446
}
12091447
],
12101448
"metadata": {}

0 commit comments

Comments
 (0)