## Multi Way Decisions

The newest version of the quadratic solver is certainly a big improvement, but it still has some quirks. Here is another example run.

This program finds the real solutions to a quadratic Please enter the coefficients (a, b, c): 1, 2, 1 The solutions are: -1.0 -1.0

This is technically correct; the given coefficients produce an equation that has a double root at -1. However, the output might be confusing to some users. It looks like the program has mistakenly printed the same number twice. Perhaps the program should be a bit more informative to avoid confusion.

The double-root situation occurs when discrim is exactly 0. In this case, discRoot is also 0, and both roots have the value If we want to catch this special case, it looks like our program actually needs a three-way decision. Here's a quick sketch of the design.

Check the value of discrim when < 0: handle the case of no roots when = 0: handle the case of a double root when > 0: handle the case of two distinct roots.

One way to code this algorithm is to use two if-else statements. The body of an if or else clause can contain any legal Python statements, including other if or if-else statements. Putting one compound statement inside of another is called nesting. Here's a fragment of code that uses nesting to achieve a three-way decision :

print "Equation has no real roots" else:

print "There is a double root at", root else:

# Do stuff for two roots

If you trace through this code carefully, you will see that there are exactly three possible paths. The sequencing is determined by the value of discrim. A flowchart of this solution is shown in Figure 7.4. You can see that the top-level structure is just an if-else. (Treat the dashed box as one big statement.) The dashed box contains the second if-else nested comfortably inside the else part of the top-level decision.

Once again, we have a working solution, but the implementation doesn't feel quite right. We have finessed a three-way decision by using two two-way decisions. The resulting code does not reflect the true three-fold decision of the original problem. Imagine if we needed to make a five-way decision using this technique. The if-else structures would nest four levels deep, and the Python code would march off the right-hand edge of the page.

There is another way to write multi-way decisions in Python that preserves the semantics of the nested structures but gives it a more appealing look. The idea is to combine an else followed immediately by an if into a single clause called an elif.

if <condition1>:

<case1 statements> elif <condition2>:

<case2 statements> elif <condition3>:

<case3 statements>

else:

<default statements>

Figure 7.4: Three-way decision for quadratic solver using nested if-else.

This form is used to set off any number of mutually exclusive code blocks. Python will evaluate each condition in turn looking for the first one that is true. If a true condition is found, the statements indented under that condition are executed, and control passes to the next statement after the entire if-elif-else. If none of the conditions are true, the statements under the else are performed. The else clause is optional; if omitted, it is possible that no indented statement block will be executed.

Using an if-elif-else to show the three-way decision in our quadratic solver yields a nicely finished program.

# quadratic4.py import math def main():

print "This program finds the real solutions to a quadratic\n"

a, b, c = input("Please enter the coefficients (a, b, c): ")

print "\nThe equation has no real roots!" elif discrim == 0:

print "\nThere is a double root at", root else:

discRoot = math.sqrt(b *b-4*a*c) rootl = (-b + discRoot) / (2 * a) root2 = (-b - discRoot) / (2 * a) print "\nThe solutions are:", rootl, root2

0 0