from collections import namedtuple
from functools import partial
from itertools import starmap
import operator

class Vector:
	def _lift_un(self, op):
		"""apply unary operator"""
		return map(op, self)
	
	def _lift_bi(self, op, v):
		"""apply binary operator"""
		return starmap(op, zip(self, v))
	
	def __mul__(self, s):
		return type(self)(*self._lift_un(partial(operator.mul, s)))
	
	__rmul__ = __mul__
	
	def __neg__(self):
		return type(self)(*self._lift_un(operator.neg))
	
	def __pos__(self):
		return type(self)(*self._lift_un(operator.pos))
	
	def __abs__(self):
		return sum(self._lift_un(lambda x: x**2))**.5
	
	def __add__(self, v):
		return type(self)(*self._lift_bi(operator.add, v))
	
	__radd__ = __add__
	
	def __sub__(self, v):
		return type(self)(*self._lift_bi(operator.sub, v))
	
	def __eq__(self, v):
		return all(self._lift_bi(operator.eq, v))
	
	def __ne__(self, v):
		return any(self._lift_bi(operator.ne, v))
	
	def __repr__(self):
		return '%s(%s)' % (type(self).__name__,
						   ', '.join(self._lift_un(repr)))

class Vector3(Vector, namedtuple('_Vector3', 'x y z')):
	pass
	
vector = Vector3(0, 0, 0)

print vector
print vector + Vector3(1,1,1)
print vector * 5
print abs(vector)
print (vector - Vector3(1,2,3)) * 2 == Vector3(-2,-4,-6)