> Надо два класса написать: один - само число, другой - калькулятор над такими числами.
Нет. Такое разделение противоречит принципу инкапсуляции.
RodegastБредишь. Может, конечно, показаться, что там один класс лезет внутрь объекта другого класса, но это только кажется, потому что поля real и imag - это свойства, реализованные без методов (в идеале, их нужно сделать read-only). Фактически мы взяли несколько разных функций, работающих с комплексными числами, и объединили их в класс по принципу работы с объектами одного типа.
Нет. Такое разделение противоречит принципу инкапсуляции.
>>> dir(complex) ['__abs__', '__add__', '__class__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv_ _', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__int__', '__le__', '__long__', '__ lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__pos__', '__pow__', '__radd__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr_ _', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', 'conjugate', 'imag', 'real']
RodegastОн идёт как калькулятор для комплексных чисел, который можно передать куда-нибудь. Допустим, ты делаешь суперкалькулятор, который умеет выполнять разные вычисления. И вот ты в него встраиваешь микрокалькулятор, который умеет оперировать комплексными числами разными способами. Потом ты в суперкалькулятор встраиваешь микрокалькулятор матриц, который умеет оперировать матрицами разными способами. Потом ещё что-нибудь встраиваешь. И потом ты между ними можешь что-нибудь делать внутри суперкалькулятора.
НАФИГА?
Rodegast>>> dir(complex)
>>> c = 1+2j >>> c.real 1.0 >>> c.imag 2.0 >>> c.real = 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: readonly attribute >>>
RodegastФабрика? Это где тут фабрика? Что-то я не вижу нигде. Просто набор статических методов (там нигде self не используется), объединённых в едином объекте. То есть мне не нужно портить комлексное число, если я хочу провести над ним специфическую операцию.
Он идёт как фабрика таких калькуляторов.
RodegastНу так я тебе и предложил поумножать комплексное число на объекты разных типов через встроенный метод умножения у этого комплексного числа. К чему ты собрался приводить вектор?
Это значит что разные типы данных должны явно приводится к одному типу.
>>> import numpy as np >>> >>> np.array([1, 2, 3]) array([1, 2, 3]) >>> np.array([1, 2, 3]) * 3 array([3, 6, 9]) >>> np.array([1, 2, 3]) * (3+2j) array([ 3.+2.j, 6.+4.j, 9.+6.j]) >>> np.array([1+1j, 2+2j, 3+3j]) * (3+2j) array([ 1. +5.j, 2.+10.j, 3.+15.j]) >>>
class ComplexCalc: ... def add(self, c1, c2): ... .... ... def sub(self, c1, c2): ... .... ... def mul(self, c1, c2): ... .... ... def abs(self, c): ... ....
RodegastЯ не стал декорировать просто все эти методы, но если ты их через линтер проведёшь, он тебе сразу скажет “не используется self”.
Расскажи это своей бабушке:
>>> class Complex: ... def __init__(self, real, imag): ... self.real = real ... self.imag = imag ... def __str__(self): ... sign = '+' if self.imag >= 0 else '' ... return '{}{}{}i'.format(self.real, sign, self.imag) ... __repr__ = __str__ ... >>> class ComplexCalc: ... @staticmethod ... def add(c1, c2): ... real = c1.real + c2.real ... imag = c1.imag + c2.imag ... return Complex(real, imag) ... @staticmethod ... def sub(c1, c2): ... real = c1.real - c2.real ... imag = c1.imag - c2.imag ... return Complex(real, imag) ... @staticmethod ... def mul(c1, c2): ... real = c1.real * c2.real - c1.imag * c2.imag ... imag = c1.imag * c2.real + c1.real * c2.imag ... return Complex(real, imag) ... @staticmethod ... def abs(c): ... return (c.real ** 2 + c.imag ** 2) ** 0.5 ... >>> calc = ComplexCalc() >>> calc.add(Complex(1, 2), Complex(3, 4)) 4+6i >>> calc.sub(Complex(1, 2), Complex(3, 4)) -2-2i >>> calc.mul(Complex(1, 2), Complex(3, 4)) -5+10i >>> calc.abs(Complex(3, 4)) 5.0 >>>
RodegastТак оно умножается само, потому что это в него зашито. А как ты думаешь массив понимает, как на число уножаться?
Покажи ты мне класс-калькулятор встроенный в numpy который вектор на число умножает.
>>> import numpy >>> >>> numpy.array([1, 2, 3]) * 3 array([3, 6, 9]) >>> >>> [1, 2, 3] * 3 [1, 2, 3, 1, 2, 3, 1, 2, 3] >>>
>>> calc = ComplexCalc() >>> calc.add(Complex(1, 2), Complex(3, 4))
py.user.next
Rodegast
class Complex: def __init__(self, real, imag): self.real = real self.imag = imag def __str__(self): sign = '+' if self.imag >= 0 else '' return '{}{}{}i'.format(self.real, sign, self.imag) class ComplexCalc: def add(self, c1, c2): real = c1.real + c2.real imag = c1.imag + c2.imag return Complex(real, imag) def sub(self, c1, c2): real = c1.real - c2.real imag = c1.imag - c2.imag return Complex(real, imag) def mul(self, c1, c2): real = c1.real * c2.real - c1.imag * c2.imag imag = c1.imag * c2.real + c1.real * c2.imag return Complex(real, imag) def abs(self, c, n): return (c.real ** 2 + c.imag ** 2) ** 0.5 def pow(self, c, n): # вот тут основная проблема calc = ComplexCalc() a = Complex(2, 3) a = calc.pow(a, 2) print(a)