import math
# noinspection PyTypeChecker
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __neg__(self): # operator - (унарный), противоположный вектор
return Point(-self.x, -self.y)
def __invert__(self): # operator ~ (унарный), поворот на 90 градусов
return Point(-self.y, self.x)
def __add__(self, other): # operator +, сложение векторов
return Point(self.x + other.x, self.y + other.y)
def __sub__(self, other): # operator -, вычитание векторов
return Point(self.x - other.x, self.y - other.y)
def __truediv__(self, other): # operator /, скалярное произведение
return self.x * other.x + self.y * other.y
def __mod__(self, other): # operator %, векторное произведение
return self.x * other.y - self.y * other.x
def __mul__(self, other): # operator *, умножение на число
return {self.x * other, self.y * other}
def argument(self):
return math.atan2(self.y, self.x)
def length(self):
return math.sqrt(self / self)
a, b = Point(4, 2), Point(10, 12)
c = a + b
print(c.length(), c.argument() / math.pi, '* PI')
print(c / Point(-1, 1), c % Point(-1, 1))
aW1wb3J0IG1hdGgKCgojIG5vaW5zcGVjdGlvbiBQeVR5cGVDaGVja2VyCmNsYXNzIFBvaW50OgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHgsIHkpOgogICAgICAgIHNlbGYueCA9IHgKICAgICAgICBzZWxmLnkgPSB5CgogICAgZGVmIF9fbmVnX18oc2VsZik6ICMgb3BlcmF0b3IgLSAo0YPQvdCw0YDQvdGL0LkpLCDQv9GA0L7RgtC40LLQvtC/0L7Qu9C+0LbQvdGL0Lkg0LLQtdC60YLQvtGACiAgICAgICAgcmV0dXJuIFBvaW50KC1zZWxmLngsIC1zZWxmLnkpCgogICAgZGVmIF9faW52ZXJ0X18oc2VsZik6ICMgb3BlcmF0b3IgfiAo0YPQvdCw0YDQvdGL0LkpLCDQv9C+0LLQvtGA0L7RgiDQvdCwIDkwINCz0YDQsNC00YPRgdC+0LIKICAgICAgICByZXR1cm4gUG9pbnQoLXNlbGYueSwgc2VsZi54KQoKICAgIGRlZiBfX2FkZF9fKHNlbGYsIG90aGVyKTogIyBvcGVyYXRvciArLCDRgdC70L7QttC10L3QuNC1INCy0LXQutGC0L7RgNC+0LIKICAgICAgICByZXR1cm4gUG9pbnQoc2VsZi54ICsgb3RoZXIueCwgc2VsZi55ICsgb3RoZXIueSkKCiAgICBkZWYgX19zdWJfXyhzZWxmLCBvdGhlcik6ICMgb3BlcmF0b3IgLSwg0LLRi9GH0LjRgtCw0L3QuNC1INCy0LXQutGC0L7RgNC+0LIKICAgICAgICByZXR1cm4gUG9pbnQoc2VsZi54IC0gb3RoZXIueCwgc2VsZi55IC0gb3RoZXIueSkKCiAgICBkZWYgX190cnVlZGl2X18oc2VsZiwgb3RoZXIpOiAjIG9wZXJhdG9yIC8sINGB0LrQsNC70Y/RgNC90L7QtSDQv9GA0L7QuNC30LLQtdC00LXQvdC40LUKICAgICAgICByZXR1cm4gc2VsZi54ICogb3RoZXIueCArIHNlbGYueSAqIG90aGVyLnkKCiAgICBkZWYgX19tb2RfXyhzZWxmLCBvdGhlcik6ICMgb3BlcmF0b3IgJSwg0LLQtdC60YLQvtGA0L3QvtC1INC/0YDQvtC40LfQstC10LTQtdC90LjQtQogICAgICAgIHJldHVybiBzZWxmLnggKiBvdGhlci55IC0gc2VsZi55ICogb3RoZXIueAoKICAgIGRlZiBfX211bF9fKHNlbGYsIG90aGVyKTogIyBvcGVyYXRvciAqLCDRg9C80L3QvtC20LXQvdC40LUg0L3QsCDRh9C40YHQu9C+CiAgICAgICAgcmV0dXJuIHtzZWxmLnggKiBvdGhlciwgc2VsZi55ICogb3RoZXJ9CgogICAgZGVmIGFyZ3VtZW50KHNlbGYpOgogICAgICAgIHJldHVybiBtYXRoLmF0YW4yKHNlbGYueSwgc2VsZi54KQoKICAgIGRlZiBsZW5ndGgoc2VsZik6CiAgICAgICAgcmV0dXJuIG1hdGguc3FydChzZWxmIC8gc2VsZikKCgphLCBiID0gUG9pbnQoNCwgMiksIFBvaW50KDEwLCAxMikKYyA9IGEgKyBiCnByaW50KGMubGVuZ3RoKCksIGMuYXJndW1lbnQoKSAvIG1hdGgucGksICcqIFBJJykKcHJpbnQoYyAvIFBvaW50KC0xLCAxKSwgYyAlIFBvaW50KC0xLCAxKSk=