# PyBat..TEMPLATE.py David MacQuigg 11-Feb-09 # Use this module as a template to create new exercises. # The essentials are: # 1) Clear, concise statement of the problem in the module docstring. # 2) Examples worthy of documentation in the function docstring. # 3) Student input in the body of the function. # 4) Student-written tests in the unittests docstring. # 5) Student comments in the function, the unittests, and footnotes. [Note 1] ''' Given 2 lists, a and b, concatenate the two lists (a then b), and return the leftmost 2 elements. The lists may be any length, including 0. Raise an AssertionError if less than two elements are available. ''' def make2(a, b): ''' >>> make2([4, 5], [1, 2, 3]) # end-of-line comments can go in doctests [4, 5] >>> make2([4], [1, 2, 3]) [4, 1] >>> make2([], [1, 2]) [1, 2] >>> make2([], [1]) Traceback (most recent call last): - - - AssertionError ''' c = a + b # concatenate two lists assert len(c) >= 2 # check for at least two elements return c[:2] # slice off the left end if __name__ == '__main__': # skip if this module has been imported [2] def unittests(): # Make these tests complete. [3] ''' >>> make2([4, 5], [1, 2, 3]) [4, 5] >>> make2([4], [1, 2, 3]) [4, 1] >>> make2([], [1, 2]) [1, 2] >>> make2([], [1]) Traceback (most recent call last): - - - AssertionError >>> make2([], []) Traceback (most recent call last): - - - AssertionError >>> make2([1, 2], []) [1, 2] >>> make2([3], [1, 2, 3]) [3, 1] >>> make2([3], [1]) [3, 1] >>> make2([3, 1, 4], []) [3, 1] >>> make2([1], [1]) [1, 1] >>> make2([1, 2, 3], [7, 8]) [1, 2] >>> make2([7, 8], [1, 2, 3]) [7, 8] >>> make2([7], [1, 2, 3]) [7, 1] >>> make2([5, 4], [2, 3, 7]) [5, 4] ''' from doctest import testmod testmod(verbose=True) ''' [1] Footnotes should be used when end-of-line comments are too short. [2] When a module is run directly from the interpreter, its __name__ is changed from the original filename to '__main__'. Unit tests and other stuff not necessary to the importing module, should be put in this section to reduce memory comsumption and namespace clutter. [3] Doctests should be repeated in the unittests function, because doctests evolve as later developers gain more insight and figure out how to say more with fewer words. Unittests are intended to cover everything, and can be messy. It is seldom necessary to remove old unittests. '''