9.1 Blizzard!
In this problem, you were to code a program that did the following:
- Open up
stormtrack.txt(somehow) and iterate through each line ofstormtrack.txt. - Where a line (i.e., hour) met blizzard conditions5, note it down.
- 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:
Creating two variables
blizzardHoursandhasBlizzardblizzardHoursis a list that stores the hours of the day (i.e., the rows ofstorm.txt) that met blizzard conditions.hasBlizzardis 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
hasBlizzardisTrueorFalsefor now. We will write code that changes the value ofhasBlizzardlater!Opening and iterating through
storm.txtusing Python’sopen()andenumerate()functionsThe
open()function grants Python access to a file. The.readlines()method returns every line inopen('storm.txt')as a list - in essence,open('storm.txt').readlines()returns a multi-dimensional list that contains each line of data instorm.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 argumentstart = 1; all iterated indices will begin at0inenumerate()by default. However, you can specify the starting index too - granted, this isn’t strictly necessary, but since we will eventually storehourinblizzardHours, I think it helps to use 1-based indexing so that we don’t confuse ourselves later on!Splitting each line of data using
.split(), converting the data into a float, and checking for blizzard conditionsI 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.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
hasBlizzardis changed toTrueand the for loop terminates.Stating whether the day’s data has a blizzard or not
This is where
hasBlizzardis incredibly handy. IfhasBlizzardisTrue, 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:
- \(a_1\) is the first term of the sequence.
- \(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!
In other terms, wind speed >= 30 and visibility <= 0.5↩︎