# 11.8. Operator Arithmetic Increment¶

• += - iadd

• -= - isub

• *= - imul

• /= - idiv

• //= - itruediv

• **= - ipow

• %= - imod

• @= - imatmul

Operator

Method

obj += other

obj.__iadd__(other)

obj -= other

obj.__isub__(other)

obj *= other

obj.__imul__(other)

obj /= other

obj.__idiv__(other)

obj //= other

obj.__itruediv__(other)

obj **= other

obj.__ipow__(other)

obj %= other

obj.__imod__(other)

obj @= other

obj.__imatmul__(other)

## 11.8.2. Example¶

>>> class Vector:
...     def __init__(self, x, y):
...         self.x = x
...         self.y = y
...
...     def __repr__(self):
...         return f'Vector(x={self.x}, y={self.y})'
...
...     def __isub__(self, other): ...              # x -= y    calls x.__isub__(y)
...     def __imul__(self, other): ...              # x *= y    calls x.__imul__(y)
...     def __ipow__(self, power, modulo=None): ... # x **= y   calls x.__ipow__(y)
...     def __imatmul__(self, other): ...           # x @= y    calls x.__imatmul__(y)
...     def __itruediv__(self, other): ...          # x /= y    calls x.__itruediv__(y)
...     def __ifloordiv__(self, other): ...         # x //= y   calls x.__ifloordiv__(y)
...     def __imod__(self, other): ...              # x %= y    calls x.__imod__(y)


## 11.8.3. Increment Operation¶

>>> from dataclasses import dataclass

>>> @dataclass
... class Vector:
...     x: int
...     y: int
...
...         self.x += other.x
...         self.y += other.y
...         return self
...
>>>
>>>
>>> a = Vector(x=1, y=2)
>>> b = Vector(x=3, y=4)
>>> c = Vector(x=5, y=6)
>>>
>>>
>>> a += Vector(x=10, y=20)
>>> print(a)
Vector(x=11, y=22)


## 11.8.4. Use Case - 0x01¶

>>> from dataclasses import dataclass, field
>>>
>>>
>>> @dataclass
... class Astronaut:
...     firstname: str
...     lastname: str
>>>
>>>
>>> @dataclass
... class Crew:
...     members: list[Astronaut] = field(default_factory=list)
...
...         self.members.append(other)
...         return self
>>>
>>>
>>> ares3 = Crew()
>>> ares3 += Astronaut('Mark', 'Watney')
>>> ares3 += Astronaut('Melissa', 'Lewis')
>>>
>>> print(ares3)
Crew(members=[Astronaut(firstname='Mark', lastname='Watney'), Astronaut(firstname='Melissa', lastname='Lewis')])
>>>
>>> for member in ares3.members:
...     print(member)
Astronaut(firstname='Mark', lastname='Watney')
Astronaut(firstname='Melissa', lastname='Lewis')


## 11.8.5. Assignments¶

"""
* Assignment: Operator Numerical Matmul
* Complexity: easy
* Lines of code: 3 lines
* Time: 3 min

English:
1. Make object understand following call: position @ (1, 2)
1. Overload @ operator, to take tuple[int, int] as argument
2. Set x and y coordinates based on passed values
3. Run doctests - all must succeed

Polish:
1. Spraw aby obiekt obsługiwał to wywołanie: position @ (1, 2)
1. Przeciąż operator @, aby przyjmował tuple[int, int] jako argument
2. Zmień koordynaty x i y na podstawie przekazanych wartości
3. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* object.__matmul__()

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

>>> position = Position()
>>> position
Position(x=0, y=0)
>>> position @ (1, 2)
>>> position
Position(x=1, y=2)
"""

from dataclasses import dataclass

@dataclass
class Position:
x: int = 0
y: int = 0


"""
* Complexity: easy
* Lines of code: 3 lines
* Time: 5 min

English:
1. Overload operator +=
2. Make Astronaut objects able to add Missions, for example:
a. mark = Astronaut(firstname='Mark', lastname='Watney')
b. mark += Mission(2035, 'Ares3')
c. mark += Mission(2040, 'Ares5')
3. Run doctests - all must succeed

Polish:
1. Przeciąż operator +=
2. Spraw aby do obiektów klasy Astronaut można dodać Mission, przykład:
a. mark = Astronaut(firstname='Mark', lastname='Watney')
b. mark += Mission(2035, 'Ares3')
c. mark += Mission(2040, 'Ares5')
3. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* object.__iadd__() -> self

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

>>> astro = Astronaut(firstname='Mark', lastname='Watney', missions=[
...     Mission(1969, 'Apollo 11'),
... ])
>>> astro += Mission(2024, 'Artemis 3')
>>> astro += Mission(2035, 'Ares 3')

>>> print(astro)  # doctest: +NORMALIZE_WHITESPACE
Astronaut(firstname='Mark', lastname='Watney',
missions=[Mission(year=1969, name='Apollo 11'),
Mission(year=2024, name='Artemis 3'),
Mission(year=2035, name='Ares 3')])
"""

from dataclasses import dataclass

@dataclass
class Astronaut:
firstname: str
lastname: str
missions: list

@dataclass
class Mission:
year: int
name: str