## Boolean Operators

Sometimes the simple conditions that we have been using do not seem expressive enough. For example, suppose you need to determine whether two point objects are in the same positionâ€”that is, they have equal x coordinates and equal y coordinates. One way of handling this would be a nested decision.

# points are the same else:

# points are different else:

# points are different

### You can see how awkward this is.

Instead of working around this problem with a decision structure, another approach would be to construct a more complex expression using Boolean operations. Like most programming languages, Python provides three Boolean operators: and, or and not. Let's take a look at these three operators and then see how they can be used to simplify our problem.

The Boolean operators and and or are used to combine two Boolean expressions and produce a Boolean result.

<expr> and <expr> <expr> or <expr>

The and of two expressions is true exactly when both of the expressions are true. We can represent this definition in a truth table.

 T T T T F F F T F F F F

In this table, Pand Q represent smaller Boolean expressions. Since each expression has two possible values, there are four possible combinations of values, each shown as one row in the table. The last column gives the value of P and Q for each possible combination. By definition, the and is true only in the case where both P and Q are true.

The or of two expressions is true when either expression is true. Here is the truth table defining or:

 T T T T F T F T T F F F

The only time the or is false is when both expressions are false. Notice especially that or is true when both expressions are true. This is the mathematical definition of or, but the word "or" is sometimes used in an exclusive sense in everyday English. If your mom said that you could have cake or cookies for dessert, she would probably scold you for taking both.

The not operator computes the opposite of a Boolean expression. It is a unary operator, meaning that it operates on a single expression. The truth table is very simple.

Using Boolean operators, it is possible to build arbitrarily complex Boolean expressions. As with arithmetic operators, the exact meaning of a complex expression depends on the precedence rules for the operators. Consider this expression.

How should this be evaluated?

Python follows a standard convention that the order of precedence is not, followed by and, followed by or. So the expression would be equivalent to this parenthesized version.

Unlike arithmetic, however, most people don't tend to know or remember the precedence rules for Booleans. I suggest that you always parenthesize your complex expressions to prevent confusion.

Now that we have some Boolean operators, we are ready to return to our example problem. To test for the co-location of two points, we could use an and operation.

if p1.getX() == p2.getX() and p2.getY() == p1.getY():

# points are the same else:

# points are different

Here the entire expression will only be true when both of the simple conditions are true. This ensures that both the x and y coordinates have to match for the points to be the same. Obviously, this is much simpler and clearer than the nested ifs from the previous version.

Let's look at a slightly more complex example. In the next chapter, we will develop a simulation for the game of racquetball. Part of the simulation will need to determine when a game has ended. Suppose that scoreA and scoreB represent the scores of two racquetball players. The game is over as soon as either of the players has reached 15 points. Here is a Boolean expression that is true when the game is over:

When either score reaches 15, one of the two simple conditions becomes true, and, by definition of or, the entire Boolean expression is true. As long as both conditions remain false (neither player has reached 15) the entire expression is false.

Our simulation will need a loop that continues as long as the game is not over. We can construct an appropriate loop condition by taking the negation of the game-over condition:

while not (scoreA == 15 or scoreB == 15): # continue playing

We can also construct more complex Boolean expressions that reflect different possible stopping conditions. Some racquetball players play shutouts (sometimes called a skunk). For these players, a game also ends when one of the players reaches 7 and the other has not yet scored a point. For brevity, I'll use a for scoreA and b for scoreB. Here is an expression for game-over when shutouts are included:

a == 15 or b == 15 or (a == 7 and b == 0) or (b == 7 and a == 0)

Do you see how I have added two more situations to the original condition? The new parts reflect the two possible ways a shutout can occur, and each requires checking both scores. The result is a fairly complex expression.

While we're at it, let's try one more example. Suppose we were writing a simulation for volleyball, rather than racquetball. Volleyball does not have shutouts, but it requires a team to win by at least two points. If the score is 15 to 14, or even 21 to 20, the game continues.

Let's write a condition that computes when a volleyball game is over. Here's one approach.

(a >= 15 and a - b >= 2) or (b >= 15 and b - a >= 2)

Do you see how this expression works? It basically says the game is over when team A has won (scored at least 15 and leading by at least 2) or when team B has won. Here is another way to do it.

This version is a bit more succinct. It states that the game is over when one of the teams has reached a winning total and the difference in the scores is at least 2. Remember that abs returns the absolute value of an expression.