Skip to main content

Homework 1: ArrayList and Inheritance -
Zipcodes with populations and locations

Due: 2024-02-08 23:59:00EDT

Overview

In this assignment, you will practice object-oriented design with inheritance. You will be building on top of your Homework 0 which parsed zipcodes from uszipcodes.csv. You will use the csv file as well as your implementation of Place.java and LookupZip.java You will also use the ExpandableArray.java implementation you wrote in Lab2. Copy all four to your hw1 directory.


In this assignment, we’ll also use a second input file ziplocs.csv. Download it with this command: wget https://raw.githubusercontent.com/BMC-CS-151/BMC-CS-151.github.io/main/hws/hw01/ziplocs.csv ziplocs.csv

which gives information about zipcodes and their associated latitudes and longitudes (as decimal numbers), among other things (but not population). Your task this week is to weave these two files together and organize the data into classes stored in an ExpandableArray that allows us to perform similiar lookups as those in Homework 0.

All programming assignments will go through an autograder on Gradescope. The autograder will test for correctness. We are providing you some public tests that you can use on your own.

In this assignment, your driver program should be called Driver01.java.

In addition, please read the program design principles and code formatting standards carefully. You are expected to adhere to all stated standards. Violations will result in deductions.

Requirement: You can ONLY include the following import statements:

import java.io.File;

import java.io.FileNotFoundException;

import java.util.Scanner;

You are NOT ALLOWED to include any other import statements in your solutions. That means you cannot use any built-in java data structures.

1 Input File Format

The file ziplocs.csv contains a header line at the top with column names. The following rows contain 12 comma-separated fields that look like this:

"07677","STANDARD","WOODCLIFF LAKE","NJ","PRIMARY",41.02,-74.05,"NA-US-NJ-WOODCLIFF LAKE","false",2945,5471,325436960

We will only use three of these fields, the zipcode (1st column), the latitude (6th column) and the longitude (7th column). In the sample line notice that 07677 is in quotes, but 41.02 and -74.05 are not.

In your last assignment, you only read the zipcode, town and state fields from uszipcodes.csv, but ignored the population information. In this homework, you’ll use the total population field in uszipcodes.csv as well. Note that some fields are missing in the csv, and not every row has an entry for the population.

By using the data between uszipcodes.csv and ziplocs.csv, we can categorize all zipcodes into one of three categories:

  1. PopulatedPlace - zipcodes with a population and location,
  2. LocatedPlace - zipcodes with a location only,
  3. Place - zip codes without either.

These types naturally form an inheritance hierarchy. Think about what the hierarchy should be before you click the answer. Hint: The top-most parent (superclass) should be the most abstract.

Hierarchy: Place
^
|
LocatedPlace
^
|
PopulatedPlace

2. LocatedPlace

Write a new class LocatedPlace that is a subclass of Place. Remember that a subclass inherits all the public or protected fields and methods in the superclass (except the constructor). Include a constructor and any necessary instance variables and getters.

The LocatedPlace class must have an overridden toString method that includes the location information in the string returned. For example, a LocatedPlace representing Bryn Mawr would return the string

Bryn Mawr, PA 40.02 -75.31

3. PopulatedPlace

Write a new class PopulatedPlace that is a subclass of LocatedPlace. Include a constructor and any necessary instance variables and getters.

The PopulatedPlace class must also override the toString method to include the place’s population in the string. A PopulatedPlace representing Bryn Mawr should return the string

Bryn Mawr, PA 40.02 -75.31 21103

4. LookupZip

Modify the readZipCodes method from LookupZip to read both data files, constructing an ExpandableArray of Places and returns it. The method will be modified to take two arguments:

   /** 
   * @param filename The name of the uszipcodes file
   * @param filename2 The name of the second csv file with location info
   * @return An ExpandableArray of Places
   */

Assume that we don’t know how many entries are in the csv files.

If a place’s population is known, it should be represented by a PopulatedPlace object.
Otherwise, if a place’s location is known, it should be represented by a LocatedPlace object.
otherwise it will be represented by a Place object.

Note that the return value is an ExapndableArray of Places. Since both LocatedPlaces and PopulatedPlaces are Places, all types can be in the return value;

This new version returns an ExpandableArray, not an array. This will cause compiler type errors with your old code that used arrays. You need to adapt your old parseLine or lookupZip accordingly.

Requirement: One restriction is that readZipCodes should read each file only once: that is, you should create a new Scanner for each file only once, not repeatedly. You should also not reset these Scanners. You should read in one file first, create objects to accumulate the partial data in that file, and then read the other file, combining the entries appropriately. Note that the zipcodes in the files are not in the same order.

5. Driver01

You can copy the driver from your last homework assignment into a new file called Driver01.java

Update the main method to work with your new methods. It will now take as command line input two Strings: one for each filename. I would recommend compiling all your java files with: javac *.java at this point. In general, compiling as you code, rather than once at the end is a good debugging strategy. Many of the compiler errors will be regarding type mismatches since we are now using ExpandableArray<Place> instead of Place[].

Once you’ve fixed the compiler errors, you can run the code with:

java Driver01 uszipcodes.csv ziplocs.csv

You’ll see the same output you had in the previous homework. At this point, you’ve created version of HW0 which does not assume anything about the length of the input csv files. This is because we are using the ExpandableArray data structure instead of a fixed length array.

Now, your task will be to modify the functionality to practice inheritance.

Recall that the appropriate toString() will be used when you print your three different objects of the Place type hierachy.

Here’s a sample session of running your driver:

zipcode: 19010
Bryn Mawr, PA 40.02 -75.31 21103

zipcode: 99400
No such zipcode

zipcode: 91729
Rancho Cucamonga, CA 34.09 -117.56

zipcode: 97252
Portland, OR

zipcode: 00000
Good Bye! 

Design Considerations

As you start implementing the functionality, you should think about these design questions and come up with answers for them:

Currently, your parseLine function in LookupZip.java returns a Place. Consider the following:

  1. How do you determine if a zipcode should be a PopulatedPlace, a LocatedPlace, or just a Place?
  2. The total population field in uszipcodes.csv is not filled out for some lines. How do you detect that it is missing? Hint: research split and learn about the overloaded version with a second parameter limit.
  3. When the population field is not filled for a zipcode in uszipcodes.csv, what object do you construct? And if the field is not empty, what object do you construct?

Currently, your readZipCodes only scans a single file. You must create two Scanners (one for each file). Read in one entire file first, then read in the second. Consider the following:

  1. After you’ve read in both csvs, you should have two data structures filled with Places (or the appropriate subclass).
  2. You should merge them into a single data structure with one entry for each zip code. How will you collate the information between both csvs?
  3. Note that the zipcode field in ziplocs.csv has double quotes around it. You should remove the quotes (after reading in - don’t modify the input file!) or you will not be able to match them with the zipcodes found in uszipcodes.csv. I recommend using replace from the Java String library (use the Java API reference to find out how).

README.txt

In a text file called README.txt answer the following questions:

  1. How much time did you spend on the homework
  2. What did you learn from this homework
  3. optional: What did you struggle with during this homework
  4. optional: any other feedback you would like to share

Autograder Formatting

Before submitting to the autograder, make sure you conform to the following format:

  1. Do not use a try-catch in your driver.
  2. Your LocatedPlace constructor should take the following types: (String, String, String, double, double)
  3. Your PopulatedPlace constructor should take the following types: String zip, String town, String state, double latitude, double longitude, int population)

Submitting

Submit the following files to the assignment called HW01 on Gradescope:

  1. Driver01.java
  2. Place.java
  3. LocatedPlace.java
  4. PopulatedPlace.java
  5. LookupZip.java
  6. ExpandableArray.java
  7. README.txt

Make sure to name these files exactly what we specify here. Otherwise, our autograders might not work and we might have to take points off.
DO NOT submit a .docx or .pdf file.
DO NOT submit any .class files or any of the csv files.

Copying the files

You will likely want to submit the files from your own laptop/computer. To copy the files from goldengate to your own machine, open up a terminal on your own computer. If you have a mac or linux, you can use the Terminal application, if you have a windows you can use the Powershell app.

Run the following command:

$ scp <username>@goldengate.cs.brynmawr.edu/home/<username>/cs151/homeworks/hw00/*

Make sure to replace <username> with your username. scp is a command to secure-copy files from one server to another. In this case, from goldengate to your own machine.