CS21 Lab 9: Zipcodes

Due 11:59pm Saturday, April 11th

Run update21, to create the cs21/labs/09 directory (and some additional files). Then cd into your cs21/labs/09 directory and create the python programs for lab 9 in this directory

ZIP Code Database
Is 90210 really the zip code for Beverly Hills and how many people actually live there? What is the ZIP code for Truth or Consequences, NM? Your assignment this week is to create a program (zipcodes.py) that allows the user to explore a zipcode database.

We have a file, /usr/local/doc/zips.txt, which contains zipcode data for most of the United States (don't copy this file to your 09 directory, just use "/usr/local/doc/zips.txt" in your python program). Each line of the file contains nine fields separated by commas:

  1. ZIP code
  2. State
  3. City name
  4. County name
  5. Latitude
  6. Longitude
  7. Population
  8. Area in sq. miles
  9. Population density in people per square mile
The entry for Swarthmore is shown here:

19081,PA,Swarthmore,Delaware,39.9,-75.35,10337,2.234,4627.126231

If you want, you can view the file with less: less /usr/local/doc/zips.txt

Your program should prompt the user with a menu of 5 choices:

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

For option 1 (Find a zip code) you should:

A sample run showing option 1 is shown here:

$ python zipcodes.py 

Welcome to the zipcode program.  Please select one of the
following choices:

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

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

Swarthmore, PA 19081
Delaware County
Population: 10337
Area: 2.23 square miles
Density: 4627 people per square mile

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 1
Enter a 5-digit zip code: 00000
This zipcode does not exist.

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 5
Goodbye!

For option 2 (Show state populations) you should:

A sample run showing option 2 is shown here:
 
$ python zipcodes.py 

Welcome to the zipcode program.  Please select one of the
following choices:

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 2
Enter a state: Penn
Penn is not a valid state abbreviation.  Try again.
Enter a state: pa
The 20 zipcodes with the higest population in PA is:

19120 Philadelphia       68104
19124 Philadelphia       66691
19143 Philadelphia       64849
19111 Philadelphia       63090
17603 Lancaster          61973
19134 Philadelphia       60675
15601 Greensburg         59483
19020 Bensalem           55493
19446 Lansdale           55138
19149 Philadelphia       55006
19140 Philadelphia       54133
17602 Lancaster          52452
19382 West Chester       52388
19320 Coatesville        52342
19104 Philadelphia       51808
19067 Morrisville        51334
17331 Hanover            50292
17601 Lancaster          49779
18102 Allentown          49779
19148 Philadelphia       49732

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 5
Goodbye!
PA Image

For option 3 (Find a city) you should:

A sample run showing option 3 is shown here:
 
$ python zipcodes.py 
Welcome to the zipcode program.  Please select one of the
following choices:

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 3
Enter a city to lookup: london

Here are all the cities I can find that start with that...
London, OH 43140 Population: 24066
Londonderry, NH 03053 Population: 23957
London, KY 40741 Population: 21875
London, KY 40744 Population: 18334
London, AR 72847 Population: 2850
Londonderry, OH 45647 Population: 2484
Londonderry, VT 05148 Population: 1140
London Mills, IL 61544 Population: 713
London, TX 76854 Population: 401
London, KY 40743 Population: 229
London, WV 25126 Population: 58

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 3
Enter a city to lookup: ponies

Sorry... I can't find anything for that city name...

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 5
Goodbye!

For option 4 (Population density of a county) you should:

A sample run showing option 3 is shown here:
 
$ python zipcodes.py 
Welcome to the zipcode program.  Please select one of the
following choices:

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 4
Enter a state: pa
Enter a county in PA: Delaware

Here are the cities in Delaware PA, sorted by population density:
Upper Darby          19082 Pop Density:  15829 people per square mile
Darby                19023 Pop Density:  11099 people per square mile
Prospect Park        19076 Pop Density:   8758 people per square mile
Clifton Heights      19018 Pop Density:   8636 people per square mile
Drexel Hill          19026 Pop Density:   8489 people per square mile
Glenolden            19036 Pop Density:   8464 people per square mile
Yeadon               19050 Pop Density:   7620 people per square mile
Norwood              19074 Pop Density:   7580 people per square mile
Folsom               19033 Pop Density:   7051 people per square mile
Holmes               19043 Pop Density:   6727 people per square mile
Morton               19070 Pop Density:   6713 people per square mile
Folcroft             19032 Pop Density:   6502 people per square mile
Havertown            19083 Pop Density:   6456 people per square mile
Chester              19013 Pop Density:   6138 people per square mile
Woodlyn              19094 Pop Density:   5494 people per square mile
Ridley Park          19078 Pop Density:   5473 people per square mile
Brookhaven           19015 Pop Density:   5072 people per square mile
Sharon Hill          19079 Pop Density:   4964 people per square mile
Swarthmore           19081 Pop Density:   4627 people per square mile
Broomall             19008 Pop Density:   3132 people per square mile
Springfield          19064 Pop Density:   3072 people per square mile
Wallingford          19086 Pop Density:   2964 people per square mile
Marcus Hook          19061 Pop Density:   2850 people per square mile
Eddystone            19022 Pop Density:   2788 people per square mile
Bryn Mawr            19010 Pop Density:   2504 people per square mile
Aston                19014 Pop Density:   2357 people per square mile
Haverford            19041 Pop Density:   1892 people per square mile
Cheyney University   19319 Pop Density:   1785 people per square mile
Essington            19029 Pop Density:   1718 people per square mile
Media                19063 Pop Density:   1547 people per square mile
Villanova            19085 Pop Density:   1478 people per square mile
Garnet Valley        19060 Pop Density:   1449 people per square mile
Thornton             19373 Pop Density:   1031 people per square mile
Glen Mills           19342 Pop Density:    928 people per square mile
Newtown Square       19073 Pop Density:    886 people per square mile
Chadds Ford          19317 Pop Density:    452 people per square mile
Chester Heights      19017 Pop Density:    391 people per square mile
Philadelphia         19113 Pop Density:     35 people per square mile

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 4
Enter a state: NJ
Enter a county in NJ: NotACounty

I couldn't find NotACounty county in NJ.

1: Find a zip code
2: Show state populations
3: Find a city
4: Population density of a county
5: Quit

Choice? 5
Goodbye!

For option 5 (Quit) you should:

Requirements 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.
  1. When you read the data from the zips.txtfile, store the data in a python list, where each item in the list is itself a list of zipcode data for one zipcode: [zipcode, state, city, county, latitude, longitude, population, area, popDensity]. Your "list of lists" should look like this:
    [[zipcode data from line 1], [zipcode data from line 2], 
    ..., [zipcode data from last line]]
    
  2. Validate all menu selections. If they user doesn't enter a valid number (1-5), let the user know it wasn't a valid selection and prompt them again for a new menu item.
  3. The file lists all zip codes in sorted order, so it is not necessary to modify the order of items when you read the data in.
  4. Your searches must be as efficient as possible. That is, you should use binary search or linear search where appropriate.
  5. Since our data is stored in a python list of lists, you will need to modify one of our sort functions from class to handle this data. You should not use the built-in python sort or sorted functions.
  6. You'll be doing several sorts for this lab. The easiest way to do this is have one generic sorting function that takes two parameters. The first is the full list of zip codes, and the second is an index telling you what item in that list you should be sorting on. You'll do the sorting based on the values of that index. For example if you wanted to do a sort on population density, the index would be 8 in this case, as that is the index for the population density field.
  7. It is best to store the zipcodes as strings. Some zipcodes begin with a zero, and python removes leading zeros from integers.
  8. Some of the data (e.g., latitude, longitude, population, etc.) will need to be converted from strings to floats or integers.
  9. Population density is stored as a float, but it is nicer to print it out as a integer when displaying. The string format of "%.0f" will do this for you.
  10. We encourage you to finish the text part of this program before you add the graphics. This makes testing easier and faster. Once you have the text portion working, then add the graphics.
  11. To plot the state boundaries we have written some functions to create the graphics window already scaled to appropriate dimensions for the given state. You should be able to use the code below to create the graphics window with the state boundary already drawn. Your program must then draw points for all zipcodes (using the latitude as the y coordinate and the longitude as the x coordinate).
    from boundaries import *
    
    state = "VA"
    win = getStateGraphWin(state)
    if win != None:
      # plot all zipcodes for this state here...use lat/long for each zipcode
      win.getMouse()
      win.close()
    
    

Missing Data

The zipcode 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. If your favorite US city or hometown in the US is missing and you know all the info (ZIP, city name, county name, state, lat, long, and population), let us know and we will be happy to add a few cities, but we are not trying to maintain a comprehensive list.

Submit

Once you are satisfied with your program, hand it in by typing handin21 in a terminal window.