# Magic Methods

In Python, magic methods are special methods that you can define to add functionality to your classes. They are also known as dunder methods, due to the double underscores

`__`

that precede and follow their names. You have already met two of these methods: `__init__`

and `__str__`

. Take a look at a simple example:```
class Circle:
def __init__(self, radius): # Initialize the object
self.radius = radius
def __str__(self): # Represent as a string
return f'Circle with radius {self.radius}'
c = Circle(5) # Create a Circle object named c
print(c) # Circle with radius 5
```

In the example, we have defined two magic methods:

`__init__`

is a constructor method that gets called when an instance of the class is created. Here, it sets the radius of the Circle.

`__str__`

defines how an instance of the class should be converted to a string when used in contexts like`print()`

.

But these are not the only magic methods in Python. There are many more. Some are presented below that allow us to make class instances have the ability to be added together with a

`+`

or compared with a `<`

or `>`

:```
class Circle:
def __init__(self, radius): # Initialize the object
self.radius = radius
def __str__(self): # Represent as a string
return f'Circle with radius {self.radius}'
def __add__(self, other): # Add two circles
return Circle(self.radius + other.radius) # Return a new circle
def __lt__(self, other): # Less than comparison of two circles
return self.radius < other.radius # Compare radiuses
c1 = Circle(5)
c2 = Circle(7)
c3 = c1 + c2 # This would create a new Circle with radius 12
print(c3) # Circle with radius 12
print(c1 < c2) # True
```

In this case:

`__add__`

allows us to use the`+`

operator with Circle instances. It adds the radius of the circles and returns a new Circle.

`__lt__`

(less than) allows us to compare two Circle instances with the`<`

operator. It checks if the radius of the first circle is less than the radius of the second.

Magic methods make our Python classes more expressive and intuitive, behaving more like built-in Python objects.

Remember to keep the special double underscore naming, because Python's interpreter looks for these specially named methods to perform certain operations. You can find the list of all the magic methods available in Python by following this link. Below are some of the popular available magic methods:

Magic Method | Operator | Description |

`__eq__` | `==` | Returns `True` if `self` is equal to `other` . |

`__lt__` | `<` | Returns `True` if `self` is less than `other` . |

`__le__` | `<=` | Returns `True` if `self` is less than or equal to `other` . |

`__gt__` | `>` | Returns `True` if `self` is greater than `other` . |

`__ge__` | `>=` | Returns `True` if `self` is greater than or equal to `other` . |

`__add__(self, other)` | `+` | Implements addition with the `+` operator. |

`__sub__(self, other)` | `-` | Implements subtraction with the `-` operator. |

`__mul__(self, other)` | `*` | Implements multiplication with the `*` operator. |

`__truediv__(self, other)` | `/` | Implements division with the `/` operator. |

`__floordiv__(self, other)` | `//` | Implements floor division with the `//` operator. |

`__mod__(self, other)` | `%` | Implements modulus with the `%` operator. |

`__pow__(self, other)` | `**` | Implements the power operator `**` . |

`__abs__(self)` | `abs()` | Implements behavior for the built-in `abs()` function. |

`__round__(self, n)` | `round()` | Implements behavior for the built-in `round()` function. |

`__neg__(self)` | `-` | Implements negation with the unary `-` operator. |

💡

Note that not all methods make sense for all classes; you should implement only those that are useful for your problem.

Challenge: Create a Vector Class

You are asked to define a class, Vector, that represents a three-dimensional vector with attributes

`x`

, `y`

, and `z`

.The class should include the implementation of special methods

`__add__`

, `__sub__`

and `__mul__`

for vector addition, subtraction, and dot product respectively.In addition to these, implement a method,

`magnitude`

, to calculate the magnitude of the vector.The requested methods:

`__add__`

: This method should accept another Vector object and return a new Vector which is the result of adding the x, y, and z components of the two vectors.

`__sub__`

: This method should accept another Vector object and return a new Vector which is the result of subtracting the x, y, and z components of the second vector from the first.

`__mul__`

: This method should accept another Vector object and return the dot product of the two vectors, calculated as .

`magnitude`

: This method should return the magnitude (length) of the vector, calculated as .

Input | Output |

`v1 = Vector(1, 2, 3); v2 = Vector(4, 5, 6); v3 = v1 + v2; v4 = v1 - v2; print(v1 * v2); print(v1.magnitude()); v4 = Vector(-3, -3, -3)` | 32
3.74165 |

#### Constraints

Time limit: 2 seconds

Memory limit: 512 MB

Output limit: 1 MB