Non-Programmer's Tutorial for Python 2.6/Boolean Expressions

Here is a little example of boolean expressions (you don't have to type it in):

With the output being:

1 True 2 False 3 True 4 False 5 True 6 True 7 False 8 True 9 False

What is going on? The program consists of a bunch of funny looking  statements. Each  statement prints a number and an expression. The number is to help keep track of which statement I am dealing with. Notice how each expression ends up being either  or. In Python, false can also be written as 0 and true as 1.

The lines:

print out a  and a   respectively just as expected since the first is true and the second is false. The third print,, is a little different. The operator  means if both the statement before and the statement after are true then the whole expression is true otherwise the whole expression is false. The next line,, shows how if part of an   expression is false, the whole thing is false. The behavior of  can be summarized as follows:

Notice that if the first expression is false Python does not check the second expression since it knows the whole expression is false.

The next line,, uses the   operator. just gives the opposite of the expression. (The expression could be rewritten as ). Here is the table:

The two following lines,  and , use the   operator. The  operator returns true if the first expression is true, or if the second expression is true or both are true. If neither are true it returns false. Here's the table:

Notice that if the first expression is true Python doesn't check the second expression since it knows the whole expression is true. This works since  is true if at least one half of the expression is true. The first part is true so the second part could be either false or true, but the whole expression is still true.

The next two lines,  and , show that parentheses can be used to group expressions and force one part to be evaluated first. Notice that the parentheses changed the expression from false to true. This occurred since the parentheses forced the  to apply to the whole expression instead of just the   portion.

Here is an example of using a boolean expression:

And here is the output:

First Match: Jill

This program works by continuing to check for match. When either  is greater than the last index of   or a match has been found the   is no longer true so the loop exits. The  simply checks to make sure that the   exited because a match was found.

The other "trick" of  is used in this example. If you look at the table for  notice that the third entry is "false and won't check". If  (in other words   is false) then   is never looked at. This is because Python knows that if the first is false then they can't both be true. This is known as a short circuit and is useful if the second half of the  will cause an error if something is wrong. I used the first expression to check and see if   was a valid index for. (If you don't believe me remove the matches "Jill" and "Life", check that it still works and then reverse the order of  to  .)

Boolean expressions can be used when you need to check two or more different things at once.

A note on Boolean Operators
A common mistake for people new to programming is a misunderstanding of the way that boolean operators works, which stems from the way the python interpreter reads these expressions. For example, after initially learning about "and " and "or" statements, one might assume that the expression  would check to see if the variable   was equivalent to one of the strings   or. This is not so. To see what I'm talking about, start an interactive session with the interpreter and enter the following expressions:

>>> 'a' == ('a' or 'b') >>> 'b' == ('a' or 'b') >>> 'a' == ('a' and 'b') >>> 'b' == ('a' and 'b')

And this will be the unintuitive result:

>>> 'a' == ('a' or 'b') True >>> 'b' == ('a' or 'b') False >>> 'a' == ('a' and 'b') False >>> 'b' == ('a' and 'b') True

At this point, the  and   operators seem to be broken. It doesn't make sense that, for the first two expressions,  is equivalent to   or   while   is not. Furthermore, it doesn't make any sense that 'b' is equivalent to  and. After examining what the interpreter does with boolean operators, these results do in fact exactly what you are asking of them, it's just not the same as what you think you are asking.

When the Python interpreter looks at an  expression, it takes the first statement and checks to see if it is true. If the first statement is true, then Python returns that object's value without checking the second statement. This is because for an  expression, the whole thing is true if one of the values is true; the program does not need to bother with the second statement. On the other hand, if the first value is evaluated as false Python checks the second half and returns that value. That second half determines the truth value of the whole expression since the first half was false. This "laziness" on the part of the interpreter is called "short circuiting" and is a common way of evaluating boolean expressions in many programming languages.

Similarly, for an  expression, Python uses a short circuit technique to speed truth value evaluation. If the first statement is false then the whole thing must be false, so it returns that value. Otherwise if the first value is true it checks the second and returns that value.

One thing to note at this point is that the boolean expression returns a value indicating  or , but that Python considers a number of different things to have a truth value assigned to them. To check the truth value of any given object, you can use the function   to see its truth value. Below is a table with examples of the truth values of various objects:

Now it is possible to understand the perplexing results we were getting when we tested those boolean expressions before. Let's take a look at what the interpreter "sees" as it goes through that code:

First case: >>> 'a' == ('a' or 'b') # Look at parentheses first, so evaluate expression "('a' or 'b')" # 'a' is a nonempty string, so the first value is True # Return that first value: 'a' >>> 'a' == 'a'          # the string 'a' is equivalent to the string 'a', so expression is True True

Second case: >>> 'b' == ('a' or 'b') # Look at parentheses first, so evaluate expression "('a' or 'b')" # 'a' is a nonempty string, so the first value is True # Return that first value: 'a' >>> 'b' == 'a'          # the string 'b' is not equivalent to the string 'a', so expression is False False

Third case: >>> 'a' == ('a' and 'b') # Look at parentheses first, so evaluate expression "('a' and 'b')" # 'a' is a nonempty string, so the first value is True, examine second value # 'b' is a nonempty string, so second value is True # Return that second value as result of whole expression: 'b' >>> 'a' == 'b'          # the string 'a' is not equivalent to the string 'b', so expression is False False

Fourth case: >>> 'b' == ('a' and 'b') # Look at parentheses first, so evaluate expression "('a' and 'b')" # 'a' is a nonempty string, so the first value is True, examine second value # 'b' is a nonempty string, so second value is True # Return that second value as result of whole expression: 'b' >>> 'b' == 'b'          # the string 'b' is equivalent to the string 'b', so expression is True True

So Python was really doing its job when it gave those apparently bogus results. As mentioned previously, the important thing is to recognize what value your boolean expression will return when it is evaluated, because it isn't always obvious.

Going back to those initial expressions, this is how you would write them out so they behaved in a way that you want:

>>> 'a' == 'a' or 'a' == 'b'  True >>> 'b' == 'a' or 'b' == 'b'  True >>> 'a' == 'a' and 'a' == 'b'  False >>> 'b' == 'a' and 'b' == 'b' False

When these comparisons are evaluated they return truth values in terms of True or False, not strings, so we get the proper results.

Examples
password1.py

Sample runs

What is your name? Josh What is the password? Friday Welcome Josh

What is your name? Bill What is the password? Money I don't know you.

Exercises
Write a program that has a user guess your name, but they only get 3 chances to do so until the program quits.