## CSC 222: Object-Oriented Programming Fall 2017

### HW 4: Lists & Objects

In lectures, we explored an application involving a massive collection of UFO sightings. The UFOsighting class stored information about a single sighting and provided methods for accessing that information. The UFOlookup class read in the UFO sighting data from a file, constructed an ArrayList of `UFOsighting` objects, and then provided methods for selectively looking up sightings based on location or date. For this assignment, you will develop similar classes that store and process cost of living data.

Each year, the Council for Community and Economic Research performs extensive studies on the costs of goods and services at cities across the country. In particular, they track costs in six major categories: groceries, housing, utilities, transportation, healthcare, and miscellaneous goods and services. Each is assigned a number relative to the national average of 100. Thus, a housing index of 110 would imply that housing is 10% higher than the national average, while a health care index of 95 would imply that health care costs are 5% lower than the national average. These six indices are combined into a single composite index, which is often used to compare cities with respect to their overall cost of living. The composite Cost of Living Index (COLI) uses the following weights:

```  COLI = 0.13*groceries + 0.29*housing + 0.10*utilities + 0.12*transportation + 0.04*health + 0.32*miscellaneous
```

For example, the six individual indices for Omaha (according to 2010 COLI data) are: 92, 79.3, 89.9, 100, 96.8, and 89.7. This results in a COLI of 88.523, which implies that Omaha has a cost of living that is approximately 12% lower than the national average:

```  COLI = 0.13*92 + 0.29*79.3 + 0.10*89.9 + 0.12*100 + 0.04*96.8 + 0.32*89.7 = 88.5
```

One common use of the cost of living index is to compare salaries at different locations. Suppose you are currently living in Omaha and making \$65,000 per year. You receive an offer for a job in Chicago making \$80,000 - is that effectively a raise? Since the cost of living in Omaha is 88.5 and Chicago is 117.0, Chicago is more expensive by a factor of 117.0/88.5 = 1.3220339, meaning you would have to make \$65,000*1.3220339 = \$85,932.20 to break even. Accepting the offer to move there at \$80,000 would actually be a backward move!

### Part 1: CityStats

Similar to the `UFOSighting` class, you are to design and implement a class named `CityStats`, which stores the names of the city and state, as well as the six cost indices for that city. The constructor for the class should take all eight pieces of information (city, followed by state, followed by the indices) and store those values in fields. It should have accessor methods for each value, e.g., `getCity`, `getState`, `getHealthIndex`, etc. It should also have a method for calculating and returning the composite COLI of that city, rounded to one decimal place. For example, if `myCity` was a `CityStats` object initialized with the above information for Omaha, then `myCity.getCOLI()` should return 88.5.

### Part 2: CityLookup

The file COLI2010.txt has been provided for you, which contains the six individual cost indices for 334 American cities. Each line in the file contains the six indices (in the order listed above), the state abbreviation, and the city name (which can include spaces). For example, the line corresponding to Omaha appears as follows:
```  92.0 79.3 89.9 100.0 96.8 89.7 NE Omaha
```

Similar to the `UFOlookup` class, you are to design and implement a class named `CityLookup` that reads in the city information from a file of this format, stores them in an `ArrayList` of `CityStats` objects, and provides methods for accessing that information. In particular, it should have the following methods:

• numCities: This method returns the number of cities that were read in and stored. For example, if the information from `COLI2010.txt` was read in and stored in a `CityLookup` named `cities`, then `cities.numCities()` should return 334.

• showByState: This method takes a state abbreviation as input, and displays the COLI of all cities from that state. Each city should be displayed on a line, and the number of matching cities should be displayed at the end. Note: this method and all that follow should be case-insensitive (meaning that the capitalization of the method inputs should not matter). For example, if the information from `COLI2010.txt` was read in and stored in a `CityLookup` named `cities`, then `cities.showByState("ND")` should display the following:
```  Bismarck, ND: 95.5
Fargo, ND: 92.7
Minot, ND: 99.8

Number of cities in ND: 3
```
• showByCity: This method takes a city name (or portion of a city name) as input, and displays the COLI of all cities that match (or contain) that name. As before, the number of matching cities should be displayed at the end. For example, if the information from `COLI2010.txt` was read in and stored in a `CityLookup` named `cities`, then `cities.showByCity("burgh")` should display the following:
```  Pittsburgh, PA: 91.8
Plattsburgh, NY: 100.2

Number of cities that contain burgh: 2
```
• lookupCOLI: This method takes a city and state as inputs, searches through the list of `CityStats` objects until it finds one whose city and state match, then returns the composite index for that city. For example, if the information from `COLI2010.txt` was read in and stored in a `CityLookup` named `cities`, then `cities.lookupCOLI("Omaha", "NE")` should return 88.5. If the inputs do not match an entry in the city list, the method should return -999.

• compareCities: This method takes a salary amount, the current city and state where a person lives, and the city and state where they are considering moving. It returns the salary the person would have to make in the new city to be equivalent to their current situation. Since the return value represents a dollar amount, it should be rounded to two decimal places. For example, if the information from `COLI2010.txt` was read in and stored in a `CityLookup` named `cities`, then `cities.compareCities(65000, "Omaha", "NE", "Chicago", "IL")` should return 85932.20.

Be sure to include javadoc comments in your classes, including your name in the top comment block. Avoid redundancy and be conservative in your use of fields - if a data value does not need to persist over the life of the object, declare it to be local to the method that needs it.