In this lesson we will learn the rules for transforming an argument and how to work with compound expressions and double negation.
Look at the example:
print(0 or 1)
1
The way the ORI operator works is that its execution from left to right is interrupted and the result of the first argument that can be converted to True
is returned. If there is no such argument, the last one, the right one, is returned.
Example with operator AND:
print(0 and 1)
0
The way the AND operator works is that its execution from left to right is interrupted and the result of the first argument, which can be converted to False
, is returned. If there is no such argument, the last one - the right one - is returned.
There are two conversion rules in Python:
0
, 0.0
, ``'and
Noneare cast to
False`. These values are called falsy. This includes other data types that we will study in HexsletTrue
.These rules are used in development, for example, to define a default value:
value = name or ''
# Examples
234 or '' # 234
'hexlet' or '' # 'hexlet'
None or '' # ''
If name
takes one of the falsy values, the variable value
will be assigned an empty string. In this case, in the following code we will be able to handle value
as a string.
But there is a potential bug here. If name
contains a falsy value, and the variable value
can be assigned values like 0
, False
, None
, the code above will not work correctly:
# The significance is actually there,
# but it is Falsy, so it is not selected on the OR condition
False or '' # ''
0 or '' # ''
None or '' # ''
If you combine logical expressions with each other, you can get some pretty interesting ways of solving problems with code.
Suppose we need to implement code in which a variable is written:
yes
if the number is evenno
if oddThis can be done by using the knowledge gained above:
# even number
result = 10 % 2 == 0 and 'yes' or 'no' # 'yes'
# or print directly to the screen
print(10 % 2 == 0 and 'yes' or 'no') # => 'yes'
# odd number
print(11 % 2 == 0 and 'yes' or 'no') # => 'no'
These expressions work according to order and priority. The priority of assignment is the lowest, so it happens at the end. The priority of comparison ==
is higher than the priority of the logical operators and
and or
, so the comparison occurs earlier. Further the code is executed from left to right, because the priority of and
is higher than the priority of or
. Let's look at it step by step:
# For an even
# 1 step
10 % 2 == 0 # True
# 2 step
True and 'yes' # The result is true
# The or check is done, but the right part is not executed, because it immediately returns 'yes'.
# For an odd
# 1 step
11 % 2 == 0 # False
# 2 step
False and 'yes' # The result is false.
# 3 step
False or 'no' # Selects and returns 'no'
The same scheme can be used with any expression at the beginning:
print(somefunc() and 'yes' or 'no')
You can check yourself and experiment with the code in Replit.
Recall what the operation of negation 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 the passed argument, rather than replacing the value with the opposite. Therefore, a double negation will also return a boolean True/False.
answer = 'python'
print(not answer) # => False
print(not not answer) # => True
Imagine that we need to check whether a value is equal to one or the other. For example, the variable value
must contain one of two values: first
or ``second`. Beginner developers sometimes write this expression this way:
value == ('first' or 'second')
However, such a code will lead to the wrong result. It is necessary to remember the priority of operations. The first thing is to calculate everything specified in brackets - 'first' or
second'`. If you execute this code in Replit, the output will be as follows:
python
Python 3.8.2 (default, Apr 12 2020, 15:53:37)
>>> 'first' or 'second'
'first'
>>>
Now replace the original expression with a partially calculated one:
value == 'first'
Not at all what we expected. Now let's go back to the beginning and write the test correctly:
# It is not necessary to put parentheses,
# because the priority == is higher than the priority of or
value == 'first' or value == 'second'
Implement a function string_or_not()
that checks if the passed parameter is a string. If yes, it returns 'yes'
otherwise 'no'
.
string_or_not('Hexlet') # 'yes'
string_or_not(10) # 'no'
string_or_not('') # 'yes'
string_or_not(False) # 'no'
You can check if the passed parameter is a string with the function isinstance():
isinstance(3, str) # False
isinstance('Hexlet', str) # True
Experiment with the code in the interactive replay https://replit.com/@hexlet/python-basics-logical-expressions
If you've reached a deadlock it's time to ask your question in the «Discussions». How ask a question correctly:
Tests are designed so that they test the solution in different ways and against different data. Often the solution works with one kind of input data but doesn't work with others. Check the «Tests» tab to figure this out, you can find hints at the error output.
It's fine. 🙆 One task in programming can be solved in many different ways. If your code passed all tests, it complies with the task conditions.
In some rare cases, the solution may be adjusted to the tests, but this can be seen immediately.
It's hard to make educational materials that will suit everyone. We do our best but there is always something to improve. If you see a material that is not clear to you, describe the problem in “Discussions”. It will be great if you'll write unclear points in the question form. Usually, we need a few days for corrections.
By the way, you can participate in courses improvement. There is a link below to the lessons course code which you can edit right in your browser.
Your exercise will be checked with these tests:
1import index
2
3
4def test1():
5 assert index.string_or_not('Hexlet') == 'yes'
6 assert index.string_or_not(10) == 'no'
7 assert index.string_or_not('') == 'yes'
8 assert index.string_or_not(False) == 'no'
9 assert index.string_or_not(True) == 'no'
10
Teacher's solution will be available in: