CS21 Lab 8: Zipcodes

Due Saturday, April 6, before midnight.


The primary goals of this lab are to continue using Top-Down-Design principles in conjunction with linear and binary search techniques to process geographic data.

Please read through the entire lab before starting!

Make sure all programs are saved to your cs21/labs/08 directory. Files outside this directory will not be graded.

  $ update21
  $ cd ~/cs21/labs/08

Note: This is a one week lab. Last lab you a full week to practice the TDD component and a second week to implement your solution. Since the design should be similar to the previous lab, you will be doing the design and implementation in a single week. If you found the open-ended nature of the last lab challenging, you will want to start this lab early.

ZIP Code database

Is 12345 a valid ZIP code? What is the ZIP code for Truth or Consequences, NM? Your assignment this week is to create a program zipcodes.py that allows a user to explore a ZIP code database. ZIP codes are used by the US Postal service to direct mail to cities more efficiently. An Online Interactive Viewer allows you to rapidly see how ZIP codes are distributed nationally (sadly, Alaska and Hawaii are omitted from the demo), and can help you find the names of places associated with any ZIP code.

The file /usr/local/doc/zipcodes.txt contains ZIP code data for most of the United States (don't copy this file to your 08 directory, just use "/usr/local/doc/zipcodes.txt" as the file name in your python program). Each line of the file contains the following fields separated by commas:

ZIP code
Latitude
Longitude
City name
County name
State
Population

The entry for Swarthmore is shown here:

19081,39.897562,-075.346584,Swarthmore,Delaware,PA,9907

For this lab, your program should prompt the user with a menu of 5 choices:

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

You program should ask the user for a valid choice and then perform the following queries listed below for each menu option, then return to the main menu again until the user selects option 5. Quit.

Find by ZIP

For option 1 (Find a ZIP code) you must:

Some examples are shown below:

Welcome to the zipcode program!

Please select one of the following choices:

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 1
Enter a 5-digit ZIP code: Corgis
Corgis is not a valid ZIP code. Try again.
Enter a 5-digit ZIP code: 19081

Swarthmore, PA, 19081
Delaware County
Population: 9907

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 1
Enter a 5-digit ZIP code: 99709

Fairbanks, AK, 99709
Fairbanks North Star County
Population: 52316

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 1
Enter a 5-digit ZIP code: 99999

No info on this ZIP exists.

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Find by Name

For option 2 you must:

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 2
Enter a city prefix: Corgiville

Sorry... I can't find any info about that name...

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 2
Enter a city prefix: Swart

Swartswood, NJ 07877 Population: 0
Swarthmore, PA 19081 Population: 9907
Swartz Creek, MI 48473 Population: 19655
Swartz, LA 71281 Population: 0

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 2   
Enter a city prefix: Pittsburgh

Pittsburgh, PA 15201 Population: 736800
Pittsburgh, PA 15202 Population: 736800
Pittsburgh, PA 15203 Population: 736800
Pittsburgh, PA 15204 Population: 736800
Pittsburgh, PA 15205 Population: 736800
Pittsburgh, PA 15206 Population: 736800
Pittsburgh, PA 15207 Population: 736800
[...Many results omitted from this lab writeup...]
[...Your program should list them all...]
Pittsburgh, PA 15278 Population: 736800
Pittsburgh, PA 15279 Population: 736800
Pittsburgh, PA 15281 Population: 736800
Pittsburgh, PA 15282 Population: 736800
Pittsburgh, PA 15283 Population: 736800
Pittsburgh, PA 15285 Population: 736800
Pittsburgh, PA 15286 Population: 736800
Pittsburgh, PA 15290 Population: 736800
Pittsburgh, PA 15295 Population: 736800

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice?

Map state

For option 3 you must:

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 3
Enter a two-letter state postal code: BC
Enter a population threshold for big cities: 23
No state found for BC

No info for state BC found

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 3
Enter a two-letter state postal code: PA
Enter a population threshold for big cities: 100000

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Map county

For option 4 you must:

Choice? 4
Enter a 5-digit ZIP code: 99999

No info on this ZIP exists.

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Choice? 4
Enter a 5-digit ZIP code: 19801

Wilmington, DE, 19801
New Castle County
Population: 219067

1. Find by ZIP code
2. Find by name
3. Map state
4. Map county
5. Quit

Requirements, Hints, and Tips

You should practice good top-down design, incrementally implement and test your solution, and document your code with comments. Start with the main menu and get a skeleton of your code working first. Then add each option from the menu one at a time (start with quit as it is easy and will allow you to exit your program when you are testing it). While much of the design is up to you, the requirements below are designed to avoid some headaches in the initial design.

The boundaries library has some helpful tools for managing the ZIP code data.

from boundaries import *

The first tool is a small ZipCode class. You can create a new ZipCode object by providing a ZIP, latitude, longitude, city name, county name, state name, and population to the ZipCode constructor. It is expected that latitude and longitude are floats, population is an int, and all other parameters, including ZIP codes are strings. The following ZipCode methods allow you to access the information of a single ZipCode object

lat = 39.897562
long = -075.346584
place = ZipCode("19081", lat, long, "Swarthmore", "Delaware", "PA" , 9907)
print(place.getZip())

To create a list of all the places from a file, you could use a sample function like the one below:

def readData(filename):
    """
    Read file of zip data, return list of
    zipcode objects
    """
    allzips = []
    f = open(filename)
    for line in f:
          line = line.strip().split(",")
          place = ZipCode(line[0], float(line[1]), float(line[2]),
           line[3], line[4], line[5], int(line[6]))
          allzips.append(place)
    f.close()
    return allzips

The second tool is the getStateGraphWin(state) function. If you provide this function a valid two letter state abbreviation, the function will create and return a GraphWin object with the boundary of the state shown in black and the coordinate of the window set to be the minimum and maximum longitudes and latitudes of the state using setCoords. If the provided state variable is not a valid abbreviation, a special None object is returned. The None type is not a GraphWin object and you cannot do anything with it besides check if it is None. Below is a sample use of the function.

state="PA"
win = getStateGraphWin(state)
if win == None:
  print("Oops, something went wrong!")
  return

# otherwise, window is OK. You can do more drawing here

# wait for mouse click before closing
win.getMouse()
win.close()

General Requirements

 place = allzips[10]
 print(place.getName())
 from boundaries import *
 win = getStateGraphWin("PA")
 #Only one of these points will display on the PA map
 pt1 = Point(-76, 40)
 pt2 = Point(40, -76)
 pt1.setFill("black")
 pt2.setFill("gold")
 pt1.draw(win)
 pt2.draw(win)
 win.getMouse()
 win.close()

Missing Data

The ZIP Code data file we have provided you is by no means complete. Some ZIP codes were missing or did not have lat/long data and were removed. For some cities, we did not have population data, so we set the population arbitrarily to 0.


Answer the Questionnaire

Each lab has a short questionnaire at the end. Please edit the QUESTIONS-08.txt file in your cs21/labs/08 directory and answer the questions in that file.


Turning in Your Labs

Don't forget to run handin21 to turn in your lab files! You may run handin21 as many times as you want. Each time it will turn in any new work. We recommend running handin21 after you complete each program or after you complete significant work on any one program.