Guard clauses

We know this routine will always fail with negative numbers so we can detect this precondition early on and raise an exception at that point, a technique called a guard clause:

def sqrt(x):
"""Compute square roots using the method of Heron of Alexandria.

Args:
x: The number for which the square root is to be computed.

Returns:
The square root of x.

Raises:
ValueError: If x is negative.
"""

if x < 0:
raise ValueError("Cannot compute square root of negative
number{}".format(x))


guess = x
i = 0
while guess * guess != x and i < 20:
guess = (guess + x / guess) / 2.0
i += 1
return guess

The test is a simple if-statement and a call to raise passing a newly minted exception object. The ValueError() constructor accepts an error message. See how we also modify the docstring to make it plain which exception type will be raised by sqrt() and under what circumstances.

But look what happens if we run the program – we're still getting a traceback and an ungraceful program exit:

$ python roots.py
3.0
1.41421356237
Traceback (most recent call last):
File "sqrt.py", line 25, in <module>
print(sqrt(-1))
File "sqrt.py", line 12, in sqrt
raise ValueError("Cannot compute square root of negative number
{0}".format(x))

ValueError: Cannot compute square root of negative number -1

This happens because we forgot to modify our exception handler to catch ValueError rather than ZeroDivisionError. Let's modify our calling code to catch the right exception class and also assign the caught exception object to a named variable so we can interrogate it after it has been caught. In this case our interrogation is simply to print the exception object, which knows how to display itself as the message to stderr:

import sys

def main():
try:
print(sqrt(9))
print(sqrt(2))
print(sqrt(-1))
print("This is never printed.")
except ValueError as e:
print(e, file=sys.stderr)

print("Program execution continues normally here.")

Running the program again, we can see that our exception is being gracefully handled:

$ python3 sqrt.py
3.0
1.41421356237
Cannot compute square root of negative number -1
Program execution continues normally here.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset