documentatio ion testin ing and debugg gging
play

Documentatio ion, , testin ing and debugg gging docstring - PowerPoint PPT Presentation

Documentatio ion, , testin ing and debugg gging docstring defensive programming assert test driven developement assertions testing unittest debugger static type checking (mypy) Ensuring good quality code ?


  1. Documentatio ion, , testin ing and debugg gging  docstring  defensive programming  assert  test driven developement  assertions  testing  unittest  debugger  static type checking (mypy)

  2. Ensuring good quality code ? Design phase Usage Development (hopefully) correct program User runs Coding program Idea success Fix bug Testing Goal  Develop programs that runs forever / crash / work correctly Find bug incorrect output /  Tools and techniques explosion / ...

  3. What is is good code ?  Readability • well-structured • documentation • comments • follow some standard structure (easy to recognize, follow PEP8 Style Guide)  Correctness • outputs the correct answer on valid input • eventually stops with an answer on valid input (should not go in infinite loop)  Reusable...

  4. Why ? Documentation Testing Debugging  specification of  Correct  Where is the #!¤$ functionality implementation ? bug ?  docstring  Try to predict behavior on • for users of the code unknown input ? • modules • methods  Performance • classes guarantees ?  comments • for readers of the code ” Program testing can be used to show the presence of bugs, but never to show their absence ” ̶ Edsger W. Dijkstra

  5. | Built-in exceptio ions +-- OSError | +-- BlockingIOError | +-- ChildProcessError (class hierarchy) | +-- ConnectionError | | +-- BrokenPipeError | | +-- ConnectionAbortedError BaseException | | +-- ConnectionRefusedError +-- SystemExit | | +-- ConnectionResetError +-- KeyboardInterrupt | +-- FileExistsError docs.python.org/3/library/exceptions.html +-- GeneratorExit | +-- FileNotFoundError +-- Exception | +-- InterruptedError +-- StopIteration | +-- IsADirectoryError +-- StopAsyncIteration | +-- NotADirectoryError +-- ArithmeticError | +-- PermissionError | +-- FloatingPointError | +-- ProcessLookupError | +-- OverflowError | +-- TimeoutError | +-- ZeroDivisionError +-- ReferenceError +-- AssertionError +-- RuntimeError +-- AttributeError | +-- NotImplementedError +-- BufferError | +-- RecursionError +-- EOFError +-- SyntaxError +-- ImportError | +-- IndentationError | +-- ModuleNotFoundError | +-- TabError +-- LookupError +-- SystemError | +-- IndexError +-- Warning | +-- KeyError +-- DeprecationWarning +-- MemoryError +-- PendingDeprecationWarning +-- NameError +-- RuntimeWarning | +-- UnboundLocalError +-- SyntaxWarning +-- TypeError +-- UserWarning +-- ValueError +-- FutureWarning | +-- UnicodeError +-- ImportWarning | +-- UnicodeDecodeError +-- UnicodeWarning | +-- UnicodeEncodeError +-- BytesWarning | +-- UnicodeTranslateError +-- ResourceWarning

  6. Testin ing for unexpected behaviour ? infinite-recursion1.py infinite-recursion3.py def f(depth): import sys f(depth + 1) # infinite recursion def f(depth): f(0) if depth > 100: print("runaway recursion???") Python shell sys.exit() # system function | RecursionError: maximum recursion depth exceeded f(depth + 1) raises SystemExit f(0) infinite-recursion2.py Python shell def f(depth): if depth > 100: | runaway recursion??? print("runaway recursion???") raise SystemExit # raise built-in exception  let the program eventually fail f(depth + 1)  check and raise exceptions f(0) Python shell  check and call sys.exit | runaway recursion???

  7. Catching unexpected behaviour – assert infinite-recursion4.py def f(depth): assert depth <= 100 # raise exception if False f(depth + 1)  keyword assert checks if f(0) Python shell boolean expression is true, | File "...\infinite-recursion4.py", line 2, in f if not, raises exception | assert depth <= 100 | AssertionError AssertionError infinite-recursion5.py def f(depth):  optional second parameter assert depth <= 100, "runaway recursion???" f(depth + 1) passed to the constructor of f(0) the exception Python shell | File ".../infinite-recursion5.py", line 2, in f | assert depth <= 100, "runaway recursion???" | AssertionError: runaway recursion???

  8. isabling assert statements Dis  assert statements are good to help check correctness of program – but can slow down program  invoking Python with option – O disables all assertions (by setting __debug__ to False ) docs.python.org/3/reference/simple_stmts.html#assert

  9. Example

  10. Fir irst try ry... (seriously, , the bugs were not on purpose) intsqrt_buggy.py def int_sqrt(x): low = 0 high = x while low < high - 1: mid = (low + high) / 2 if mid ** 2 <= x: low = mid else: high = mid return low Python shell > int_sqrt(10) | 3.125 # 3.125 ** 2 = 9.765625 > int_sqrt(-10) | 0 # what should the answer be ?

  11. Let u us add a specificatio ion...  all methods, classes, and intsqrt.py modules can have a def int_sqrt(x): docstring (ideally """Compute the integer square root of an integer x. docstring have) as a specification input Assumes that x is an integer and x >= 0 requirements  for methods: summarize Returns integer floor(sqrt(x))""" output purpose in first line, guarantees ... followed by input Python shell requirements and ouput > help(int_sqrt) guarantees | Help on function int_sqrt in module __main__:  the docstring is assigned | | int_sqrt(x) to the object’s __doc__ | Compute the integer square root of an integer x. attribute | Assumes that x is an integer and x >= 0 | Returns integer floor(sqrt(x)) PEP 257 -- Docstring Conventions www.python.org/dev/peps/pep-0257/

  12. Let u us check in input requirements...  doing explicit checks for intsqrt.py valid input arguments is def int_sqrt(x): """Compute the integer square root of an integer x. part of defensive programming and helps Assumes that x is an integer and x >= 0 spotting errors early Returns integer floor(sqrt(x))""" (instead of continuing assert isinstance(x, int) check input assert 0 <= x requirements using likely wrong ... values... resulting in a Python shell final meaningless error) > int_sqrt(-10) | File "...\int_sqrt.py", line 7, in int_sqrt | assert 0 <= x | AssertionError

  13. Let u us check if if output correct... intsqrt.py def int_sqrt(x):  output check identifies """Compute the integer square root of an integer x. the error Assumes that x is an integer and x >= 0 mid = (low+high) / 2 Returns integer floor(sqrt(x))"""  should have been assert isinstance(x, int) mid = (low+high) // 2 assert 0 <= x ...  The output check helps assert isinstance(result, int) check assert result ** 2 <= x < (result + 1) ** 2 output us to ensure that return result functions specification is Python shell guaranteed in > int_sqrt(10) applications | File "...\int_sqrt.py", line 20, in int_sqrt | assert isinstance(result, int) | AssertionError

  14. Let u us test s some in input valu lues... intsqrt.py def int_sqrt(x):  test identifies ... wrong output for x = 1 assert int_sqrt(0) == 0 assert int_sqrt(1) == 1 assert int_sqrt(2) == 1 assert int_sqrt(3) == 1 assert int_sqrt(4) == 2 assert int_sqrt(5) == 2 assert int_sqrt(200) == 14 Python shell | Traceback (most recent call last): | File "...\int_sqrt.py", line 28, in <module> | assert int_sqrt(1) == 1 | File "...\int_sqrt.py", line 21, in int_sqrt | assert result ** 2 <= x < (result + 1) ** 2 | AssertionError

  15. Let u us check progress of alg lgorithm... intsqrt.py ...  test identifies wrong low, high = 0, x output for x = 1 while low < high - 1: check invariant assert low ** 2 <= x < high ** 2  but invariant apparently for loop mid = (low + high) / 2 correct ??? if mid ** 2 <= x:  problem low = mid else: low == result == 0 high = mid high == 1 result = low implies loop never entered ...  output check identifies the Python shell error | Traceback (most recent call last): | File "...\int_sqrt.py", line 28, in <module> high = x | assert int_sqrt(1) == 1  should have been | File "...\int_sqrt.py", line 21, in int_sqrt | high = x + 1 assert result ** 2 <= x < (result + 1) ** 2 | AssertionError

  16. intsqrt.py def int_sqrt(x): """Compute the integer square root of an integer x. Fin inal program Assumes that x is an integer and x >= 0 Returns the integer floor(sqrt(x))""" assert isinstance(x, int) assert 0 <= x low, high = 0, x + 1 We have used assertions to: while low < high - 1: assert low ** 2 <= x < high ** 2  Test if input arguments / usage is mid = (low + high) // 2 if mid ** 2 <= x: valid (defensive programming) low = mid else:  Test if computed result is correct high = mid result = low  Test if an internal invariant in the assert isinstance(result, int) computation is satisfied assert result ** 2 <= x < (result + 1) ** 2  Perform a final test for a set of return result test cases (should be run assert int_sqrt(0) == 0 whenever we change anything in assert int_sqrt(1) == 1 assert int_sqrt(2) == 1 the implementation) assert int_sqrt(3) == 1 assert int_sqrt(4) == 2 assert int_sqrt(5) == 2 assert int_sqrt(200) == 14

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend