Chapter 5 - Conditional statements

Decisions, decisions

It is not hard to think of situations where your actions are conditional, that is, you decide what to do based on the answer to some question or on some condition that you observe. For example,

_static/if_statement_1.png

Frequently we also have an alternative in mind, too:

_static/if_statement_2.png

Notice that there is a kind of structure to the description above: a set of things we do if it’s raining, and an alternative set of things we do if it isn’t raining. It is convenient to use indentation to help us visually group together these related actions. The fact that “go to work” isn’t indented along with “put on sneakers” suggests that we have to go to work whether it’s raining or not.

The structure of decisions like these can be visualized nicely with flowcharts. Remember from unit 1 that we use a diamond-shaped block for a decision point in a flowchart, so the first example would look like this:

_static/if_statement_4.png

And the second example would look like this:

_static/if_statement_3.png

The flowcharts make one thing very clear, anyway. There are two branches or paths through the diagram, and you’ll do the things on the “Yes” branch, OR you’ll do the things on the “No” branch, but there’s no possible path along the arrows in which you do the things on both branches.

Also notice the small circle where the “Yes” and “No” branches come back together. That is an important feature that reflects the way that conditional statements are used in programming. You’ll take one of two alternative paths that have different actions on them, but both paths MUST eventually end up at the same point again.

Boolean expressions

As you might expect, we want to be able to write statements in Python representing conditional actions. What’s a “condition”, anyway? By “condition”, we just mean an expression whose value is either true or false. For example, what if you type an expression like “2 < 3” in the shell or in an activecode window?

Well, that sort of makes sense. Let’s try another one.

We know that every value has a type, so what is the type of an expression like 2 < 3? It obviously isn’t an int, a float, or a string, the three types we know about so far. We can find out with the type function.

This is something we haven’t seen before. It turns out that “bool” is short for “boolean”, a type that has just two possible values, represented by the Python literals True and False. We can write simple boolean expressions using the relational operators for greater-than and less-than as in the examples above. There are six relational operators in all. You’ve seen them all in math classes, but in Python we have to use slightly different symbols, as shown in the table below.

_static/math_symbols_1.png

That last one is somewhat curious. Remember, the symbol = is not an equals sign in Python, it is the assignment operator. So to test whether two expressions are equal, we need a different symbol. Like several other programming languages, Python uses a double equals sign (==) for this purpose:

We read the first line as “x gets the value 42”, which is a statement that changes the value of x. We read the second line as “x is equal to 43”, which is an expression with the value False. It doesn’t change the value of x.

Be careful! Using an assignment operator, that is, a single equals sign, when you really want to check equality is definitely one of the all-time top ten programming errors. Notice that if we accidentally wrote x = 43 in the second line above, it wouldn’t check whether x was equal to 43, it would change the value of x to be 43!

Conditional statements

Let’s start with an example. Here’s a short script that reads an exam score from a user and then prints a brief response.

Let’s examine this more closely. Notice there are two new keywords, if and else.

_static/if_statement_5.png

Note that all the statements between if and else are indented by the same amount, and the statements after the else and before the last print statement are also indented. This is important, because it is from the indentation that the Python interpreter figures out which statements are in each block. The print statement at the end is not part of either block, and so it gets executed whether or not the score is below 65.

The general syntax is for this conditional statement is:

_static/if_else_explanation_1.png

In general, a statement block is just a group of statements that are indented by the same amount.

The example above shows one form of conditional statement. There are actually three forms in all. The second form is just like the first, except that there is no else block. In this script, when the score is 65 or more, the only output is “Bye”.

This form of the conditional statement has the following general syntax:

_static/if_else_explanation_2.png

Since there’s no else block, if the condition is false, we just do nothing.

A problem-solving exercise

Let’s try one example as a problem-solving exercise. Suppose there is a company bettermousetraps.com that sells mousetraps online. Mousetraps cost $2.00 each plus .50 each for shipping. However, shipping is free for orders of 30 or more mousetraps. Write an interactive script that reads a number of mousetraps from the user and then prints the total order cost.

First, let’s work out an example or two to make sure we know what we’re doing. How much would it be for 10 mousetraps?

10 * 2.00 = 20.00 for the mousetraps

Are we ordering 30 or more?

No, so we pay 10 * .50 = 5.00 for shipping

Total 20.00 + 5.00 = 25.00

How about for 100 mousetraps?

100 * 2.00 = 200.00 for the mousetraps

Are we ordering 30 or more?

Yes, so shipping is free.

Total 200.00

What about for exactly 30?

50 * 2.00 = 100.00 for the mousetraps

Are we ordering 30 or more?

Yes, so shipping is free.

Total 100.00

The value of exactly 30 mousetraps is called a “boundary condition” since it represents the boundary between two alternative actions, namely, free shipping and non-free shipping. (It is a good idea to always check the boundary conditions, because that’s a common place to make mistakes.)

Now that we have some examples worked out, it should be easy to write the code. Just look at the examples, and do the same thing. Let’s assume we have a variable num that contains the number of mousetraps that are being ordered.

_static/mousetrap_1.png

Well, that seems reasonable enough. But remember, there was a decision to make in order to compute the shipping cost. We’d better try another example in which the decision comes out “Yes” instead of “No”.

_static/mousetrap_2.png

One example of a completed script would look like this. The code is exactly as above, where we added an if statement to distinguish the two cases, non-free shipping and free shipping.

Notice the indentation. We want to calculate total and execute the print statement to occur no matter how many mousetraps there are, so we don’t want to accidentally put one of the statements into the else block, like this:

Finally, we should read through the code and double check that we get the right answer for the boundary condition, exactly 30 mousetraps. Since the condition “30 < 30” is false, we will execute the else block and have a shipping charge of zero.

It is worth thinking about the fact that there is more than one way to solve this problem. For example, we could start out by computing the shipping cost, and then change it to zero if we find that there are 30 or more mousetraps. In that case, you would end up with a script like this one.

Which one is “right”? Well, both of them are. The most important thing to remember is that the Python statements you write are just a mirror of how you go about solving the problem. There is usually more than one way to think about a given problem. You may approach a solution differently than someone else, but as long as you faithfully translate the steps of your strategy into Python statements, you’ll end up with a working program.