Table Of Contents

Previous topic

Function breakdown and Testing Intro

Next topic

OO Design and Refactoring

This Page

Modules, packages, oh my!!

In this third phase, we chop up our original module into a legitimate Python package. The new directory structure is (hopefully) self-explanatory:

├── elex3
│   ├──
│   ├── lib
│   │   ├──
│   │   ├──
│   │   ├──
│   │   └──
│   ├── scripts
│   │   └──
│   └── tests
│       ├──
│       ├── sample_results.csv
│       ├── sample_results_parsed.json
│       ├── sample_results_parsed_tie_race.json
│       ├──
│       └──
  • lib/ contains re-usable bits of code.
  • scripts/ contains...well..scripts that leverage our re-usable code.
  • tests/ contains tests for re-usable bits of code and related fixtures.

Note that we did not change any of our functions. Mostly we just re-organized them into new modules, with the goal of grouping related bits of logic in common-sense locations. We also updated imports and “namespaced” them of our own re-usable code under elex3.lib.

Here’s where we start seeing the benefits of the tests we wrote in the elex2 phase. While we’ve heavily re-organized our underlying code structure, we can run the same tests (with a few minor updates to import statements) to ensure that we haven’t broken anything.

Note: You must add the refactoring101 directory to your PYTHONPATH before any of the tests or script will work.
$ cd /path/to/refactoring101

$ nosetests -v elex3/tests/*.py
$ python elex3/scripts/

Check out the results of the command. The new summary_results.csv should be stored inside the elex3 directory, and should match the results file produced by elex2/


  • Do you like the package structure and module names? How would you organize or name things differently?
  • Why is it necessary to add the refactoring101/ directory to your PYTHONPATH?
  • What are three ways to add a library to the PYTHONPATH?
  • What is a class? What is a method?
  • What is an object in Python? What is an instance?
  • What is the init method on a class used for?
  • What is self and how does it relate to class instances?


  • Look at the original results data, and model out some classes and methods to reflect “real world” entities in the realm of elections.
  • Examine functions in lib/ and try assigning three functions to one of your new classes.
  • Try extracting logic from the summarize function and re-implement it as a method on one of your classes.