11.11. Operator Comparison

  • in - contains

11.11.1. SetUp

>>> from functools import reduce

11.11.2. About

Table 11.6. Comparison Operator Overload

Operator

Method

obj < other

obj.__lt__(other)

obj <= other

obj.__le__(other)

obj > other

obj.__gt__(other)

obj >= other

obj.__ge__(other)

11.11.3. Use Case - 0x01

  • Game

>>> hero < Damage(20)  
>>> hero > Damage(20)  

11.11.4. Use Case - 0x02

  • Numpy

SetUp:

>>> import numpy as np
>>> from pprint import pprint

Python does not support element-wise comparison:

>>> data = [[1, 2, 3],
...         [4, 5, 6],
...         [7, 8, 9]]
>>>
>>>
>>> data > 2
Traceback (most recent call last):
TypeError: '>' not supported between instances of 'list' and 'int'

In Python you have to iterate over each row and each element in a row, then to create a temporary row-result to which you append the information, at the end, you append this temporary object to result and process next line:

>>> data = [[1, 2, 3],
...         [4, 5, 6],
...         [7, 8, 9]]
>>>
>>> result = []
>>>
>>> for row in data:
...     tmp = []
...     for number in row:
...         tmp.append(number > 2)
...     result.append(tmp)
>>>
>>>
>>> pprint(result, width=30)
[[False, False, True],
 [True, True, True],
 [True, True, True]]

Alternatively you can use nested list comprehensions to do the same:

>>> data = [[1, 2, 3],
...         [4, 5, 6],
...         [7, 8, 9]]
>>>
>>> result = [
...     [number > 2 for number in row]
...     for row in data
... ]
>>>
>>> pprint(result, width=30)
[[False, False, True],
 [True, True, True],
 [True, True, True]]

In numpy all the comparison is being done element-wise and we do not have to worry about iteration etc. It is called vectorized operation:

>>> data = np.array([[1, 2, 3],
...                  [4, 5, 6],
...                  [7, 8, 9]])
>>>
>>> data > 2
array([[False, False,  True],
       [ True,  True,  True],
       [ True,  True,  True]])

11.11.5. Assignments

Code 11.29. Solution
"""
* Assignment: Operator Comparison Equals
* Complexity: easy
* Lines of code: 3 lines
* Time: 5 min

English:
    1. Override operator for code to work correctly
    2. Do not use `dataclasses`
    3. Run doctests - all must succeed

Polish:
    1. Nadpisz operator aby poniższy kod zadziałał poprawnie
    2. Nie używaj `dataclasses`
    3. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> class Car:
    ...     def __init__(self, year, name):
    ...         self.year = year
    ...         self.name = name

    >>> Mission(2035, 'Ares 3') == Car(2035, 'Ares 3')
    False
    >>> Mission(2035, 'Ares 3') == Mission(2035, 'Ares 3')
    True
    >>> Mission(2035, 'Ares 3') == Mission(1973, 'Apollo 18')
    False
    >>> Mission(2035, 'Ares 3') == Mission(2035, 'Apollo 18')
    False
    >>> Mission(2035, 'Ares 3') == Mission(1973, 'Ares 3')
    False
"""

class Mission:
    def __init__(self, year, name):
        self.year = year
        self.name = name