I'm following a project in Python Crash Course that demonstrates how to use CSV files. The code below successfully populates the dates
list with what I believe are datetime
objects. For example, this is the first element of the dates
list: datetime.datetime(2014, 1, 1, 0, 0)
. Here is the functional code:
import csv
from datetime import datetime
filename = 'sitka_weather_2014.csv'
with open(filename) as f:
reader = csv.reader(f)
# Move onto the next row as the first contains no data
next(reader)
dates = []
for row in reader:
try:
date = datetime.strptime(row[0], "%Y-%m-%d")
except ValueError:
print(date, "missing data")
else:
dates.append(date)
print(dates[0])
The output of this code is: 2014-01-01 00:00:00
Now, I wanted to implement this project with several different files, and practice with OO design principles. I set up a parent class WeatherData
that has two attributes: a list called data
and a string called filename
. The WeatherData
class will populate the data
list with the a specific column from the CSV file. Next I created a child class called WeatherLocation
that inherits from WeatherData
. WeatherLocation
has three attributes:
- A list called
highs
that stores the max temperatures - A list called
lows
that stores the low temperatures - A list called
dates
that stores the dates
If we look at the set_data
method of WeatherData
we'll see that the same logic as the code above is implemented. When the set_dates
method of WeatherLocation
is called, the same row number is passed, and fetching_dates
is set to True
so the correct section of the if statement is executed. The code is shown below:
import csv
import os.path
from datetime import datetime
class WeatherData:
def __init__(self, filename):
self.data = []
self.filename = self.give_file(filename)
def give_file(self, filename):
"""Method checks for existence of file before setting the 'filename'
attribute to the argument
"""
if not os.path.isfile(filename):
print("The file " + filename + " could not be found")
else:
return filename
def set_data(self, row_number, fetching_dates=False):
"""Sets the data attribute to a list of data selected by the program"""
if not self.filename:
print("You must call give_file() and provide it a filename"
+ " before calling this method")
with open(self.filename) as f:
reader = csv.reader(f)
# Call next method so we can skip the header_column and get
# into the data
next(reader)
for row in reader:
if fetching_dates:
try:
date = datetime.strptime(row[row_number], "%Y-%m-%d")
except ValueError:
print(date, "missing data")
else:
self.data.append(date)
else:
try:
datum = int(row[row_number].strip())
except ValueError:
print(datum, "missing data")
else:
self.data.append(datum)
def get_data(self):
return self.data
class WeatherLocation(WeatherData):
def __init__(self, filename):
super().__init__(filename)
self.highs = self.set_highs()
self.lows = self.set_lows()
self.dates = self.set_dates()
def set_highs(self):
super().set_data(1)
return super().get_data()
def set_lows(self):
super().set_data(3)
return super().get_data()
def set_dates(self):
super().set_data(row_number=0, fetching_dates=True)
return super().get_data()
sitka = WeatherLocation('sitka_weather_2014.csv')
print(sitka.dates[0])
Unfortunately, the output of this code is 46
. What am I doing wrong?