# deriving from complex

Discussion in 'Python' started by =?ISO-8859-1?Q?Sch=FCle_Daniel?=, Mar 7, 2006.

1. ### =?ISO-8859-1?Q?Sch=FCle_Daniel?=Guest

Hello

I am trying to customize the handling of complex numbers
what I am missing is a builtin possibility to create
complex numbers in polar coordinates

so first I wrote a standalone function

>>> def polar(r,arg):

.... re, im = r*cos(arg), r*sin(arg)
.... return re + im*1j

then I tried to extend this to a class

>>> from math import *

>>> class Complex(complex):

.... def __init__(self,x,y,polar=False):
.... if not polar:
.... self.re, self.im = x,y
.... else:
.... self.re, self.im = x*cos(y), x*sin(y)
....
>>>
>>> c=Complex(1,1)
>>> c

(1+1j)
>>> p=Complex(10,45.0/360*2*pi,True)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: complex() takes at most 2 arguments (3 given)
>>>

and got stuck with this error
it seems that last argument is rejected
because complex wants to have 2 arguments
but this works well ..

>>> class X(object):

.... def __init__(self,a):
.... self.a = a
....
>>> class Y(X):

.... def __init__(self,a,b):
.... self.a = a
.... self.b = b
....
>>> y=Y(1,2)

what's causing the above exception?

one more question

>>> class Complex(complex):

.... def __init__(self,x,y):
.... self.real = x
.... self.imag = y
....
>>> c=Complex(1,1)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __init__
>>>

how can I work around this problem?

Regards, Daniel

=?ISO-8859-1?Q?Sch=FCle_Daniel?=, Mar 7, 2006

2. ### =?ISO-8859-1?Q?Sch=FCle_Daniel?=Guest

what do you think of this design?

>>> def polar(x,y=None):

.... if type(x) in (list,tuple) and len(x) == 2 and y is None:
.... return complex(x[0]*cos(x[1]), x[0]*sin(x[1]))
.... if type(x) is complex and y is None:
.... return (abs(x), atan2(x.imag,x.real))
.... if type(x) in (float, int, long) and type(y) in (float, int, long):
.... return complex(x*cos(y), x*sin(y))
....
>>> polar(2**0.5, 45.0/360*2*pi)

(1.0000000000000002+1j)
>>> polar((2**0.5, 45.0/360*2*pi))

(1.0000000000000002+1j)
>>> polar([2**0.5, 45.0/360*2*pi])

(1.0000000000000002+1j)
>>> polar(1+1j)

(1.4142135623730951, 0.78539816339744828)
>>>

btw I like how Ruby handles the creation of complex numbers

c = Complex(1,1)
p = Complex.polar(1,45.0/360*2*PI)

Regards, Daniel

=?ISO-8859-1?Q?Sch=FCle_Daniel?=, Mar 8, 2006

3. ### Scott David DanielsGuest

Schüle Daniel wrote:
> I am trying to customize the handling of complex numbers
> what I am missing is a builtin possibility to create
> complex numbers in polar coordinates.... I wrote...:
> >>> def polar(r,arg):

> ... re, im = r*cos(arg), r*sin(arg)
> ... return re + im*1j
> then I tried to extend this to a class
> >>> class Complex(complex):

> ... def __init__(self,x,y,polar=False):
> ... if not polar:
> ... self.re, self.im = x,y
> ... else:
> ... self.re, self.im = x*cos(y), x*sin(y)

What you are missing is that complex is an immutable type.
You need to fiddle with __new__, not __init__.

class Complex(complex):
def __new__(class_, x, y=0.0, polar=False):
if polar:
return complex.__new__(class_, x * cos(y), x * sin(y))
else:
return complex.__new__(class_, x, y)

Which will produce instances of Complex, or:

class Complex(complex):
def __new__(class_, x, y=0.0, polar=False):
if polar:
return complex(x * cos(y), x * sin(y))
else:
return complex(class_, x, y)

Which will produce instances of complex.

--Scott David Daniels

Scott David Daniels, Mar 8, 2006
4. ### Scott David DanielsGuest

Scott David Daniels wrote:
> Schüle Daniel wrote:
>> ...

And, of course, I reply with a cutto-pasto (pre-success code).
> ...
> Which will produce instances of Complex, or:
> class Complex(complex):
> def __new__(class_, x, y=0.0, polar=False):
> if polar:
> return complex(x * cos(y), x * sin(y))
> else:
> return complex(class_, x, y)

This last line should, of course, be:
return complex(x, y)

--Scott David Daniels

Scott David Daniels, Mar 8, 2006
5. ### Scott David DanielsGuest

Schüle Daniel wrote:
....
> btw I like how Ruby handles the creation of complex numbers
>
> c = Complex(1,1)
> p = Complex.polar(1,45.0/360*2*PI)

class Complex(complex):
@classmethod

--Scott David Daniels

Scott David Daniels, Mar 8, 2006
6. ### =?ISO-8859-1?Q?Sch=FCle_Daniel?=Guest

thank you
I will have to take a closer look on __new__

Regards, Daniel

=?ISO-8859-1?Q?Sch=FCle_Daniel?=, Mar 8, 2006
7. ### Guest

, Mar 8, 2006
8. ### Guest

, Mar 8, 2006