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):
= [] ; hasBlizzard = False
blizzardHours
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):
= True
hasBlizzard 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
blizzardHours
andhasBlizzard
blizzardHours
is a list that stores the hours of the day (i.e., the rows ofstorm.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
isTrue
orFalse
for now. We will write code that changes the value ofhasBlizzard
later!Opening and iterating through
storm.txt
using 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 at0
inenumerate()
by default. However, you can specify the starting index too - granted, this isn’t strictly necessary, but since we will eventually storehour
inblizzardHours
, 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
hasBlizzard
is changed toTrue
and the for loop terminates.Stating whether the day’s data has a blizzard or not
This is where
hasBlizzard
is incredibly handy. IfhasBlizzard
isTrue
, 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↩︎