See All Titles |
![]() ![]() Lines 30-41The main driver of the application is main(), called from the top-level if the script is invoked directly. If imported, the importing function either manages the execution by calling doprob(), or calls main() for program control. main() simply calls doprob() to engage the user in the main functionality of the script and prompts the user to quit or to try another problem. Since the values and operators are chosen randomly, each execution of matheasy.py should be different. Here is what we got today (oh, and your answers may vary as well!): % matheasy.py 7 - 2 = 5 correct Try another? ([y]/n) 7 * 6 = 42 correct Try another? ([y]/n) 7 * 3 = 20 incorrect… try again 7 * 3 = 22 incorrect… try again 7 * 3 = 23 sorry… the answer is 7 * 3 = 21 7 * 3 = 21 correct Try another? ([y]/n) 7 - 5 = 2 correct Try another? ([y]/n) n Another useful application of apply() comes in terms of debugging or performance measurement. You are working on functions that need to be fully tested or run through regressions every night, or that need to be timed over many iterations for potential improvements. All you need to do is to create a diagnostic function that sets up the test environment, then calls the function in question. Because this system should be flexible, you want to allow the testee function to be passed in as an argument. So a pair of such functions, timeit() and testit(), would probably be useful to the software developer today. We will now present the source code to one such example of a testit() function (see Example 11.4). We will leave a timeit() function as an exercise for the reader (see Exercise 11.12 at end of chapter). This module provides an execution test environment for functions. The testit() function takes a function and arguments, then invokes that function with the given arguments under the watch of an exception handler. If the function completes successfully, a return value of 1 packaged withthe return value of the function is sent back to the caller. Any failure returns a status of 0 and the cause of the exception. (Exception is the root class for all exceptions; review Chapter 10 for details.) Example 11.4. Testing Functions (testit.py)testit() invokes a given function with its arguments, returning a 1 packaged with the return value of the function on success and 0 with the cause of the exception on failure. <$nopage> 001 1 #!/usr/bin/env python 002 2 003 3 def testit(func, *nkwargs, **kwargs): 004 4 005 5 try: 006 6 retval = apply(func, nkwargs, kwargs) 007 7 result = (1, retval) 008 8 except Exception, diag: 009 9 result = (0, str(diag)) 010 10 return result 011 11 012 12 def test(): 013 13 funcs = (int, long, float) 014 14 vals = (1234, 12.34, '1234', '12.34') 015 15 016 16 for eachFunc in funcs: 017 17 print '-' * 20 018 18 for eachVal in vals: 019 19 retval = testit(eachFunc, \ 020 20 eachVal) 021 21 if retval[0]: 022 22 print '%s(%s) =' % \ 023 23 (eachFunc.__name__, 'eachVal'), retval[1] 024 24 else: <$nopage> 025 25 print '%s(%s) = FAILED:' % \ 026 26 (eachFunc.__name__, 'eachVal'), retval[1] 027 27 028 28 if __name__ == '__main__': 029 29 test() 030 <$nopage> The unit tester function test() runs a set of numeric conversion functions on an input set of four numbers. There are two failure cases in this test set to confirm such functionality. Here is the output of running the script: % testit.py -------------------- int(1234) = 1234 int(12.34) = 12 int('1234') = 1234 int('12.34') = FAILED: invalid literal for int(): 12.34 -------------------- long(1234) = 1234L long(12.34) = 12L long('1234') = 1234L long('12.34') = FAILED: invalid literal for long(): 12.34 -------------------- float(1234) = 1234.0 float(12.34) = 12.34 float('1234') = 1234.0 float('12.34') = 12.34
|
© 2002, O'Reilly & Associates, Inc. |