Question: Python help We're ready to implement one of our menu items, and a couple of our class methods. We will be importing a file that
Python help
We're ready to implement one of our menu items, and a couple of our class methods. We will be importing a file that contains thousands of temperature readings taken during a week at the STEM Center.
Download the file in today's module 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 between 0 and 5, 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.
BE CAREFUL: There is an INSTANCE METHOD, getLoadedTemps(), that CALCULATES the number of samples loaded in the current OBJECT by looking at the list data_set. There is a separate CLASS VARIABLE, total_samples_loaded, that KEEPS TRACK of the sum of samples across ALL OBJECTS of the class. getLoadedTemps() will help you update total_samples_loaded, but they are not the same thing.
Steps to Implementation
This is a pretty complex project, but here's a roadmap to what needs to be done:
First, open a new file for this assignment. Copy in your code from assignment five, including its main (make sure that you fix any issues that were noted by your professor!). Then copy the class from assignment six. Make sure you do not include the unit test from assignment six. Just before your main, instantiate an object current_set of type TempDataset(). Run this code to make sure you have no stray lines. Your menu should run just as in assignment five. Now we are ready to build on this code!
We will start with processFile().
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 processFile("Temperatures2017-08-06.csv") and processFile("Blah"). 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 processFile(), 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 belongs to the class, be careful not to create another variable that is local to processFile()!
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.
We want to discard anything other than a temp reading (how?). For everything else, we will make a tuple:
(day, time, sensor, temp)
and add the tuple to the list data_set.
We'll make the bold 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.
Update the class variable that holds the total number of samples loaded. You should be ADDING to the variable, not replacing.
Continue until we are done with the list, and return True!
Next we implement getLoadedTemps()
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, newFile()
Recall that our menu item 1 calls newFile(). This function should ask for a filename and then use processFile() to load the data.
If processFile() fails to load data, the program should complain (from newFile(), not from processFile!) to the user that it is unable to load a file. newFile() should then fall back to main.
If processFile() succeeds, then newFile should report the number of samples that were loaded.
newFile() should then ask for a 3 to 20 character name for the data. Use the setName() method 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 setName() at all, we already verified that it works. All of this functionality should happen in newFile().
Test out 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 printMenu():
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.
One more thing to clean up. In the __init__ method we need to call processFile() if a filename was supplied. So add code in __init__ to check if filename is None and return true if it is. If it is not None (a filename was supplied) then call processFile() with the filename, and then __init__ should return the return value of processFile() (maybe read that a couple times, this can all happen on the same line). My mistake, this won't work!
That's it! Make sure your sample run shows a failed load as well as a successful one.
Sample run:
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?
File like this
0,0.0291087962962963,1,BATTERY,2.58
0,0.0637731481481481,1,BATTERY,2.58
0,0.0984375000000000,1,BATTERY,2.58
0,0.1331134259259260,1,BATTERY,2.58
0,0.1677893518518520,1,BATTERY,2.58
0,0.2024652777777780,1,BATTERY,2.58
0,0.2371296296296300,1,BATTERY,2.58
0,0.2718055555555560,1,BATTERY,2.59
0,0.3064814814814810,1,BATTERY,2.59
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
