# Lab 8: Arrays, ArrayLists, and Files: Analysing Data CS 141: Introduction to Programming , Fall 2015

This lab is due Monday, Nov 9, by the end of the lab. (Try to have Part 1 done by Nov 2.)

### Overview

The goal of this lab is to give you practice working with arrays, ArrayLists, and files. In the first part of the lab, you will focus on using a 1D arrays of primitives. In the second part, you will work with a 1D array of objects. Finally, in the last part, you will be given code to read in the data from a text file.

### Practice with Arrays (this part will not be collected)

Many of the problems in the Basic Array Problems are similar to the methods you must implement below. Try to do the problems below first but if you have trouble, take a look at the solutions for the Basic Array Problems. Many of these basic problems will be covered in class and are also discussed in your text.

### Part 1: 1D Arrays

• Create a Netbeans project. Add a Temperatures class which contains a member variable called temperatures as given here:
``````
// Mean July temperatures in Salem, Oregon from 1903 to 2015
private double temperatures [] = {
63.6,66.8,68.8,72.0,67.6,70.4,62.9,67.2,69.5,67.0,
66.1,68.3,66.5,64.2,69.0,66.3,66.7,64.7,65.1,69.5,
67.6,67.3,69.3,70.8,69.6,68.0,65.2,62.4,66.6,63.7,
65.0,64.5,65.9,65.5,65.7,69.2,67.8,66.5,72.0,68.6,
67.0,67.7,68.1,67.3,65.7,65.5,66.0,67.3,66.7,67.5,
64.6,62.7,62.4,67.7,64.5,71.2,67.9,67.6,67.5,64.3,
61.9,66.4,67.2,65.2,67.6,66.1,64.9,67.2,67.3,67.5,
67.4,65.8,67.0,65.3,64.5,68.8,67.9,65.5,65.0,65.6,
64.3,65.4,70.1,63.5,64.8,66.8,64.6,69.6,68.0,68.9,
63.2,69.1,68.5,70.2,66.9,69.6,66.1,66.0,66.0,68.8,
70.2,70.0,68.9,69.8,69.9,68.0,71.2,67.5,65.9,66.8,
70.5,72.5,72.8};
``````
Note, this data can be found Salem Temperature Data, July.
• Add another member variable that contains the starting year (i.e. 1903)

• Add methods:

1. Temperatures(): a no-arg constructor - doesn't need to do anything at the moment
2. Temperatures(Temperatures t): a copy constructor (be careful to do deep copying!)
3. Temperatures(double[] a,int start): a constructor which takes an array and a start year which are used to set the values of the member variables.
4. temperatureAtIndex(int i): returns the ith temperature. Note, it should return Double.NaN (not a number) if i is not a legal subscript.
5. temperatureAtYear(int year): returns the temperature in a specific year. Note, it should return Double.NaN (not a number) if the year is earlier than 1903 or after 2015.
6. getTemperatureArray(): returns a reference to a copy of the entire array. Returning a copy is safer than returning the array itself. Use a for-loop to make a copy.
7. getStartYear(): return the starting year
8. getNumberOfYears(): returns the length of the array
9. calcAverage(): returns the average of all the temperatures
10. getMax(): returns the maximum of all the values
11. getMin(): returns the minimum of all the values
12. getMedian (): returns the median of all values. (If you don't know what the median is, google "median value"). This method will take some thinking about. To determine the median, you will first need to sort the list. You can use the Arrays class to do the sorting - read the javadoc to understand how to use the Arrays sort method. Also, note, the Arrays sort method will sort the array in place meaning you lose the original ordering by year, which you don't want to lose. Therefore, you will need to make a temporary copy of the array and do the sorting on the copy. Use the getTemperatureArray() method to create the copy. Note, the median calculation is different if the array has an even vs an odd number of elements. The temperatures array given above has an odd number but write your code so it will work correctly regardless of whether there is an even or odd number of elements.
13. toString(): returns a string that prints a list of (year, temperature) pairs, for example:
``````year: 1903 temperature = 63.6
year: 1904 temperature = 66.8
year: 1905 temperature = 68.8
year: 1906 temperature = 72.0
year: 1907 temperature = 67.6
year: 1908 temperature = 70.4
year: 1909 temperature = 62.9
year: 1910 temperature = 67.2
year: 1911 temperature = 69.5
year: 1912 temperature = 67.0
year: 1913 temperature = 66.1
...``````
14. graph(): This returns a String representation (don't use sout) of a graph of the data. Each row corresponds to a single year with the number of "*"s representing the size of the data. To do this well will take some thought. For example, the simplest approach is to just round each temperature to an integer (e.g. 64.6 will become 65) and draw the number of "*"s equal to this rounded temperature (e.g. draw 65 "*"s). The result would look like this for the first 10 years:
``````
Salem Mean July Temperatures
Range shown is from 0 to 72.8 ( one "*" corresponds to 1 degree)
1903:  63.6 ****************************************************************
1904:  66.8 *******************************************************************
1905:  68.8 *********************************************************************
1906:  72.0 ************************************************************************
1907:  67.6 ********************************************************************
1908:  70.4 **********************************************************************
1909:  62.9 ***************************************************************
1910:  67.2 *******************************************************************
1911:  69.5 **********************************************************************
1912:  67.0 *******************************************************************
1913:  66.1 ******************************************************************
``````

Another more challenging way to do this exaggerates the differences by drawing only the region between the min and max, scaling the results so it fits across the width of the window. If you want a challenge do it this way, otherwise, do it the above simpler way. In this case, the result would look like:

``````
Salem Mean July Temperatures
Range shown is from 61.9 to 72.8
1903:  63.6 ************
1904:  66.8 ***********************************
1905:  68.8 **************************************************
1906:  72.0 **************************************************************************
1907:  67.6 *****************************************
1908:  70.4 **************************************************************
1909:  62.9 *******
1910:  67.2 **************************************
1911:  69.5 *******************************************************
1912:  67.0 *************************************
1913:  66.1 ******************************
``````
15. (Optional) If you have time, add some additional methods that could be interesting when analyzing the data, For example, a method that prints all year/temps that are above (or below) a specific temperature could help you see if temperatures have been warmer in the more recent years.

• Thoroughly test your program, for example, executing the following code below in main and comparing to the output here.

``````Temperatures temps = new Temperatures();
System.out.println("Start year: " + temps.getStartYear());
System.out.println("Number of years of data: " + temps.getNumberOfYears());
System.out.println("Temperature data:\n" + temps);
System.out.println("Temperature at index 2: " + temps.temperatureAtIndex(2));
System.out.println("Temperature in year 1910: " + temps.temperatureAtYear(1910));
System.out.println("Average July temperature: " + temps.calcAverage());
System.out.println("Max July temperature: " + temps.getMax());
System.out.println("Min July temperature: " + temps.getMin());
System.out.println("Median July temperature: " + temps.getMedian());
double [] tempCopy = temps.getTemperatureArray();
tempCopy[0] = 100;  // this should not change the original array!
System.out.println("Orig: Temperature at index 0: " + temps.temperatureAtIndex(0));
System.out.println("Copy: Temperature at index 0: " + tempCopy[0]);
System.out.println("\n"+temps.graph());
``````
• Demonstrate your Temperatures class to the instructor or lab assistant before continuing. There is nothing to turn in on WISE.

### Part 2: Array of Objects

In the above program, you worked with an array of primitive types (i.e. doubles). The downside is that it was not always possible to maintain the connection between the year and the temperature. For example, when you sorted the temperatures, you had no way of knowing what year each temperature corresponded to. This can easily be fixed by creating an array of objects where each object encapsulates the related items (in this case, the year and temperature).

In this part of the lab, you will create a simple class that holds a year and a temperature. You will then create another class which contains an array of the simple class. By adding a compareTo() method, we will be able to use the Arrays class to sort the array. Once sorted, you can print out the sorted list where each object maintains the grouping of the year and temperature. This will enable us to observe how the temperature is related to year and ask questions such as "are most of the hottest years more recent?"

Instructions:

• We are going to construct the three classes shown in the picture above.
• Create a new Netbeans project.
• Add a simple TempData class which contains two member variables: the year and temperature. Include:
• A constructor which has 2 parameters, one each for setting the year and temperature.
• A copy constructor.
• setters and getters for both variables (you can have Netbeans write these for you.)
• A toString that prints out something like
``year: 1954  temp: 62.7``
• A compareTo(TempData t) which returns the integer 0 if the objects temperatures are the same, 1 if "this" has a larger temperature than t, and -1 if "this" has a lower temperature than t. The header should look like:
``public int compareTo(TempData t)``
• In order for the Arrays sort method to work, it needs to know how to compare TempData objects. The compareTo method is a special method that the Arrays class knows about and will use for this purpose. To insure that you have used the proper syntax for the compareTo method, you must add to the class heading the words "implements Comparable" as follows so that the class declaration looks like:
``public class TempData implements Comparable<TempData>``

We say that Comparable is an interface. Interfaces require that you implement certain methods that have specified headers, in this case, we need the compareTo method with the header given above.

If the TempData class includes a .compareTo method which compares TempData objects based on the value of their temperature, then we can sort the array. And, since the year and temperature are encapsalated together in the TempData object, we are able to maintain the relationship between the year and the temperature.

• Create another class in Netbeans called TemperatureObjects (the object version of your Temperatures class). It should have:
• A single member variable (e.g. called tempDataArray) which is a reference to an array of TempData objects. The actual array elements will be created in the constructor (see next).
• A no-arg constructor. Copy and paste your temperatures array from before as a local variable in the constructor. It should be local because once tempDataArray is created, you don't need the temperatures array anymore. Also include a local int variable to store the start year. To fill out the tempDataArray, first, create the array of references of your array tempDataArray. Then, in a for-loop, create the actual TempData objects using the data in the local temperatures array and calculating the year from the start year and loop index.
• A toString method which prints out the list of year/temp pairs similar to what was done in part 1.
• A method which returns the object with the highest temperature (make use of the compareTo method in TempData).
• A method which returns the object with the lowest temperature.
• A sort method which creates a copy of the tempDataArray and uses the Array class to sort the array. It then returns the resulting copy.
• A method called graph which returns a String representation of the graph. You can modify your graph method from before.
• Finally, create a JFrame. Add a TemperatureObjects member variable to your JFrame as shown in the picture above. Add components so that your JFrame implements the following functions and looks something like:

### Part 3: Files

In this part of the lab, you are to read in the array of temperature values from a file.

1. Download the file meanJulyTemp1903to2015.txt and save it into the src folder of your project (along with your .java files).
2. Download MyFileReader.java and also save it into the src folder of your project. This class reads in an array of doubles. You may need to "refactor" it by fixing the package name. We will go over the code in class.
3. In the constructor of your TemperatureObjects class, you just need to replace the temperatures array
``````double temperatures[] = {
63.6, 66.8, 68.8, 72.0, 67.6, 70.4, 62.9, 67.2, 69.5, 67.0,
66.1, 68.3, 66.5, 64.2, 69.0, 66.3, 66.7, 64.7, 65.1, 69.5,
...};``````
with
``````MyFileReader reader = new MyFileReader("src\\your_package_name\\meanJulyTemp1903to2015.txt");
double temperatures[] = reader.data;``````
If you are working on a Mac, the path/file syntax will be different. Try instead:
``MyFileReader reader = new MyFileReader("src/your_package_name/meanJulyTemp1903to2015.txt");``

Compile and run your program. It should run exactly as before. The advantage of having the data in a file is that:

• It is easier to change the data - just pick a different data file.
• If you do change the data, you don't have to re-compile the program.
• If you want the user to have the ability to choose the data, you can add a "load file" button which prompts the user for the name of the desired file and then reads in this file.
• If you want the user to have the ability to modify values in the file, you can add a "change item" button and resave the data to a new data file.

### Deliverables

To receive full credit, you need to:

1. Make sure that your Java code:

• Is well commented, including at the top of each file, your name, lab name, program name, date, brief description of what the class does.
• Is well formatted, i.e. proper indentation and line returns.
2. Demonstrate:

• Your Temperatures class (Part 1) to the instructor or lab assistant
• You final program with the GUI and reading from a file (Parts 2 & 3).

• Submit the following 4 files to Wise as attachments to Lab 8

• For Part 1: Temperatures.java
• For Part 2 and 3: your JFrame java file, TempData.java, and TemperatureObjects.java