## Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

### Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

# Python "magic methods" clarification

I'm having trouble wrapping my head around what these methods ( x ) do exactly. I've found a few links that explain them somewhat, but I really haven't been able to pinpoint exactly what they are intended for. Can someone help me clarify exactly what they do? Are they specifically for objects/inheritance? Thanks in advance! I can post the links to the articles I've found if anyone is interested. The magic methods cover a lot of ground but one large aspect of them is operator overloading. I threw together an example `Vector` class to showcase some of them:

```class Vector(object):
def __init__(self, components=[]):
self.components = components

# Defines the behaviour for addition.
# Since we're making a Vector class we'll add corresponding components together
if len(self) == len(other):
result = []
for left, right in zip(self, other):
result.append(left + right)
return result
else:
raise ArithmeticError()

def __sub__(self, other):
# Similar setup to addition, just subtracting each component.
if len(self) == len(other):
result = []
for left, right in zip(self, other):
result.append(left - right)
return result
else:
raise ArithmeticError()

def __mul__(self, other):
# We'll do something more suited to a vector and return the dot product
if len(self) == len(other):
result = 0
for left, right in zip(self, other):
result += left * right
return result
else:
raise ArithmeticError()

def __eq__(self, other):
# We'll treat the vectors as equal if their components are equivalent and in the same order
# This is the default behaviour for a list so we can use the __eq__ method of it here.
return self.components == other.components

def __ne__(self, other):
# Reuse the code from the equality overload then flip the result
return not self == other

def __getitem__(self, item):
# Called when using this class like a list
return self.components[item]

def __contains__(self, item):
# This is called with keywords such as "in"
return item in self.components

def __len__(self):
# This is called when the len built in function is passed a Vector
return len(self.components)

def __iter__(self):
# Use the list's iterator so we don't have to write our own
# Used for things like for loops
return iter(self.components)

def __str__(self):
# String representation of the vector
return "{}".format(self.components)

if __name__ == "__main__":
vec1 = Vector([1,2,3])
vec2 = Vector([9,8,7])

print("Subtraction: {}".format(vec2 - vec1))
print("Size of vec1: {}".format(len(vec1)))
print("Does vec1 contain 5? {}".format(5 in vec1))
print("Does vec2 contain 9? {}".format(9 in vec2))
print("Dot product: {}".format(vec1 * vec2))
print("Do vec1 and vec2 have the same elements? {}".format(vec1 == vec2))
print("Is vec2 not equal to itself? {}".format(vec2 != vec2))
print("Last element of vec1: {}".format(vec1[-1]))
``` damn! that looks kinda advanced, but looks pretty great, I hope that i can code like that soon...or it isn't as complex as it looks?

either way, cool job man (Y)