In this lesson, we will learn the rules for converting an argument and how to work with compound expressions and double negation.
Rules of conversion
Take a look at this example:
print(0 or 1)
1
The OR operator interrupts its execution from left to right and returns the result of the first argument, which we can convert to True
. When we have no such arguments, the program returns the last one on the right.
Here we see an example with the AND operator:
print(0 and 1)
0
The AND operator interrupts execution from left to right and returns the result of the first argument, which it can convert to `False'. When we have no such argument, the program returns the last one on the right.
There are two conversion rules in Python:
- We should convert to
False
the0
,0.0
,''
, andNone
. Those values are considered falsy. It includes other types of data that we will study in Hexlet - We should convert to
True
everything else
These rules are used in development, for example, to define a default value:
value = name or ''
# Some examples
234 or '' # 234
'hexlet' or '' # 'hexlet'
None or '' # ''
When name
takes one of the false values
, we assign an empty string to the value
variable. In this case, we can treat value
as a string in the following code.
However, there is a potential bug. Suppose name
contains:
- A falsy value
- The variable
value
to which we can assign values like0
,false
, ornone
In this case, the above code will not work correctly:
# The value is there, but it is falsy
# So, we do not select it on the OR condition
False or '' # ''
0 or '' # ''
None or '' # ''
Compound expressions
If you combine logical expressions, you can get some pretty interesting ways of solving problems with code.
Suppose we need to implement some code with a variable that gets:
- The
yes
string if the number is even - The
no
string if it is odd
We can do this by using the knowledge gained above:
# The number is even
result = 10 % 2 == 0 and 'yes' or 'no' # 'yes'
# Or print directly to the screen
print(10 % 2 == 0 and 'yes' or 'no') # => 'yes'
# The number is odd
print(11 % 2 == 0 and 'yes' or 'no') # => 'no'
These expressions work by order and priority. The assignment has the lowest priority, so it comes last. The comparison operator ==
has a higher priority than the logical operators and
and or
, so it comes earlier.
Next, the code is executed from left to right, since the priority of and
is higher than that of or
. Let's look at this step by step:
# For an even number:
# Step 1
10 % 2 == 0 # True
# Step 2
True and 'yes' # The result is true
# The code passes the `or` check and immediately returns `yes`
# So, we do not execute the right part
# For an odd number:
# step 1
11 % 2 == 0 # False
# step 2
False and 'yes' # The result is `false`
# step 3
False or 'no' # The code returns `no`
Also, we can use it with any expression at the beginning:
print(somefunc() and 'yes' or 'no')
Double negations
Let us remember what the negation operation looks like:
answer = True
print(not answer) # => False
With double negation, the final value is equal to the initial value:
answer = True
print(not not answer) # => True
The not
operator always returns a Boolean value, regardless of the type of argument passed. It does not replace the value with its opposite. Therefore, double negation will also return a boolean True
or False
:
answer = 'python'
print(not answer) # => False
print(not not answer) # => True
Selection errors
Suppose we need to check whether a value equals one or another. For example, the variable value
must contain one of two values: first
or second
. Beginners sometimes write this expression this way:
value == ('first' or 'second')
However, this kind of code will lead to the wrong result. We must remember the priority of operations. The first thing to evaluate is everything in parentheses like this:
'first' or 'second'
python
Python 3.8.2 (default, Apr 12 2020, 15:53:37)
>>> 'first' or 'second'
'first'
>>>
Now we will substitute the original expression with the partly evaluated one:
value == 'first'
It is not what we expected. Now we go back to the beginning and write the check correctly:
# The priority of '==' is higher than the priority of 'or'
# So, there is no need for brackets
value == 'first' or value == 'second'