10.1. Conditional Logic

10.1.1. Negation

  • not logically inverts

~1 -> 0
~0 -> 1
>>> not True
False
>>>
>>> not False
True

Use Case:

>>> admins = {'alice', 'bob', 'carol'}
>>> login = 'mallory'
>>>
>>> if login not in admins:
...     print('Access denied')
...
Access denied

10.1.2. Conjunction

  • ... and ... - conjunction

Definition:

1 & 1 -> 1
1 & 0 -> 0
0 & 1 -> 0
0 & 0 -> 0

Example:

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

Use Case:

>>> login = 'alice'
>>> password = 'alicepass'
>>>
>>> login == 'alice' and password == 'alicepass'
True

Because:

>>> login == 'alice'
True
>>>
>>> password == 'alicepass'
True

Therefore:

>>> True and True
True

10.1.3. Disjunction

  • ... or ... - disjunction

Definition:

1 | 1 -> 1
1 | 0 -> 1
0 | 1 -> 1
0 | 0 -> 0

Example:

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

Use Case:

>>> login = 'alice'
>>> password = 'alicepass'
>>>
>>> login == 'alice' or login == 'bob'
True

Because:

>>> login == 'alice'
True
>>>
>>> login == 'bob'
False

Therefore:

>>> True or False
True

10.1.4. Boolean Algebra

  • and has higher precedence

  • or has lower precedence

  • use round brackets ( and ) to make code more readable

Example:

>>> True or False and True
True
>>>
>>> True or (False and True)
True
>>>
>>> (True or False) and True
True

Similarity:

>>> 1 + 2 * 3
7
>>>
>>> 1 + (2 * 3)
7
>>>
>>> (1 + 2) * 3
9

Use Case:

>>> login = 'alice'
>>> password = 'secret'
>>>
>>> (login == 'alice' and password == 'secret') or \
... (login == 'bob' and password == 'qwerty') or \
... (login == 'carol' and password == '123456')
True

Because:

>>> login == 'alice' and password == 'secret'
True
>>>
>>> login == 'bob' and password == 'qwerty'
False
>>>
>>> login == 'carol' and password == '123456'
False

Therefore:

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

10.1.5. Optimization

  • Python won't evaluate the rest of an expression if already knows an answer

Python won't evaluate the rest of an expression if already knows an answer. In the following example you may see, that expression on the right side is not checked at all! Mind also, that variable x was never defined!

>>> False and x > 1
False
>>>
>>> x
Traceback (most recent call last):
NameError: name 'x' is not defined

Python will see False and .... False and something will always return False so Python does performance optimization and won't even check the other argument. In this case, it would fail with NameError if it does.

10.1.6. Membership

  • in checks whether value is in sequence

  • works with str, list, tuple, set, dict

  • O(n) - contains in str

  • O(n) - contains in list

  • O(n) - contains in tuple

  • O(1) - contains in set

  • O(1) - contains in dict

  • More information in Performance Optimization Contains

Contains with str:

>>> 'P' in 'Python'
True
>>>
>>> 'p' in 'Python'
False
>>> 'Python' in 'Python'
True
>>>
>>> 'Py' in 'Python'
True

Contains with list:

>>> 1 in [1, 2, 3]
True
>>>
>>> [1] in [1, 2, 3]
False
>>>
>>> [1, 2] in [[1, 2], [3, 4]]
True

Contains with tuple:

>>> 1 in (1, 2, 3)
True
>>>
>>> (1) in (1, 2)
True
>>>
>>> (1,) in (1, 2)
False
>>>
>>> (1, 2) in ((1, 2), (3, 4))
True

Contains with set:

>>> 1 in {1, 2}
True
>>>
>>> {1} in {1, 2}
False
>>>
>>> (1, 2) in {(1, 2), (3, 4)}
True
>>>
>>> {1, 2} in {{1, 2}, {3, 4}}
Traceback (most recent call last):
TypeError: unhashable type: 'set'

Contains with dict:

>>> crew = {
...     'commander': 'Melissa Lewis',
...     'botanist': 'Mark Watney',
...     'pilot': 'Rick Martinez',
... }
>>>
>>>
>>> 'commander' in crew
True
>>>
>>> 'chemist' in crew
False
>>>
>>> 'Melissa Lewis' in crew
False
>>> crew = {
...     'commander': 'Melissa Lewis',
...     'botanist': 'Mark Watney',
...     'pilot': 'Rick Martinez',
... }
>>>
>>>
>>> 'commander' in crew.keys()
True
>>>
>>> 'Melissa Lewis' in crew.values()
True

Use Case:

>>> text = 'Monty Python'
>>>
>>> if 'Python' in text:
...     print('yes')
... else:
...     print('no')
yes
>>> users = {'mwatney', 'mlewis', 'rmartinez'}
>>>
>>> if 'mwatney' in users:
...     print('yes')
... else:
...     print('no')
yes

10.1.7. Operator Precedence

  • Precedence - when an expression contains two different kinds of operators,which should be applied first?

  • Associativity - when an expression contains two operators with the same precedence, which should be applied first?

  • Order: not, and, or,

Precedence:

>>> 1 + 2 * 3
7

Associativity:

>>> 1 + 2 - 3
0
Table 10.1. Operator precedence

Operator

Description

(expressions...), [expressions...], {key: value...}, {expressions...}

Binding or parenthesized expression, list display, dictionary display, set display

x[index], x[index:index], x(arguments...), x.attribute

Subscription, slicing, call, attribute reference

await x

Await expression

**

Exponentiation

+x, -x, ~x

Positive, negative, bitwise NOT

*, @, /, //, %

Multiplication, matrix multiplication, division, floor division, remainder

+, -

Addition and subtraction

<<, >>

Shifts

&

Bitwise AND

^

Bitwise XOR

|

Bitwise OR

not x

Boolean NOT

and

Boolean AND

or

Boolean OR

if - else

Conditional expression

lambda

Lambda expression

:=

Assignment expression

10.1.8. Use Case - 1

>>> admins = {'alice', 'bob', 'carol'}
>>> login = 'mallory'
>>>
>>> if login not in admins:
...     print('Access denied')
...
Access denied

10.1.9. Use Case - 2

>>> login = 'alice'
>>> password = 'alicepass'
>>>
>>> login == 'alice' and password == 'alicepass'
True

Because:

>>> login == 'alice'
True
>>>
>>> password == 'alicepass'
True

Therefore:

>>> True and True
True

10.1.10. Use Case - 4

>>> login = 'alice'
>>> password = 'alicepass'
>>>
>>> login == 'alice' or login == 'bob'
True

Because:

>>> login == 'alice'
True
>>>
>>> login == 'bob'
False

Therefore:

>>> True or False
True

10.1.11. Use Case - 5

>>> login = 'alice'
>>> password = 'alicepass'
>>>
>>> (login == 'alice' and password == 'alicepass') or \
... (login == 'bob' and password == 'bobpass') or \
... (login == 'carol' and password == 'carolpass')
True

Because:

>>> login == 'alice' and password == 'alicepass'
True
>>>
>>> login == 'bob' and password == 'bobpass'
False
>>>
>>> login == 'carol' and password == 'carolpass'
False

Therefore:

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

10.1.12. Use Case - 1

>>> import sys
>>>
>>>
>>> print(sys.version_info)
sys.version_info(major=3, minor=13, micro=..., releaselevel='final', serial=0)

Compare:

>>> sys.version_info >= (3, 9)
True
>>>
>>> sys.version_info >= (3, 14)
False
>>> sys.version_info >= (3, 9, 0)
True
>>>
>>> sys.version_info >= (3, 14, 0)
False

10.1.13. Recap

  • not ... - negation

  • ... and ... - conjunction

  • ... or ... - disjunction

  • Precedence: not, and, or

  • use round brackets ( and ) to make code more readable

Define:

>>> x = True
>>> x = False

Check:

>>> data = True
>>>
>>> x = data is True        # True
>>> x = data is not True    # False

Negation

>>> x = not True            # False
>>> x = not False           # True

Conjunction:

>>> x = True and True       # True
>>> x = True and False      # False
>>> x = False and True      # False
>>> x = False and False     # False

Disjunction:

>>> x = True or True        # True
>>> x = True or False       # True
>>> x = False or True       # True
>>> x = False or False      # False

Membership:

>>> data = {1, 2, 3}
>>> 0 in data
False

10.1.14. Assignments

# %% About
# - Name: Conditional Logic Negation
# - Difficulty: easy
# - Lines: 2
# - Minutes: 2

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Define `result_a: bool` with result of `bool(not True)`
# 2. Define `result_b: bool` with result of `bool(not False)`
# 3. Non-functional requirements:
#    - run doctests - all must succeed
#    - in place of ellipsis (`...`) insert only `True` or `False`
#    - do not evaluate expressions in REPL or script
#    - fill in what you think is the result
#    - this assignment checks if you understand the bool type

# %% Polish
# 1. Zdefiniuj `result_a: bool` z wynikiem `bool(not True)`
# 2. Zdefiniuj `result_b: bool` z wynikiem `bool(not False)`
# 3. Wymagania niefunkcjonalne:
#    - uruchom doctesty - wszystkie muszą się powieść
#    - w miejsce trzech kropek (`...`) wstawiaj tylko `True` lub `False`
#    - nie ewaluuj wyrażeń w REPL'u ani w skrypcie Python
#    - wpisz to co Ci sie wydaje, że jest wynikiem
#    - zadanie sprawdza, czy rozumiesz typ bool

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

>>> assert result_a is not Ellipsis, \
'Assign your result to variable `result_a`'
>>> assert type(result_a) is bool, \
'Variable `result_a` has invalid type, should be bool'
>>> assert (not True) == result_a, \
'Variable `result_b` has invalid value, check calculation'

>>> assert result_b is not Ellipsis, \
'Assign your result to variable `result_b`'
>>> assert type(result_b) is bool, \
'Variable `result_b` has invalid type, should be bool'
>>> assert (not False) == result_b, \
'Variable `result_b` has invalid value, check calculation'
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result_a: bool
result_b: bool

# %% Data

# %% Result
result_a = ...
result_b = ...

# %% About
# - Name: Conditional Logic Conjunction
# - Difficulty: easy
# - Lines: 4
# - Minutes: 2

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Define `result_a: bool` with result of `bool(True and True)`
# 2. Define `result_b: bool` with result of `bool(True and False)`
# 3. Define `result_c: bool` with result of `bool(False and True)`
# 4. Define `result_d: bool` with result of `bool(False and False)`
# 5. Non-functional requirements:
#    - run doctests - all must succeed
#    - in place of ellipsis (`...`) insert only `True` or `False`
#    - do not evaluate expressions in REPL or script
#    - fill in what you think is the result
#    - this assignment checks if you understand the bool type

# %% Polish
# 1. Zdefiniuj `result_a: bool` z wynikiem `bool(True and True)`
# 2. Zdefiniuj `result_b: bool` z wynikiem `bool(True and False)`
# 3. Zdefiniuj `result_c: bool` z wynikiem `bool(False and True)`
# 4. Zdefiniuj `result_d: bool` z wynikiem `bool(False and False)`
# 5. Wymagania niefunkcjonalne:
#    - uruchom doctesty - wszystkie muszą się powieść
#    - w miejsce trzech kropek (`...`) wstawiaj tylko `True` lub `False`
#    - nie ewaluuj wyrażeń w REPL'u ani w skrypcie Python
#    - wpisz to co Ci sie wydaje, że jest wynikiem
#    - zadanie sprawdza, czy rozumiesz typ bool

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

>>> assert result_a is not Ellipsis, \
'Assign your result to variable `result_a`'
>>> assert type(result_a) is bool, \
'Variable `result_a` has invalid type, should be bool'
>>> assert bool(True and True) == result_a, \
'Variable `result_a` has invalid value'

>>> assert result_b is not Ellipsis, \
'Assign your result to variable `result_b`'
>>> assert type(result_b) is bool, \
'Variable `result_b` has invalid type, should be bool'
>>> assert bool(True and False) == result_b, \
'Variable `result_b` has invalid value'

>>> assert result_c is not Ellipsis, \
'Assign your result to variable `result_c`'
>>> assert type(result_c) is bool, \
'Variable `result_c` has invalid type, should be bool'
>>> assert bool(False and True) == result_c, \
'Variable `result_c` has invalid value'

>>> assert result_d is not Ellipsis, \
'Assign your result to variable `result_d`'
>>> assert type(result_d) is bool, \
'Variable `result_d` has invalid type, should be bool'
>>> assert bool(False and False) == result_d, \
'Variable `result_d` has invalid value'
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result_a: bool
result_b: bool
result_c: bool
result_d: bool

# %% Data

# %% Result
result_a = ...
result_b = ...
result_c = ...
result_d = ...

# %% About
# - Name: Conditional Logic Disjunction
# - Difficulty: easy
# - Lines: 4
# - Minutes: 2

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Define `result_a: bool` with result of `bool(True or True)`
# 2. Define `result_b: bool` with result of `bool(True or False)`
# 3. Define `result_c: bool` with result of `bool(False or True)`
# 4. Define `result_d: bool` with result of `bool(False or False)`
# 5. Non-functional requirements:
#    - run doctests - all must succeed
#    - in place of ellipsis (`...`) insert only `True` or `False`
#    - do not evaluate expressions in REPL or script
#    - fill in what you think is the result
#    - this assignment checks if you understand the bool type

# %% Polish
# 1. Zdefiniuj `result_a: bool` z wynikiem `bool(True or True)`
# 2. Zdefiniuj `result_b: bool` z wynikiem `bool(True or False)`
# 3. Zdefiniuj `result_c: bool` z wynikiem `bool(False or True)`
# 4. Zdefiniuj `result_d: bool` z wynikiem `bool(False or False)`
# 5. Wymagania niefunkcjonalne:
#    - uruchom doctesty - wszystkie muszą się powieść
#    - w miejsce trzech kropek (`...`) wstawiaj tylko `True` lub `False`
#    - nie ewaluuj wyrażeń w REPL'u ani w skrypcie Python
#    - wpisz to co Ci sie wydaje, że jest wynikiem
#    - zadanie sprawdza, czy rozumiesz typ bool

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

>>> assert result_a is not Ellipsis, \
'Assign your result to variable `result_a`'
>>> assert type(result_a) is bool, \
'Variable `result_a` has invalid type, should be bool'
>>> assert bool(True or True) == result_a, \
'Variable `result_a` has invalid value'

>>> assert result_b is not Ellipsis, \
'Assign your result to variable `result_b`'
>>> assert type(result_b) is bool, \
'Variable `result_b` has invalid type, should be bool'
>>> assert bool(True or False) == result_b, \
'Variable `result_b` has invalid value'

>>> assert result_c is not Ellipsis, \
'Assign your result to variable `result_c`'
>>> assert type(result_c) is bool, \
'Variable `result_c` has invalid type, should be bool'
>>> assert bool(False or True) == result_c, \
'Variable `result_c` has invalid value'

>>> assert result_d is not Ellipsis, \
'Assign your result to variable `result_d`'
>>> assert type(result_d) is bool, \
'Variable `result_d` has invalid type, should be bool'
>>> assert bool(False or False) == result_d, \
'Variable `result_d` has invalid value'
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result_a: bool
result_b: bool
result_c: bool
result_d: bool

# %% Data

# %% Result
result_a = ...
result_b = ...
result_c = ...
result_d = ...

# %% About
# - Name: Conditional Logic Algebra
# - Difficulty: easy
# - Lines: 8
# - Minutes: 5

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Define `result_a: bool` with result of `bool(True or True and True)`
# 2. Define `result_b: bool` with result of `bool(True or False and True)`
# 3. Define `result_c: bool` with result of `bool(False or True and True)`
# 4. Define `result_d: bool` with result of `bool(False or False and True)`
# 5. Define `result_e: bool` with result of `bool(True and True or True)`
# 6. Define `result_f: bool` with result of `bool(True and False or True)`
# 7. Define `result_g: bool` with result of `bool(False and True or True)`
# 8. Define `result_h: bool` with result of `bool(False and False or True)`
# 9. Non-functional requirements:
#    - run doctests - all must succeed
#    - in place of ellipsis (`...`) insert only `True` or `False`
#    - do not evaluate expressions in REPL or script
#    - fill in what you think is the result
#    - this assignment checks if you understand the bool type

# %% Polish
# 1. Zdefiniuj `result_a: bool` z wynikiem `bool(True or True and True)`
# 2. Zdefiniuj `result_b: bool` z wynikiem `bool(True or False and True)`
# 3. Zdefiniuj `result_c: bool` z wynikiem `bool(False or True and True)`
# 4. Zdefiniuj `result_d: bool` z wynikiem `bool(False or False and True)`
# 5. Zdefiniuj `result_e: bool` z wynikiem `bool(True and True or True)`
# 6. Zdefiniuj `result_f: bool` z wynikiem `bool(True and False or True)`
# 7. Zdefiniuj `result_g: bool` z wynikiem `bool(False and True or True)`
# 8. Zdefiniuj `result_h: bool` z wynikiem `bool(True and False or True)`
# 9. Wymagania niefunkcjonalne:
#    - uruchom doctesty - wszystkie muszą się powieść
#    - w miejsce trzech kropek (`...`) wstawiaj tylko `True` lub `False`
#    - nie ewaluuj wyrażeń w REPL'u ani w skrypcie Python
#    - wpisz to co Ci sie wydaje, że jest wynikiem
#    - zadanie sprawdza, czy rozumiesz typ bool

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

>>> assert result_a is not Ellipsis, \
'Assign your result to variable `result_a`'
>>> assert type(result_a) is bool, \
'Variable `result_a` has invalid type, should be bool'
>>> assert bool(True or True and True) == result_a, \
'Variable `result_a` has invalid value'

>>> assert result_b is not Ellipsis, \
'Assign your result to variable `result_b`'
>>> assert type(result_b) is bool, \
'Variable `result_b` has invalid type, should be bool'
>>> assert bool(True or False and True) == result_b, \
'Variable `result_b` has invalid value'

>>> assert result_c is not Ellipsis, \
'Assign your result to variable `result_c`'
>>> assert type(result_c) is bool, \
'Variable `result_c` has invalid type, should be bool'
>>> assert bool(False or True and True) == result_c, \
'Variable `result_c` has invalid value'

>>> assert result_d is not Ellipsis, \
'Assign your result to variable `result_d`'
>>> assert type(result_d) is bool, \
'Variable `result_d` has invalid type, should be bool'
>>> assert bool(False or False and True) == result_d, \
'Variable `result_d` has invalid value'

>>> assert result_e is not Ellipsis, \
'Assign your result to variable `result_e`'
>>> assert type(result_e) is bool, \
'Variable `result_e` has invalid type, should be bool'
>>> assert bool(True and True or True) == result_e, \
'Variable `result_e` has invalid value'

>>> assert result_f is not Ellipsis, \
'Assign your result to variable `result_f`'
>>> assert type(result_f) is bool, \
'Variable `result_f` has invalid type, should be bool'
>>> assert bool(True and False or True) == result_f, \
'Variable `result_f` has invalid value'

>>> assert result_g is not Ellipsis, \
'Assign your result to variable `result_g`'
>>> assert type(result_g) is bool, \
'Variable `result_g` has invalid type, should be bool'
>>> assert bool(False and True or True) == result_g, \
'Variable `result_g` has invalid value'

>>> assert result_h is not Ellipsis, \
'Assign your result to variable `result_h`'
>>> assert type(result_h) is bool, \
'Variable `result_h` has invalid type, should be bool'
>>> assert bool(False and False or True) == result_h, \
'Variable `result_h` has invalid value'
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% Imports

# %% Types
result_a: bool
result_b: bool
result_c: bool
result_d: bool
result_e: bool
result_f: bool
result_g: bool
result_h: bool

# %% Data

# %% Result
result_a = ...
result_b = ...
result_c = ...
result_d = ...
result_e = ...
result_f = ...
result_g = ...
result_h = ...