Skip to content

Instantly share code, notes, and snippets.

@dmitriyKolmogorov
Last active July 10, 2020 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitriyKolmogorov/256008b702073c0a3fd0009be3a44aaa to your computer and use it in GitHub Desktop.
Save dmitriyKolmogorov/256008b702073c0a3fd0009be3a44aaa to your computer and use it in GitHub Desktop.
from collections.abc import Iterable
class Vector(object):
def __init__(self, *args):
if isinstance(args[0], int) or isinstance(args[0], float):
self.__values = tuple(args)
else:
if len(args) != 1:
raise ValueError('Expected 1 argument which is not of type float or int.')
self.__values = list(args[0])
self.shape = len(self.__values)
def __len__(self):
return self.shape
def __iter__(self):
return iter(self.__values)
def __hash__(self):
return hash(tuple(self.__values))
def __getitem__(self, key):
if isinstance(key, slice):
return Vector(self.__values[key])
elif isinstance(key, Iterable):
return Vector([self.__values[i] for i in key])
else:
return self.__values[key]
def __setitem__(self, key, value):
self.__values[key] = value
def __reversed__(self):
rev_values = reversed(self.__values)
return Vector(rev_values)
def __contains__(self, value):
return value in self.__values
def __delitem__(self, key):
del self.__values[key]
self = Vector(self.__values)
def __bool__(self) -> bool:
for value in self.__values:
if value != 0:
return True
return False
def __abs__(self):
return sum(self**2)**0.
def __eq__(self, value):
return all([v1 == v2 for v1, v2 in zip(self, value)])
def __ne__(self, value):
return not self.__eq__(value)
def __lt__(self, value):
raise TypeError('Vector class does not support comparison operations.')
def __gt__(self, value):
raise TypeError('Vector class does not support comparison operations.')
def __le__(self, value):
raise TypeError('Vector class does not support comparison operations.')
def __ge__(self, value):
raise TypeError('Vector class does not support comparison operations.')
def __str__(self) -> str:
return '<' + ', '.join([str(v) for v in self]) + '>'
def __repr__(self) -> str:
return 'Vector(' + self.__str__() + ')'
def __mul__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value * coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 * v1 for v1, v2 in zip(value, self)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __div__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor / value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 / v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __add__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor + value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 + v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __sub__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor - value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 - v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __mod__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor % value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 % v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __floordiv__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor // value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 // v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __divmod__(self, value):
raise TypeError('This class does not support using with divmod() function.')
def __pow__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor ** value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 ** v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __lshift__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor << value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 << v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rshift__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([coor >> value for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v1 >> v2 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __and__(self, value):
return bool(value) & bool(self)
def __or__(self, value):
return bool(value) | bool(self)
def __xor__(self, value):
return bool(value) ^ bool(self)
def __rsub__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value - coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 - v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rpow__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value ** coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 ** v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rdiv__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value / coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 / v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rfloordiv__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value // coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 // v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rmod__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value % coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 % v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rlshift__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value << coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 << v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __radd__(self, value):
return self.__add__(value)
def __rmul__(self, value):
return self.__mul__(value)
def __rrshift__(self, value):
if isinstance(value, int) or isinstance(value, float):
return Vector([value >> coor for coor in self])
elif isinstance(value, Vector):
if value.shape != self.shape:
raise ValueError(f'Wrong dimension for operand. Expected {self.shape}, got {value.shape}')
return Vector([v2 >> v1 for v1, v2 in zip(self, value)])
else:
raise TypeError(f'Invalid type for operand. Expected int, float or Vector (got {type(value)}).')
def __rand__(self, value):
return bool(value) & bool(self)
def __ror__(self, value):
return bool(value) | bool(self)
def __rxor__(self, value):
return bool(value) ^ bool(self)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment