File Import
We're ready to implement another one of our menu items, and a couple of the instance methods of our class. We will be importing a file that contains thousands of temperature readings taken during a week at the STEM Center.
Download the file (STEM Center Temperature Data)Kindly find it in the attachment(Temperatures2017-08-06.csv). and place it in the same directory as your python files. The file is in .csv format (comma-separated value). Each line represents one "report" from a sensor in the STEM center, most of which are temperature readings.
The format of each line is:
Day of Week, Time of Day, Sensor Number, Reading Type, Value
Day of Week is an int where 0 represents Sunday, 1 represents Monday, etc.
Time of Day is a float between 0 and 1. 0 is 12:00AM and 1 is 11:59PM. The rest of the times are scaled linearly. We will covert this value to an hour of day value.
Sensor Number is an int, and maps to the sensors we coded in a previous assignment.
Reading Type is a string that contains "BATTERY", "TEMP", "AWAKE" or "SLEEPING". We will only use the lines with "TEMP".
Value is the value related of the reading. For TEMP type, this is degrees Celsius.
Steps to Implementation
This is a complex project and you will learn a lot. Here is a roadmap for what needs to be done:
First, open a new .py file for this assignment. Copy in your code from assignment seven, including its main. Then copy the class from assignment eight. Make sure you do not include the unit test from assignment eight. In main(), instantiate an object current_set of type TempDataset(). Finally, we'll fix all the function calls in our menu that passes the argument None, we can now pass current_set instead. Run this code to make sure you have no stray lines. Your menu should run just as in assignment seven. Now we are ready to build on this code!
We will start with process_file().
This method has filename as one of its parameters. We need to try (hint) to open this file for reading. If we can't open it, we need to return False. Once you have that coded, you can test it by calling process_file("Temperatures2017-08-06.csv") and process_file("Blah"). Remember, these are instance methods in our class, so you need to call them using the current_set object we created. The first should quietly succeed if you have downloaded the datafile and put it in the correct directory. The second should return False.
Continuing in process_file(), recall that we have a variable _data_set in our class that was initialized to None. We want to reinitialize this as an empty list. Remember that this variable is an instance attribute in the class, be careful not to create another variable that is local to process_file()!
In a loop, we read-in each line from the file. We'll need to do type conversions to make day and sensor as ints and temp as a float. We also must convert Time of Day to a number that represents the hour of the day. Multiply the given time by 24, and then use math.floor to round the result down to an integer between 0 and 23 (you will need to import math at the top of your module to use the floor function).
We want to discard anything other than a temp reading (how?). For temperature readings, we will make a tuple:
(day, time, sensor, temp)
and add the tuple to the list _data_set.
We'll make the assumption that the data in the file is correct. We should be handling errors in the reading of the data, but for our purposes, if we get past opening the file, we'll assume that everything else will go smoothly. Feel free to improve on this by returning False if any kind of load error happens throughout the process.
Continue until we are done with the list, and return True!
Next we implement get_loaded_temps()
This method is simple. If we have not successfully loaded a data file, it should return None. Otherwise, it should return the number of samples that were loaded (an int). Think of how we can check if a data file has ever been loaded, by looking at _data_set.
Finally, new_file()
Recall that our menu item 1 calls new_file(). This function should ask for a filename and then use process_file() to load the data.
If process_file() fails to load data, the program should complain (from new_file(), not from process_file!) to the user that it is unable to load a file. new_file() should then fall back to main.
If process_file() succeeds, then new_file() should report the number of samples that were loaded.
new_file() should then ask for a 3 to 20 character name for the data. Use the setter method we created in TempDataset to validate and set the name. Tell the user if the name is bad, and don't let them leave until they input a good name. You are not changing the property name() at all, we already verified that it works. All of this functionality should happen in new_file().
Remember to change the menu routine, replace None in the call to new_file() with the appropriate object.
Note that process_file() and the property name() should not print anything.
Test the functionality of your loop, the number of samples retrieved should be the same as my sample run below (11,724).
One last thing. For testing, add these lines in main right after your call to print_menu():
if current_set._data_set is not None:
print([current_set._data_set[k] for k in range(0, 5000, 1000)])
After you run and load the file, you should see a list that looks (exactly) like this. The loop pulls out item 0, 1000, 2000, 3000 and 4000, and you can use this to verify that the data is loaded correctly. I will be adding this line to your code and checking that you have the correct data.
[(0, 18, 0, 17.5), (0, 2, 3, 21.59), (1, 9, 0, 19.55), (1, 12, 2, 23.23), (2, 4, 1, 22.05)]
We're breaking the rules by directly accessing object data. So quickly take these lines out after you verify the data! We wouldn't want to get caught.
That's it! Make sure your sample run shows a failed load as well as a successful one.
Sample run:
STEM Center Temperature Project
Mike Murphy
Main Menu
---------
1 - Process a new data file
2 - Choose units
3 - Edit room filter
4 - Show summary statistics
5 - Show temperature by date and time
6 - Show histogram of temperatures
7 - Quit
What is your choice? 1
Please enter the filename of the new dataset: Temperatures2017-08-06.csv
Loaded 11724 samples
Please provide a 3 to 20 character name for the dataset My Data Set
Main Menu
---------
1 - Process a new data file
2 - Choose units
3 - Edit room filter
4 - Show summary statistics
5 - Show temperature by date and time
6 - Show histogram of temperatures
7 - Quit
What is your choice?