CS21 Lab 9: Campaign Contributions

Due 11:59pm Saturday, Nov 23, 2013

Run update21, if you haven't already, to create the cs21/labs/09 directory. Then cd into your cs21/labs/09 directory and create the python program for lab 09 in this directory (handin21 looks for your lab 09 assignments in your cs21/labs/09 directory).

$ update21
$ cd cs21/labs/09
$ vim contributions.py
Campaign Contribution Database

The 2012 Presidential Election was the most expensive election in the history of the United states. In this lab we are going to look at individual contributions for Barack Obama and Mitt Romney during the 2012 election cycle (which is for the years 2011 and 2012). Your assignment this week is to create a program (contributions.py) that allows the user to explore our campaign contribution database.

The contribution database is contained in a single file, /usr/local/doc/contributions2012.txt, which contains individual contribution data for both candidates aggregated by zip code. Don't copy this file to your 09 directory, just use "/usr/local/doc/contributions2012.txt" in your python program. Each line of the file contains nine fields separated by commas:

  1. ZIP code
  2. city name
  3. state
  4. latitude
  5. longitude
  6. number of Obama contributions
  7. total amount of Obama contributions
  8. number of Romney contributions
  9. total amount of Romney contributions
The entry for Swarthmore is shown here:


If you want, you can look at the file with the less command:

    $ less /usr/local/doc/contributions2012.txt

Your program should prompt the user for either a zip code or at least part of a city name. Depending on what the user types, your program should do one of the following:

A sample run is shown here:

$ python contributions.py 
Welcome to contributions.py v1.0

Enter a zip code or the name of a city and I'll tell you
campaign contribution information about it. Enter a blank
line when you're finished...

zip or city: 19081

Contribution information for SWARTHMORE, PA 19081
Obama:    125 contributions totaling $  51018
Romney:    14 contributions totaling $  10060

Top ten contribution zip codes for Obama in PA:
        PHILADELPHIA, PA 19103:   361 contributions totaling $ 209770
        PHILADELPHIA, PA 19119:   384 contributions totaling $ 178534
          PITTSBURGH, PA 15217:   310 contributions totaling $ 153372
        PHILADELPHIA, PA 19106:   212 contributions totaling $ 114749
           BRYN MAWR, PA 19010:   223 contributions totaling $ 108930
               WAYNE, PA 19087:   239 contributions totaling $ 107962
        PHILADELPHIA, PA 19118:   221 contributions totaling $ 104645
           WYNNEWOOD, PA 19096:   190 contributions totaling $  96328
        PHILADELPHIA, PA 19147:   214 contributions totaling $  90611
        PHILADELPHIA, PA 19130:   181 contributions totaling $  90516

Top ten contribution zip codes for Romney in PA:
           BRYN MAWR, PA 19010:   184 contributions totaling $ 236000
               WAYNE, PA 19087:   164 contributions totaling $ 150680
           VILLANOVA, PA 19085:   123 contributions totaling $ 139125
           HAVERFORD, PA 19041:    93 contributions totaling $ 131430
             MALVERN, PA 19355:   137 contributions totaling $ 121189
           SEWICKLEY, PA 15143:   133 contributions totaling $ 117870
        WEST CHESTER, PA 19382:   120 contributions totaling $ 114207
        PHILADELPHIA, PA 19103:    94 contributions totaling $ 105400
            GLADWYNE, PA 19035:    92 contributions totaling $ 103400
            NEW HOPE, PA 18938:   107 contributions totaling $ 102150
pa image

zip or city: 8765309
Please enter a 5-digit zip code...

zip or city: london

Here are all the cities I can find that start with that and have
contributions, sorted by zip code... 

         LONDONDERRY, NH 03053, Obama:  $  8250, Romney  $  8420
         LONDONDERRY, VT 05148, Obama:  $   450, Romney  $  2000
              LONDON, KY 40741, Obama:  $   250, Romney  $  8800
              LONDON, KY 40743, Obama:  $     0, Romney  $  7250
              LONDON, KY 40744, Obama:  $  2875, Romney  $  5211
              LONDON, OH 43140, Obama:  $   250, Romney  $   493
         LONDONDERRY, OH 45647, Obama:  $     0, Romney  $   750
              LONDON, TX 76854, Obama:  $     0, Romney  $  3000

zip or city: 02474

Contribution information for ARLINGTON, MA 02474
Obama:    181 contributions totaling $  82137
Romney:    22 contributions totaling $  18300

Top ten contribution zip codes for Obama in MA:
           CAMBRIDGE, MA 02138:  1146 contributions totaling $ 686051
           CAMBRIDGE, MA 02139:   555 contributions totaling $ 273167
           BROOKLINE, MA 02446:   549 contributions totaling $ 267010
           BROOKLINE, MA 02445:   480 contributions totaling $ 253217
              BOSTON, MA 02116:   384 contributions totaling $ 229269
             BELMONT, MA 02478:   431 contributions totaling $ 220564
           CAMBRIDGE, MA 02140:   389 contributions totaling $ 219822
       JAMAICA PLAIN, MA 02130:   444 contributions totaling $ 212523
             CONCORD, MA 01742:   424 contributions totaling $ 212011
           LEXINGTON, MA 02421:   385 contributions totaling $ 194054

Top ten contribution zip codes for Romney in MA:
     WELLESLEY HILLS, MA 02481:   238 contributions totaling $ 320100
              WESTON, MA 02493:   246 contributions totaling $ 313576
              BOSTON, MA 02116:   204 contributions totaling $ 301444
             BELMONT, MA 02478:   188 contributions totaling $ 232584
             CONCORD, MA 01742:   106 contributions totaling $ 128356
             WAYLAND, MA 01778:   100 contributions totaling $ 117120
           WELLESLEY, MA 02482:    89 contributions totaling $ 115555
              BOSTON, MA 02108:    81 contributions totaling $ 109700
       CHESTNUT HILL, MA 02467:    82 contributions totaling $ 104910
               DOVER, MA 02030:    77 contributions totaling $ 103450

ma image

zip or city: pickles

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

zip or city: vien

Here are all the cities I can find that start with that and have

              VIENNA, ME 04360, Obama:    1000, Romney       0
              VIENNA, VA 22180, Obama:   42545, Romney   47995
              VIENNA, VA 22181, Obama:   87293, Romney   66798
              VIENNA, VA 22182, Obama:   55355, Romney  127409
              VIENNA, VA 22183, Obama:       0, Romney    1925
              VIENNA, WV 26105, Obama:    1750, Romney   11750
              VIENNA, GA 31092, Obama:    1000, Romney     500
              VIENNA, OH 44473, Obama:     500, Romney    3250
              VIENNA, IL 62995, Obama:       0, Romney    2500
zip or city: <Enter>
Requirements and tips...

You should practice good top-down design, incrementally implement and test your solution, and document your code with comments. 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 contributions2012.txt file, store the data in a python list, where each item in the list is itself a list of contribution data for one zip code: [zip, city, state, latitude, longitude, number of Obama contributions, total Obama contributions, number of Romney contributions, total Romney contributions]. Your "list of lists" should look like this:
    [[contribution data from line 1], [contribution data from line 2], ..., 
     [contribution data from last line]]
  2. When you prompt the user to enter a location, the user can enter either a zip code or a city (or part of a city). Your program must determine if the user input looks like a zip code, a city, or garbage, and do the right thing (Hint: use str methods like isdigit() and/or isalpha()).
  3. The contribution 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 (e.g., for zip codes or for cities in a given state) must be as efficient as possible. That is, you should use binary search or linear search where appropriate.
  5. If you cannot find an entry for a particular city or zip code, inform the user that you cannot find that location and prompt them to enter another location.
  6. For reporting the top contribution zip codes in each state, you should sort this data from largest to smallest in total contributions. Also, most big cities have more than one zip code, so you may see the same city listed multiple times with different zip codes.
  7. 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.
  8. It is best to store the zip codes as strings. Some zip codes begin with a zero, and python removes leading zeros from integers.
  9. Some of the data (latitude, longitude, contributions, etc.) will need to be converted from strings to floats or integers.
  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 zip codes (using the latitude as the y coordinate and the longitude as the x coordinate) showing where Obama got more contributions than Romney with a blue point and showing where Romney got more contributions with a red point. If neither candidate received contributions from a zip code, do not plot a point for that zip code.
    from boundaries import *
    state = "VA"
    w = getStateGraphWin(state)
    if w != None:
      # plot all zip codes for this state here...use lat/long for each zip code

Data Sources

The contribution data used in this lab was compiled from opensecrets.org. We tried to compile this data as accurately as possible, but there are likely inaccuracies and omissions, so use the data for entertainment purposes only. :) If you find an error with our data, let us know and we will be happy to fix it, but we are not trying to maintain a comprehensive list. If you are interested in learning more about money in politics, opensecrets.org is a great resource to help you to learn more.


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

Hacker's Challenge
There are lots of ways of extending this assignment. Any extensions should not be attempted until you are completely finished with all other parts of the assignment. It will also not get you any extra points -- you will only be rewarded with extra knowledge and satisfaction. :) Here are some suggestions of how you can continue to explore the campaign finance data.