type(True)
bool
In the previous tutorial, we mentioned – without detailing – the notion of conditional statements, through the example of membership tests. Now, we will delve into the details of how conditions work in Python. They are a major step in creating programs that automate operations since they allow you to execute or not execute code based on certain conditions. They enable the computer to make decisions based on criteria set by the user.
In its simplest form, a test in Python is an expression that evaluates to “true” or “false.” For example, the expression \(3 > 2\) is true, so the associated test will return “true.” For this type of evaluation, Python has a particular type of object: booleans. Unlike the object types we have seen (int
, float
, str
, etc.), booleans can only take two values: True
and False
.
type(True)
bool
Like any object, booleans can be assigned to variables.
= False
a print(a)
print(type(a))
False
<class 'bool'>
The values True
and False
must be written precisely this way (first letter capitalized, no quotes). They also cannot be used as variable names to avoid ambiguities.
= true # Python will look for the variable `true`, but it doesn't exist a
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[51], line 1 ----> 1 a = true # Python will look for the variable `true`, but it doesn't exist NameError: name 'true' is not defined
True = 3
Cell In[52], line 1 True = 3 ^ SyntaxError: cannot assign to True
Comparison operators formalize mathematical comparison operations (equality, inequality, inequalities). They compare two values and return a boolean value.
|
|Let’s illustrate these operators with a few examples.
3 == 3
True
63 == 36
False
2 != 3
True
2 != 2
False
3 > 2
True
= 36
a <= a a
True
< a a
False
Everything seems to work correctly for usual mathematical operations. But these operators actually work on any type of object.
'do re mi fa sol' == 'do re mi fa sol'
True
'do re mi fa sol' == 'Do Re Mi Fa Sol'
False
'duck' != 'bee'
True
True == True
True
True == False
False
1, 2, 3] == [1, 2, 3] [
True
1, 2] != [3, 4] [
True
Finally, it is possible to chain comparisons. The expression returns True
provided that each of the comparisons is true.
5 < 7 <= 8
True
5 < 7 <= 6
False
Boolean operators allow simultaneous testing of multiple logical expressions. Fundamentally, these operators take two boolean values as input and return a single boolean value according to fixed logic rules. These rules are stated in truth tables.
and
operatorThe first boolean operator is and
. Let’s look at its truth table:
|
|True and True
| True
|True and False
| False
|False and True
| False
|False and False
| False
|Let’s verify these rules in practice with a few examples.
True and True
True
False and True
False
The rules seem to work on boolean values. Of course, in practice, we are more interested in evaluating real logical expressions. We can use these operators to test expressions that return a boolean value.
3 > 2) and (5 <= 9) (
True
= ("x" != "z")
a = ("x" == "y")
b and b a
False
Note the use of parentheses to delimit the tests: they are not mandatory but are strongly recommended as they greatly improve the readability of tests.
or
operatorThe second boolean operator is or
. Its truth table is as follows:
|
|True or True
| True
|True or False
| True
|False or True
| True
|False or False
| False
|True or True
True
False or True
True
3 > 2) or (5 <= 9) (
True
= ("x" != "z")
a = ("x" == "y")
b or b a
True
not
operatorThe last boolean operator is not
. Its truth table is as follows:
Expression | Evaluation |
---|---|
not True |
False |
not False |
True |
not True
False
not False
True
not (3 + 3 == 6)
False
not (7 < 7)
True
All the expressions we have seen so far are boolean expressions: a test is performed, and the operation returns True
or False
depending on whether the evaluated expression is true or not. In the context of a computer program that automates operations, we want to use them as conditions: if the expression is true, then the computer must perform a certain operation. Conditional structures allow precisely this usage.
Let’s illustrate this principle by implementing the following program:
Define a variable x
.
If x
is greater than \(5\), then print “The expression is true.”
Otherwise, print “The expression is false.”
Vary the value of x
to verify the correct operation of the test.
= 7
x
if x >= 5:
print("The expression is true.")
else:
print("The expression is false.")
The expression is true.
The previous example illustrates the syntax of conditional structures in Python. These structures are based on instruction blocks, which delimit the set of instructions to be executed when a test is true. Conditional structures have three rules:
The line specifying the test ends with :
.
All instructions that must be executed if the test is true are at the same level of indentation.
The conditional structure ends when the indentation returns to its original level.
Note that conditional structures can indeed be nested, as illustrated in the following example.
= 7
x
if x >= 5:
print("The first expression is true.")
if x >= 12:
print("The second expression is true.")
The first expression is true.
When x = 7
, the first test returns True
, so the instruction block at indentation level 1 is executed line by line. The second test returns False
, so the instruction block at indentation level 2 is not executed.
Vary the value of x
so that both blocks are executed.
if
, else
, and elif
statementsIn conditional structures, tests can be specified using three statements: if
, else
, and elif
. The previous examples have already illustrated the operation of the first two (and most frequent) statements.
In the case of a simple test (a single condition), only an if
statement will be used, whose operation is simple: if the condition (test) returns True
, then the instruction block (indented) that follows is executed. If the condition returns False
, nothing happens. Let’s illustrate this with a membership test, for which we have seen examples in the previous tutorial.
= "Isidore"
client
if client in ["Alexandrine", "Achille", "Colette"]:
print("Known client.")
In practice, we often want to specify an alternative when the condition of the if
statement returns False
. The else
statement allows specifying an alternative instruction block.
= "Isidore"
client
if client in ["Alexandrine", "Achille", "Colette"]:
print("Known client.")
else:
print("Unknown client.")
Unknown client.
Finally, we may want to specify multiple alternatives. In this case, we will use elif
statements. The first elif
statement will only execute if the test of the if
statement returns False
. The second elif
statement will only execute if the test of the first elif
statement returns False
, and so on. Again, a final else
statement can be specified, which only executes if none of the previous tests returned True
.
= "Isidore"
client
if client == "Alexandrine":
print("Hello Alexandrine.")
elif client == "Achille":
print("Hello Achille.")
elif client == "Colette":
print("Hello Colette.")
else:
print("Hello dear unknown.")
Hello dear unknown.
NB: The previous instructions are for example purposes only. In practice, there are much more concise ways to code a program that performs the same operations.
1/ What is the particularity of booleans compared to other basic object types in Python?
2/ What are the inputs and outputs of a comparison operator?
3/ What types of objects can be compared using a comparison operator?
4/ What is the difference between the =
operator and the ==
operator?
5/ What are the inputs and outputs of a boolean operator?
6/ Explain in English the principle of the and
boolean operator. Same for or
and not
.
7/ What is the difference between a boolean expression and a condition?
8/ What is the structure of a conditional statement?
9/ Can conditional statements be nested?
10/ Among the if
, else
, and elif
statements, which ones are mandatory and which ones are optional?
1/ They have only two values: True and False. Other types have an infinite number of possible values.
2/ Inputs: two values. Output: boolean value.
3/ All types of objects. In practice, however, it often does not make much sense to compare objects of different types; the result will generally be False
.
4/ The =
operator assigns a value to a variable. The ==
operator tests the equality of two objects.
5/ Inputs: two boolean values or two expressions that return booleans. Output: boolean value.
6/ The and
operator returns True
if both of its inputs are True
, and False
in all other cases. The or
operator returns True
if at least one of its inputs is True
, and False
if both are False
. The not
operator returns False
if its input is True
, and True
otherwise.
7/ In both cases, they are tests. A condition is when the expressions are used within conditional structures.
8/ The conditional statement starts with an if
, else
, or elif
statement, ending with :
. Then comes an indented instruction block that only executes if the statement is True
. The block ends when the indentation returns to its original level.
9/ Yes, conditional statements can be nested indefinitely (in theory). Just be careful to respect the levels of indentation.
10/ Only the if
statement is mandatory.
Predict the results of the following tests and verify your predictions:
'Simon' in ['simon', 'oceane', 'veronique']
[1, 2, 3] == ['1', '2', '3']
'x' != 'x'
(9 > 5) and (3 == 5)
(3 > 2 and 5 >= 1) or (5 <= 9 and 6 > 12)
not (9 > 2*3)
not (9 > (2*3))
not ((7 > 8) or (5 <= 5))
(True and True) or (True == False)
(not False) or (not True)
# Test your answer in this cell
'Simon' in ['simon', 'oceane', 'veronique']
: False
[1, 2, 3] == ['1', '2', '3']
: False
'x' != 'x'
: False
(9 > 5) and (3 == 5)
: False
(3 > 2 and 5 >= 1) or (5 <= 9 and 6 > 12)
: True
not (9 > 2*3)
: False
not (9 > (2*3))
: False
not ((7 > 8) or (5 <= 5))
: False
(True and True) or (True == False)
: True
(not False) or (not True)
: True
Consider the program written in the following cell.
= 10
x
if True:
print("Initialization.")
= []
l if x > 8:
"a")
l.append(elif x >= 2:
"b")
l.append(else:
"c")
l.append(if x - 6 < 0:
print("Negative.")
print(l)
Initialization.
['a']
For the following values:
x = 1
x = 5
x = 10
predict the program’s results:
What is l
at the end of the program?
What is printed in the console during the program?
Verify your results.
# Test your answer in this cell
x = 1
: l = ['c']
and messages printed: ‘Initialization’ and ‘Negative’
x = 5
: l = ['b']
and messages printed: ‘Initialization’ and ‘Negative’
x = 10
: l = ['a']
and messages printed: ‘Initialization’
Write a program that performs the following operations:
Define a list that contains 4 names.
Write a test that prints the message (‘Too many people.’) if the list contains more than three people.
Remove a person from the list (using the del
function or the pop
method seen in a previous tutorial).
Perform the test again, there should be no output.
# Test your answer in this cell
= ["Romuald", "Ursula", "Jean-Vincent", "Philomène"]
people
if len(people) > 3:
print('Too many people.')
print(people)
"Jean-Vincent")
people.remove(print(people)
if len(people) > 3:
print('Too many people.')
Too many people.
['Romuald', 'Ursula', 'Jean-Vincent', 'Philomène']
['Romuald', 'Ursula', 'Philomène']
The input
function allows the user to enter a value in a Python program. The syntax is as follows: x = input()
. When this command is executed, the user must enter a value, which is then assigned to the variable x.
Using input
and the if
, elif
, and else
statements, code the following program:
Ask the user for a value, which will be stored in a variable p
.
If p
is strictly less than $15, print the message “too low!”.
If p
is strictly greater than $15, print the message “too high!”.
If p
is equal to $15, print the message “right on!”.
Note, input
returns a string by default. Therefore, you need to convert the value of p
to an integer (using the int
function) for the game to work.
# Test your answer in this cell
= input()
p = int(p)
p
if p < 15:
print("too low!")
elif p > 15:
print("too high!")
else:
print("right on!")
--------------------------------------------------------------------------- StdinNotImplementedError Traceback (most recent call last) Cell In[92], line 1 ----> 1 p = input() 2 p = int(p) 4 if p < 15: File /opt/hostedtoolcache/Python/3.10.15/x64/lib/python3.10/site-packages/ipykernel/kernelbase.py:1281, in Kernel.raw_input(self, prompt) 1279 if not self._allow_stdin: 1280 msg = "raw_input was called, but this frontend does not support input requests." -> 1281 raise StdinNotImplementedError(msg) 1282 return self._input_request( 1283 str(prompt), 1284 self._parent_ident["shell"], 1285 self.get_parent("shell"), 1286 password=False, 1287 ) StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.
In Python, all objects evaluate to True
or False
in a conditional test (if
/else
). The general rule is that objects that are zero or empty (e.g., an empty list, an empty dictionary) evaluate to False
, and vice versa. But there is no need to know these rules by heart: they can be easily found in practice! For example, you can use the following conditional test:
if "test":
print("True.")
else:
print("False.")
True.
Predict which boolean value the following objects will evaluate to, and verify using the previous syntax.
0
1
12
-1
’’ (empty string)
’ ’ (string containing only a space)
[]
(empty list)
['']
(list containing only an empty string)
{}
{-1}
# Test your answer in this cell
0
: False
1
: True
12
: True
-1
: True
''
(empty string): False
' '
(string containing only a space): True
[]
(empty list): False
['']
(list containing only an empty string): True
{}
: False
{-1}
: True
We have seen that it is possible to perform chained comparisons, which return True
provided that each of the included comparisons is true. Find a way to rewrite the following chained comparison using boolean operators.
5 < 7 <= 8 < 18
# Test your answer in this cell
print(5 < 7 <= 8 < 18)
print(5 < 7 and 7 <= 8 and 8 < 18)
True
True
A chained comparison can be rewritten with and
operators. It makes sense: each comparison must be true for the whole to be true. In practice, the version with and
is probably preferable for readability.
Booleans are strongly linked to binary language, where `1
corresponds to "true" and
0` to “false.” Let’s see if this link exists in the context of Python. To do this:
Calculate the “integer representation” of the boolean value of your choice using the int
function.
Use booleans in the context of mathematical calculations to verify their behavior in this context.
# Test your answer in this cell
print(int(True))
1
A boolean evaluated as an integer indeed gives the associated binary value.
print(True + 3)
4
What do inequality comparison tests applied to strings return? Produce some examples to test the behavior.
# Test your answer in this cell
print("a" > "b")
print("a" < "b")
print("apricot" > "avocado")
print("apricot" < "avocado")
print("1" > "2")
print("1" < "2")
print("A1" < "A2")
False
True
False
True
False
True
True
The order relation used is alphanumeric order: each character is taken individually, and the orders are A < Z and 1 < 9.
Equality tests between real numbers (type float
in Python) can be misleading. To convince yourself, perform the following test: (6 - 5.8) == 0.2
To understand the test result, perform the calculation of the left-hand side of the test alone. What do you notice?
Imagine (without necessarily implementing it) another test, based on inequalities, that would allow testing approximate equality.
# Test your answer in this cell
= 3 - 2.7
diff
print(diff == 0.3)
print(diff)
False
0.2999999999999998
In Python, floating-point numbers are always approximate values. We can therefore have such surprises in calculations.
= 0.0001
tolerance = (0.3 - tolerance) < diff < (0.3 + tolerance)
new_test print(new_test)
True