Last active
July 10, 2020 12:42
-
-
Save dmitriyKolmogorov/256008b702073c0a3fd0009be3a44aaa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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