Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Open In Colab Open In Kaggle

Exercise 1: Name your measurements

Create scientifically named variables for a single observation at a river gauge: a discharge of 4.7 m³ s⁻¹, a station name of your choice, an integer count of 24 hourly samples, and a boolean flag for whether discharge exceeds 5 m³ s⁻¹. Print each value together with its type.

Exercise 2: Unit conversions

A temperature is recorded as 18.5 °C. Compute it in kelvin and in degrees Fahrenheit. Separately, a discharge of 4.7 m³ s⁻¹ drains a catchment of area 250 km². Express the specific discharge in mm per day (use: 1 m³ s⁻¹ spread over 1 km² for one day equals 86.4 mm). Print each result to two decimals with an f-string.

Exercise 3: Operator families and a quality flag

Three daily readings arrive from a station: reading_1_celsius = 18.2, reading_2_celsius = -300.0, and reading_3_celsius = None (the sensor reported nothing).

  1. Build a boolean is_plausible that is True when the first reading is above absolute zero and below 60 °C.

  2. Build is_implausible for the second reading: apply the same test as in step 1, and negate it with not.

  3. Use is to check whether the third reading is missing.

  4. Starting from n_valid = 0, use += twice to count how many of the first two readings pass the step 1 test. Note that int() casts True to 1 and False to 0.

  5. The sensor is rated for -40 °C to 60 °C, both bounds included. Use >= and <= to test whether the first reading lies in that range, and != to check that the first two readings differ.

Exercise 4: Parse a record

A logger emits records like "2024-01-15 , JUNGFRAUJOCH , -2.3 , degC". Extract the date string, the station name in title case, the numeric value as a float, and the unit as written, then print them. Then print the station name in lower case as well, the form you would use in a file name.

Exercise 5: Indexing and slicing a record

Weather records often arrive in a fixed shape, where each field always occupies the same positions. Given

record = "ALO01.03.2022"

the first three characters are the station code and the rest is a date as dd.mm.yyyy.

  1. Using only indexing and slicing (no .split()), extract the station code, the day, the month, and the four-digit year, and print them.

  2. Now extract the month a second way, using .split(".") on the date part, and use == to confirm you get the same answer.

  3. In a comment, say which of the two approaches you would trust to extract the month from a record where the station code can be two or four characters long, and why.

Exercise 6: Formatting π to the precision you choose

math.pi holds π to about 16 significant digits, and an f-string format specifier prints it to as many decimals as you ask for.

  1. Create the _files folder if it does not exist, as in the lecture, then write the sentence "This is my first I/O exercise." to _files/pi_exercise.txt with mode "w".

  2. Reopen the file with mode "a" and append three more lines: one built with an f-string that reports math.pi to four decimal places, and two lines of your own choosing.

  3. Read the file back with .readlines() and print its full contents.

  4. Change the format specifier to two decimals instead of four, rerun, and confirm the printed value now rounds to 3.14.

Exercise 7: Round-trip through a file, with an append

Write the Jungfraujoch week from the lecture — the daily maximum temperatures -8.4, -8.9, -9.2, -9.0, -9.5 (°C) — to _files/jfj_week.txt, one value per line, using pathlib and a with block. Create the _files folder first if it does not exist; do not rely on Exercise 6 having made it.

  1. Write the five values with mode "w", one .write() call per value.

  2. Reopen the file with mode "a" and append the last two days of the week, -7.8 and -6.1.

  3. Read the file back with .readlines(), cast each of the seven lines to float by name, and compute the mean by summing the seven values by hand with + and dividing by len(). Print it to two decimals.

Going deeper (optional)

Exercise 8: Same seven values, same mean?

Adding the same floats in a different order does not have to give exactly the same result, because each + rounds its result to the nearest float. This exercise uses math.isclose from the going-deeper box on floating-point precision.

  1. Compute the mean of the Jungfraujoch week — -8.4, -8.9, -9.2, -9.0, -9.5, -7.8, -6.1 — by adding the values in that order and dividing by 7.

  2. Compute it again, adding the same seven values in reverse order.

  3. Compare the two means with ==, and print the result.

  4. Compare the same two means with math.isclose, and print the result.

  5. In a comment, say which of the two comparisons you would put in a script that checks whether two calculations of the same quantity agree, and why.

Exercise 9: A year of station data

The exercises so far used values typed by hand. This one uses a real record: daily maximum temperatures for 2022 from the automated weather station at Independence Municipal Airport, Iowa, US, station code IIB. The file has one row for each of the 365 days, but 16 of them, from 25 October to 9 November, have no temperature value. Work through the steps in order, since each step reuses variables from the one before. The same file returns in 1.2, where you turn the whole year into a monthly summary.

The data has three columns: the station code, the day as dd.mm.yy, and the daily maximum temperature in degrees Fahrenheit. Converting to SI units is part of the job.

data cached at: /home/runner/.cache/mlees/station_iib_daily_max_temp_2022.csv

Step 1. Open the file with a with block in read mode and read all its lines with .readlines().

Print how many lines the file has, then print the first three lines exactly as they come off disk.

Step 2. Look at the first record (the second line of the file). Split it on the separator and print the resulting list. Then print the type of each of the three fields.

Answer in a comment: are the temperatures numbers at this point?

Step 3. Take that same first record and turn it into three properly typed, well-named variables: the station code as text, the day as text, and the maximum temperature as a float in degrees Celsius. Print them in one line with an f-string, showing the temperature to one decimal with its unit.

Recall that °C = (°F − 32) × 5/9.

Step 4. Now do the same for the second record (the third line of the file), so you have two days side by side.

  1. Ask which of the two days was warmer by comparing the two raw temperature fields, before any casting.

  2. Ask the same question again, this time comparing the two values after casting to float.

  3. The two answers disagree. In a comment, explain which one is right and why the other one is wrong.

Step 5. Write your own summary file, in SI units this time.

  1. Build a path to _files/station_iib_summary.csv with pathlib.Path, creating the folder if it does not exist.

  2. In one with block in mode "w", write a header line station,day,max_temp_celsius and then one line for each of the two days you converted, with the temperature formatted to one decimal.

  3. Reopen the file in mode "r", read it back with .read(), and print it.