A Boolean Type

In Python, there is a type called bool (without an “e”). Unlike int and float, which have billions of possible values, bool has only two: True and False. True and False are values, just as much as the numbers 0 and -43.7.

Boolean Operators

There are only three basic Boolean operators: and, or, and not. not has the highest precedence, followed by and, followed by or.

not is a unary operator: it is applied to just one value, like the negation in the expression -(3 + 2). An expression involving not produces True if the original value is False, and it produces False if the original value is True:

 >>>​​ ​​not​​ ​​True
 False
 >>>​​ ​​not​​ ​​False
 True

In the previous example, instead of not True, we could simply use False, and instead of not False, we could use True. Rather than apply not directly to a Boolean value, we would typically apply not to a Boolean variable or a more complex Boolean expression. The same goes for the following examples of the Boolean operators and and or, so although we apply them to Boolean constants in the following examples, we’ll give an example of how they are typically used at the end of this section.

and is a binary operator. It produces True if both operands are True, and it produces False otherwise:

 >>>​​ ​​True​​ ​​and​​ ​​True
 True
 >>>​​ ​​False​​ ​​and​​ ​​False
 False
 >>>​​ ​​True​​ ​​and​​ ​​False
 False
 >>>​​ ​​False​​ ​​and​​ ​​True
 False

or is also a binary operator. It produces True if either operand is True, and it produces False only if both are False:

 >>>​​ ​​True​​ ​​or​​ ​​True
 True
 >>>​​ ​​False​​ ​​or​​ ​​False
 False
 >>>​​ ​​True​​ ​​or​​ ​​False
 True
 >>>​​ ​​False​​ ​​or​​ ​​True
 True

This definition is called inclusive or, since it allows both possibilities as well as either. In English, the word or is also sometimes an exclusive or. For example, if someone says, “You can have pizza or tandoori chicken,” they probably don’t mean that you can have both. Unlike English (but like most programming languages), Python always interprets or as inclusive.

We mentioned earlier that Boolean operators are usually applied to Boolean expressions rather than Boolean constants. If we want to express “It is not cold and windy” using two variables, cold and windy, that refer to Boolean values, we first have to decide what the ambiguous English expression means: is it not cold but at the same time windy, or is it both not cold and not windy? A truth table for each alternative is shown in Table 5, Boolean Operators, and the following code snippet shows what they look like translated into Python:

 >>>​​ ​​cold​​ ​​=​​ ​​True
 >>>​​ ​​windy​​ ​​=​​ ​​False
 >>>​​ ​​(not​​ ​​cold)​​ ​​and​​ ​​windy
 False
 >>>​​ ​​not​​ ​​(cold​​ ​​and​​ ​​windy)
 True

Table 5. Boolean Operators

cold

windy

cold and windy

cold or windy

(not cold) and windy

not (cold and windy)

True

True

True

True

False

False

True

False

False

True

False

True

False

True

False

True

True

True

False

False

False

False

False

True


Relational Operators

We said earlier that True and False are values. Typically those values are not written down directly in expressions but rather created in expressions. The most common way to do that is by doing a comparison using a relational operator. For example, 3 < 5 is a comparison using the relational operator < that produces the value True, while 13 > 77 uses > and produces the value False.

As shown in Table 6, Python has all the operators you’re used to using. Some of them are represented using two characters instead of one, like <= instead of .


Table 6. Relational and Equality Operators

Symbol

Operation

>

Greater than

<

Less than

>=

Greater than or equal to

<=

Less than or equal to

==

Equal to

!=

Not equal to


The most important representation rule is that Python uses == for equality instead of just =, because = is used for assignment. Avoid typing x = 3 when you mean to check whether variable x is equal to three: x == 3.

All relational operators are binary operators: they compare two values and produce True or False as appropriate. The greater-than (>) and less-than (<) operators work as follows:

 >>>​​ ​​45​​ ​​>​​ ​​34
 True
 >>>​​ ​​45​​ ​​>​​ ​​79
 False
 >>>​​ ​​45​​ ​​<​​ ​​79
 True
 >>>​​ ​​45​​ ​​<​​ ​​34
 False

We can compare integers to floating-point numbers with any of the relational operators. Integers are automatically converted to floating point when we do this, just as they are when we add 14 to 23.3:

 >>>​​ ​​23.1​​ ​​>=​​ ​​23
 True
 >>>​​ ​​23.1​​ ​​>=​​ ​​23.1
 True
 >>>​​ ​​23.1​​ ​​<=​​ ​​23.1
 True
 >>>​​ ​​23.1​​ ​​<=​​ ​​23
 False

The same holds for “equal to” and “not equal to”:

 >>>​​ ​​67.3​​ ​​==​​ ​​87
 False
 >>>​​ ​​67.3​​ ​​==​​ ​​67
 False
 >>>​​ ​​67.0​​ ​​==​​ ​​67
 True
 >>>​​ ​​67.0​​ ​​!=​​ ​​67
 False
 >>>​​ ​​67.0​​ ​​!=​​ ​​23
 True

Of course, it doesn’t make much sense to compare two numbers that you know in advance, since you would also know the result of the comparison. Relational operators therefore almost always involve variables, like this:

 >>>​​ ​​def​​ ​​is_positive(x:​​ ​​float)​​ ​​->​​ ​​bool:
 ...​​ ​​"""Return True iff x is positive.
 ...
 ... >>> is_positive(3)
 ... True
 ... >>> is_positive(-4.6)
 ... False
 ... """
 ...​​ ​​return​​ ​​x​​ ​​>​​ ​​0
 ...
 >>>​​ ​​is_positive(3)
 True
 >>>​​ ​​is_positive(-4.6)
 False
 >>>​​ ​​is_positive(0)
 False

In this docstring, we use the acronym “iff,” which stands for “if and only if.” An equivalent phrase is “exactly when.” The type contract states that the function will return a bool. The docstring describes the conditions under which True will be returned. It is implied that when those conditions aren’t met the function will return False.

We can now write our exclusive or expression from Building an Exclusive or Expression, much more simply:

 b1 != b2

Exclusive or means that exactly one of b1 and b2 has to be True. If b1 is True, b2 can’t be, and vice versa.

Combining Comparisons

We have now seen three types of operators: arithmetic (+, -, and so on), Boolean (and, or, and not), and relational (<, ==, and so on).

Here are the rules for combining them:

  • Arithmetic operators have higher precedence than relational operators. For example, + and / are evaluated before < or >.

  • Relational operators have higher precedence than Boolean operators. For example, comparisons are evaluated before and, or, and not.

  • All relational operators have the same precedence.

These rules mean that the expression 1 + 3 > 7 is evaluated as (1 + 3) > 7, not as 1 + (3 > 7). These rules also mean that you can often skip the parentheses in complicated expressions:

 >>>​​ ​​x​​ ​​=​​ ​​2
 >>>​​ ​​y​​ ​​=​​ ​​5
 >>>​​ ​​z​​ ​​=​​ ​​7
 >>>​​ ​​x​​ ​​<​​ ​​y​​ ​​and​​ ​​y​​ ​​<​​ ​​z
 True

It’s usually a good idea to put the parentheses in, though, since it helps the eye find the subexpressions and clearly communicates the order to anyone reading your code:

 >>>​​ ​​x​​ ​​=​​ ​​5
 >>>​​ ​​y​​ ​​=​​ ​​10
 >>>​​ ​​z​​ ​​=​​ ​​20
 >>>​​ ​​(x​​ ​​<​​ ​​y)​​ ​​and​​ ​​(y​​ ​​<​​ ​​z)
 True

It’s very common in mathematics to check whether a value lies in a certain range—in other words, that it is between two other values. You can do this in Python by combining the comparisons with and:

 >>>​​ ​​x​​ ​​=​​ ​​3
 >>>​​ ​​(1​​ ​​<​​ ​​x)​​ ​​and​​ ​​(x​​ ​​<=​​ ​​5)
 True
 >>>​​ ​​x​​ ​​=​​ ​​7
 >>>​​ ​​(1​​ ​​<​​ ​​x)​​ ​​and​​ ​​(x​​ ​​<=​​ ​​5)
 False

This comes up so often, however, that Python lets you chain the comparisons:

 >>>​​ ​​x​​ ​​=​​ ​​3
 >>>​​ ​​1​​ ​​<​​ ​​x​​ ​​<=​​ ​​5
 True

Most combinations work as you would expect, but there are cases that may startle you:

 >>>​​ ​​3​​ ​​<​​ ​​5​​ ​​!=​​ ​​True
 True
 >>>​​ ​​3​​ ​​<​​ ​​5​​ ​​!=​​ ​​False
 True

It seems impossible for both of these expressions to be True. However, the first one is equivalent to this:

 (3 < 5) ​and​ (5 != True)

while the second is equivalent to this:

 (3 < 5) ​and​ (5 != False)

Since 5 is neither True nor False, the second half of each expression is True, so the expression as a whole is True as well.

This kind of expression is an example of something that’s a bad idea even though it’s legal. We strongly recommend that you only chain comparisons in ways that would seem natural to a mathematician—in other words, that you use < and <= together, or > and >= together, and nothing else. If you feel the impulse to do something else, resist. Use simple comparisons and combine them with and in order to keep your code readable. It’s also a good idea to use parentheses whenever you think the expression you are writing may not be entirely clear.

Short-Circuit Evaluation

When Python evaluates an expression containing and or or, it does so from left to right. As soon as it knows enough to stop evaluating, it stops, even if some operands haven’t been looked at yet. This is called short-circuit evaluation.

In an or expression, if the first operand is True, we know that the expression is True. Python knows this as well, so it doesn’t even evaluate the second operand. Similarly, in an and expression, if the first operand is False, we know that the expression is False. Python knows this as well, and the second operand isn’t evaluated.

To demonstrate this, we use an expression that results in an error:

 >>>​​ ​​1​​ ​​/​​ ​​0
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
 ZeroDivisionError: division by zero

We now use that expression as the second operand to or:

 >>>​​ ​​(2​​ ​​<​​ ​​3)​​ ​​or​​ ​​(1​​ ​​/​​ ​​0)
 True

Since the first operand produces True, the second operand isn’t evaluated, so the computer never actually tries to divide anything by zero.

Of course, if the first operand to an or is False, the second operand must be evaluated. The second operand also needs to be evaluated when the first operand to an and is True.

Comparing Strings

It’s possible to compare strings just as you would compare numbers. The characters in strings are represented by integers: a capital A, for example, is represented by 65, whereas a space is 32, and a lowercase z is 122. This encoding is called ASCII,[4] which stands for “American Standard Code for Information Interchange.” One of its quirks is that all the uppercase letters come before all the lowercase letters, so a capital Z is less than a small a.

One of the most common reasons to compare two strings is to decide which one comes first alphabetically. This is often referred to as dictionary ordering or lexicographic ordering. Python decides which string is greater than which by comparing corresponding characters from left to right. If the character from one string is greater than the character from the other, the first string is greater than the second. If all the characters are the same, the two strings are equal; if one string runs out of characters while the comparison is being done (in other words, is shorter than the other), then it is less. The following code fragment shows a few comparisons in action:

 >>>​​ ​​'A'​​ ​​<​​ ​​'a'
 True
 >>>​​ ​​'A'​​ ​​>​​ ​​'z'
 False
 >>>​​ ​​'abc'​​ ​​<​​ ​​'abd'
 True
 >>>​​ ​​'abc'​​ ​​<​​ ​​'abcd'
 True

In addition to operators that compare strings lexicographically, Python provides an operator that checks whether one string appears inside another one:

 >>>​​ ​​'Jan'​​ ​​in​​ ​​'01 Jan 1838'
 True
 >>>​​ ​​'Feb'​​ ​​in​​ ​​'01 Jan 1838'
 False

Using this idea, we can prompt the user for a date in this format and report whether that date is in January:

 >>>​​ ​​date​​ ​​=​​ ​​input(​​'Enter a date in the format DD MTH YYYY: '​​)
 Enter a date in the format DD MTH YYYY: 24 Feb 2013
 >>>​​ ​​'Jan'​​ ​​in​​ ​​date
 False
 >>>​​ ​​date​​ ​​=​​ ​​input(​​'Enter a date in the format DD MTH YYYY: '​​)
 Enter a date in the format DD MTH YYYY: 03 Jan 2002
 >>>​​ ​​'Jan'​​ ​​in​​ ​​date
 True

The in operator produces True exactly when the first string appears in the second string. This is case sensitive:

 >>>​​ ​​'a'​​ ​​in​​ ​​'abc'
 True
 >>>​​ ​​'A'​​ ​​in​​ ​​'abc'
 False

The empty string is always a substring of every string:

 >>>​​ ​​''​​ ​​in​​ ​​'abc'
 True
 >>>​​ ​​''​​ ​​in​​ ​​''
 True

The in operator also applies to other types; you’ll see examples of this in Chapter 8, Storing Collections of Data Using Lists, and in Chapter 11, Storing Data Using Other Collection Types.

..................Content has been hidden....................

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