Before you start, copy the contents of the subfolder carpentry_exercises
into your exercise repository.
Goals: Write a test suite using the unittest
module.
Write a test file, test_center.py
, that tests the function center from the module string
(http://docs.python.org/library/string.html#string.center). At each step, run the tests and make sure they pass.
In the file, write three test cases:
a) The first test case checks the functionality of the function, leaving the argument fillchar set to its default value. Control that the function works as advertised for
b) The second test case checks the functionality of string.center
, with fillchar set to specific values. Test using a letter, a numerical value, and the default value.
c) Finally, test that string.center
raises a TypeError
when fillchar is set to an empty string, and to a string longer than one character.
Goals: Use the numpy.testing
utility functions and numerical fuzzing techniques to test numerical code.
Write a new test suite, test_multinomial.py
, to test the function numpy.random.multinomial
(http://tinyurl.com/448f5dz).
a) Read the documentation and play with the function using ipython
until you are sure you understand how it works (always leave the size argument to its default value).
b) Write a first test case, testing the function in deterministic cases:
c) Write a numerical fuzzing test case that verifies that, with a large number of samples, the sampling frequency of each entry is close to its probability.
Goals: General practice of debugging and unit testing using agile development techniques.
Enter the directory deceivingly_simple
. The file maxima.py
contains a function, find_maxima
, that finds local maxima in a list and returns their indices. Please read the last sentence again: it returns the indices, not the values. ;)
a) Using ipython
, test the function with these input arguments and others of your own invention until you are satisfied that it does the right thing for typical cases (remember that the function returns the indices of the maxima):
x = [0, 1, 2, 1, 2, 1, 0]
x = [-i**2 for i in range(-3, 4)]
x = [numpy.sin(2*alpha) for alpha in numpy.linspace(0.0, 5.0, 100)]
b) Now try with the following inputs:
x = [4, 2, 1, 3, 1, 2]
x = [4, 2, 1, 3, 1, 5]
x = [4, 2, 1, 3, 1]
For each bug you find, solve it using the agile programming strategy:
i. Isolate the bug using a debugger
ii. Write a new test case that reproduces the bug. Try to make the test case as simple as possible; here, this means using the simplest input data that still triggers the bug
iii. Correct the code
iv. Makesurethatallthetestspass
c) You may think that the code is now clean and robust... Look at the output of the function for the input list
x = [1, 2, 2, 1]
Does the output correspond to your intuition? Think about a reasonable default behavior in this situation, and meditate on how such a simple function can hide so many complications
d) (optional) Implement the “reasonable behavior” you conceived in c), adding a new test. Make sure that your function handles these inputs correctly (include them in the tests):
x = [1, 2, 2, 3, 1]
x = [1, 3, 2, 2, 1]
x = [3, 2, 2, 3]
e) (optional) Run a coverage analysis on the tests; there should be at least one statement that is not covered. Write a test that covers it and debug the code.