9.1 Blizzard!

In this problem, you were to code a program that did the following:

  1. Open up stormtrack.txt (somehow) and iterate through each line of stormtrack.txt.
  2. Where a line (i.e., hour) met blizzard conditions5, note it down.
  3. If four consecutive lines met blizzard conditions, then have the program say that blizzard conditions were met during the day (and vice versa).

While prof. Marek used numpy for his solution, I did it using base Python - I suppose that for those who have trouble understanding prof. Marek’s code, that they could look at another way (i.e., my way) of tackling the problem!

Nonetheless, here is my code (note that the stormtrack.txt file was called storm.txt in my case - however, I still have the same data that you have):

blizzardHours = [] ; hasBlizzard = False

for hour, con in enumerate(open('storm.txt').readlines(), start = 1):
  if float(con.split()[0]) >= 30 and float(con.split()[1]) <= 0.5:
    blizzardHours.append(hour)

for i in range(len(blizzardHours) - 4):
  if sum(blizzardHours[i:i + 4]) == 2 * (2 * blizzardHours[i] + 3):
    hasBlizzard = True 
    break 

print("There is a blzzard!" if hasBlizzard else "There is NOT a blizzard!")

I will explain my code in the below bullet points:

  1. Creating two variables blizzardHours and hasBlizzard

    blizzardHours is a list that stores the hours of the day (i.e., the rows of storm.txt) that met blizzard conditions. hasBlizzard is a boolean variable that indicates whether there is a blizzard during the day’s data or not.

    In case you’re wondering, it really doesn’t matter if hasBlizzard is True or False for now. We will write code that changes the value of hasBlizzard later!

  2. Opening and iterating through storm.txt using Python’s open() and enumerate() functions

    The open() function grants Python access to a file. The .readlines() method returns every line in open('storm.txt') as a list - in essence, open('storm.txt').readlines() returns a multi-dimensional list that contains each line of data in storm.txt!

    In case you do not know or remember what enumerate() is, you can check out this section of the webpage for a succinct briefing. In any case, note the argument start = 1; all iterated indices will begin at 0 in enumerate() by default. However, you can specify the starting index too - granted, this isn’t strictly necessary, but since we will eventually store hour in blizzardHours, I think it helps to use 1-based indexing so that we don’t confuse ourselves later on!

  3. Splitting each line of data using .split(), converting the data into a float, and checking for blizzard conditions

    I then used the built-in .split() string method - .split() splits a string according to a pattern and returns a list of substrings. In this case, I chose to split each line of data by an empty space; I then converted the numbers in each line of data into a float (note that our data is still a string at this point) before checking them for blizzard conditions.

    If a line of data met blizzard conditions, I then appended the hour of the day (which is 1-indexed) to blizzardHours.

  4. Using arithmetic to check for a blizzard during the day

    In the final for loop, I then utilize a sliding-window approach to check if there is a blizzard in the day’s data. A day has a blizzard if its data has four or more consecutive hours that meet blizzard conditions.

    Hence, I think it is fitting to write code that checks for an arithmetic sequence in sublists of four elements. If you do not know or remember what an arithmetic sequence is, not to worry - I wrote a small section on what this is below!

    Nevertheless, if an arithmetic sequence of length 4 is found, then hasBlizzard is changed to True and the for loop terminates.

  5. Stating whether the day’s data has a blizzard or not

    This is where hasBlizzard is incredibly handy. If hasBlizzard is True, then we say that the day’s data has a blizzard (and vice versa)!

9.1.1 What is an arithmetic sequence?

An arithmetic sequence is a collection of numbers that differ from each other by a fixed amount. For instance, consider the following sequences (assuming that \(n \ge 1\) in all sequences, where \(n\) is the \(n^\text{th}\) term of the sequence):

\[\begin{align*} &1, 2, 3, 4, ..., 1 + (n - 1) \\ \\ &\frac{1}{3}, \frac{3}{5}, \frac{5}{7}, \frac{7}{9}, ..., \frac{1 + 2(n - 1)}{3 + 2(n - 1)} \\ \\ &2, \frac{3}{2}, \frac{8}{7}, \frac{7}{9}, ..., \frac{10 - (n - 1)}{5 + (n - 1)} \end{align*}\]

In blizzardHours, there is a sublist that is an arithmetic sequence, but first, there are a few formulas to note:

9.1.1.1 Formulas to note…

The \(n^\text{th}\) term of an arithmetic sequence \(a_n\) is:

\[\begin{equation} a_n = a_1 + d(n - 1) \tag{9.1} \end{equation}\]

Where:

  1. \(a_1\) is the first term of the sequence.
  2. \(d\) is the difference between terms in the sequence.

Nonetheless, the sum of \(n\) terms of an arithmetic sequence is:

\[\begin{align} \sum_{k = 1}^n a_k &= \frac{n}{2}(a_1 + a_n) \\ &= \frac{n}{2}(a_1 + a_1 + d(n - 1)) \tag{9.2} \\ &= \frac{n}{2}(2a_1 + d(n - 1)) \end{align}\]

If I’m not mistaken, one of your tutorial questions also references arithmetic sequences, so I would definitely bear equations (9.1) and (9.2) in mind!

9.1.1.2 What does this have to do with the tutorial question?

We can use formula (9.2) to check if there is a blizzard during the day.

Since the question looks out for consecutive hours, we can assume that \(d = 1\) in the question. Furthermore, since we want to check for four consecutive hours, we can also let \(n = 4\) in this question. Hence, this leads to the following line of pseudocode (to check for a blizzard):

if sum of subsequence of length 4 == 2 * (2 * first term of subsequence + 3)

And we implement this in Python to check if there is a blizzard during the day!


  1. In other terms, wind speed >= 30 and visibility <= 0.5↩︎