Skip to content

Commit f6b0be5

Browse files
committed
update README with Candidate.add_votes refactoring
1 parent 2907646 commit f6b0be5

File tree

1 file changed

+63
-3
lines changed

1 file changed

+63
-3
lines changed

README.md

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,76 @@ to delete the original *clean_party* function in _lib/parser.py_. Ideally, we'll
218218

219219
##### Exercises
220220

221+
### Add vote
222+
223+
Each candidate has a single name and party (well, usually), and numerous county-level results.
224+
As part of our summary report, county-level results need to be rolled up into a racewide total for each candidate.
225+
At a high level, it seems natural for each candidate to track his or her own vote totals.
226+
227+
Below are a few other basic assumptions, or requirements, that will help us flesh out
228+
vote-handling code on the Candidate class:
229+
230+
* A candidate should start with zero votes
231+
* Adding a vote should increment the vote count
232+
* County-level results should be accessible
233+
234+
With this basic list of requirements in hand, we're ready to start coding. For each requirement, we'll start by
235+
writing a (failing) test that captures this assumnption; then we'll write code to make the test pass. The goal
236+
is to capture our assumptions in the form of tests, and then write code required to meet those assumnptions.
237+
238+
1. Add test for zero vote count as initial Candidate state ([elex4.3.0][])
239+
240+
> Note: We created a new *TestCandidateVotes* class with a *setUp* method that lets us
241+
> re-use the same candidate instance across all test methods. This
242+
> makes our tests less brittle -- e.g., if we add a parameter to the
243+
> Candidate class, we only have to update the candidate instance in
244+
> one the *setUp* method, rather than in every test method (as
245+
> we will have to in the *TestCandidate* class)
246+
247+
1. Run test; see it fail
248+
1. Update Candidate to have initial vote count of zero ([elex4.3.1][])
249+
1. Run test; see it pass
250+
1. Add test for *Candidate.add_votes* method ([elex4.3.2][])
251+
1. Run test; see it fail
252+
1. Create the *Candidate.add_votes* method ([elex4.3.3][])
253+
1. Run test; see it pass
254+
1. Create test for county_results attribute ([elex4.3.4][])
255+
1. Run test; see it fail
256+
1. Update *Candidate.add_votes* method to store county-level results ([elex4.3.5][])
257+
1. Run test; see it pass
258+
259+
[elex4.3.0]: https://github.com/PythonJournos/refactoring101/blob/elex4.3.0/elex4/tests/test_models.py "test_models.py"
260+
[elex4.3.1]: https://github.com/PythonJournos/refactoring101/blob/elex4.3.1/elex4/lib/models.py "lib/models.py"
261+
[elex4.3.2]: https://github.com/PythonJournos/refactoring101/blob/elex4.3.2/elex4/tests/test_models.py "test_models.py"
262+
[elex4.3.3]: https://github.com/PythonJournos/refactoring101/blob/elex4.3.3/elex4/lib/models.py "lib/models.py"
263+
[elex4.3.4]: https://github.com/PythonJournos/refactoring101/blob/elex4.3.4/elex4/tests/test_models.py "test_models.py"
264+
[elex4.3.5]: https://github.com/PythonJournos/refactoring101/blob/elex4.3.5/elex4/lib/models.py "lib/models.py"
265+
266+
#### Questions
267+
268+
* What does the TestCase *setUp* method do?
269+
* The test methods *test_vote_count_update* and *test_county_results_access*
270+
each add 20 votes to the candidate instance created in *setUp*. Why
271+
are candidate votes equal to 20 in both tests, instead of
272+
adding up to 40 in one of them (which would cause a test failure)?
273+
* In what order are test methods run?
274+
* What other unittest.TestCase methods are available?
275+
276+
#### Exercises
277+
278+
* Read the [unittest docs][] page.
279+
* The *Candidate.add_votes* method has a potential bug: It can't handle votes that are strings instead of proper integers.
280+
This bug might crop up if our parser fails to convert strings to integers. Write a test to capture the bug, then update
281+
the method to handle such "dirty data" gracefully.
282+
283+
[unittest docs]: http://docs.python.org/2/library/unittest.html
221284

222285
## TODO
223286

224-
* Candidate.votes
225287
* Race.office and district
226288
* Race.add_result (gets or creates candidate instance)
227289
* Candidate.winner, margin, vote_pct (since these require all Candidates to be available via parent Race class)
228290
* Write high-level tests for summarize output
229291
* Update Parser to return Candidate and Race classes
230292
* Update summary script to use Cand/Race objects returned by Parser class
231293

232-
233-

0 commit comments

Comments
 (0)