Найти - Пользователи
Полная версия: Реализовать в виде класса набор подпрограмм, для выполнения следующих операций над комплексными числами
Начало » Центр помощи » Реализовать в виде класса набор подпрограмм, для выполнения следующих операций над комплексными числами
1 2 3 4 5 6
Rodegast
> Надо два класса написать: один - само число, другой - калькулятор над такими числами.

Нет. Такое разделение противоречит принципу инкапсуляции.
py.user.next
Rodegast
Нет. Такое разделение противоречит принципу инкапсуляции.
Бредишь. Может, конечно, показаться, что там один класс лезет внутрь объекта другого класса, но это только кажется, потому что поля real и imag - это свойства, реализованные без методов (в идеале, их нужно сделать read-only). Фактически мы взяли несколько разных функций, работающих с комплексными числами, и объединили их в класс по принципу работы с объектами одного типа.
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']
py.user.next
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
> Он идёт как калькулятор для комплексных чисел, который можно передать куда-нибудь.

НЕТ. Он идёт как фабрика таких калькуляторов. Если тебе так калькуляторы нравятся, то не мелочись, делай специальный модуль, а потом таскай его прицепом. Правда без этого модуля твои суперчисла будут бесполезны и операторы их будут игнорировать, но зато твоя фантазия будет удовлетворена.

> я вижу, как встроенный метод разрастается, определяя внутри себя тип аргумента и выбирая правильную операцию под этот тип, и эта картинка меня не радует. Трёхкилометровый встроенный метод получается.

Python это язык со строгой типизацией. Это значит что разные типы данных должны явно приводится к одному типу. Конечно существует полиморфизм, но он ограничен. По этому не должно быть “трёхкилометровых встроенный методов”, а нужно явно приводить тип при необходимости.
py.user.next
Rodegast
Он идёт как фабрика таких калькуляторов.
Фабрика? Это где тут фабрика? Что-то я не вижу нигде. Просто набор статических методов (там нигде self не используется), объединённых в едином объекте. То есть мне не нужно портить комлексное число, если я хочу провести над ним специфическую операцию.

Вот фабрика
wiki. abstract factory
Код на C# посмотришь, там она классическая.

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])
>>>

Математически ты не можешь комплексное число на вектор умножить, так как операция умножения комплексных чисел определена на множестве комплексных чисел (при умножении комплексного числа на комплексное число получается комплексное число). Но в программировании ты можешь такое делать, преобразуя операцию умножения комплексного числа в операцию умножения вектора на комплексное число. Поэтому ты и в калькулятор это можешь добавить, так как он не фиксирован только на классических операциях, а только использует комплексные числа в вычислениях.
Rodegast
> Что-то я не вижу нигде. Просто набор статических методов (там нигде self не используется), объединённых в едином объекте.

Расскажи это своей бабушке:
 class ComplexCalc:
...     def add(self, c1, c2):
...        ....
...     def sub(self, c1, c2):
...        ....
...     def mul(self, c1, c2):
...        ....
...     def abs(self, c):
...        ....

> Вот смотри, что такое умножение вектора на число

Покажи ты мне класс-калькулятор встроенный в numpy который вектор на число умножает.
py.user.next
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]
>>>

Не думал, почему питон не умножает списки в соответствии с математическим законом? Операция умножения у списков своя, специфическая.
Rodegast
> он тебе сразу скажет “не используется self”.
 >>> calc = ComplexCalc()
>>> calc.add(Complex(1, 2), Complex(3, 4))
Объясни чем по твоему статический метод отличается от метода объекта.

> Так оно умножается само, потому что это в него зашито.

Ну вот и покажи в каком месте оно “зашито”.
AsphaltHero
Товарищи, прошу вас немного отвлечься от вашей дискуссии)
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)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB