-2

I am currently trying to write a program that deals with complex numbers. I have to use classes and methods. I am trying to be able to add, subtract, multiply etc., complex numbers, as well as compare them to one another. I think I have gotten a good start but have some issues.

I have started each method, and I think I just need to fill in the gaps. In the method, I used self.x as a placeholder. I'm not really sure what goes there. First off, the program needs to create it's own complex numbers. I'm new to making methods and functions and I'm not sure if I used (self) in the correct places.

I'm pretty sure I have some syntax issues, i.e. It keeps saying that the variable "i" is not defined, when I clearly have it defined in multiple places.

Once all this is sorted out, I need to create a test function that actually uses the code.

Any help would be appreciated. Thanks!

My code so far:

import math
i = math.sqrt(-1) 

class Complex(object):

    def __init__(Complex, a, b):
        '''Creates Complex Number'''
        a = 0
        b = 0
        return(Complex, a, b) 


    def __str__(Complex, a, b):
        '''Returns complex number as a string'''
        a = 0
        b = 0
        return str(a, b) 

    def __add__(self):
        '''Adds complex numbers'''
        i = math.sqrt(-1) 
        self.x = (a + bi) + (c + di) = (a + c) + (b + d)i

    def __sub__(self):
        '''Subtracts complex numbers'''
        self.x = (a + bi) - (c + di) = (a - c) + (b - d)i

    def __mul__(self):
        '''Multiplies complex numbers'''
        self.x =  (a + bi) * (c + di) = (ac - bd) + (bc + ad)i

    def __div__(self):
        '''Divides complex numbers'''
        self.x =  (a + bi) / (c + di) = (ac + bd)/(c**2 + d**2) + (bc - ad)i/(c**2 + d**2)

    def __abs__(self):
        '''Determines absolute value of complex numbers'''
        self.x = math.sqrt(a**2 + b**2)
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
xrocker15
  • 51
  • 2
  • 2
  • 6
  • 2
    Just to make sure, the built in support for complex numbers either did not meet your needs or you are not allowed to use in this context? – vossad01 Sep 19 '12 at 00:16
  • You should check out the built-in type `complex`: http://docs.python.org/library/stdtypes.html#numeric-types-int-float-long-complex – K. Brafford Sep 19 '12 at 00:17
  • 1
    Also, in Python, `bi` doesn't mean `b` times `i`, it means an entirely unrelated variable `bi`. – abarnert Sep 19 '12 at 00:19
  • And: math.sqrt(-1) will raise a ValueError. And if you think about it, the only way it could possibly work is if math already completely supported complex numbers. Of course the built-in native complex support can do this for you: `(-1+0j)**.5` will return `1j` or something within reasonable rounding error thereof. – abarnert Sep 19 '12 at 00:23
  • I am trying to create me "own" complex function, not the built in one – xrocker15 Sep 19 '12 at 00:25
  • Then you can't rely on built-in or math-library functions to do the heavy lifting, can you? Anyway, _why_ are you trying to create your own complex functions? – abarnert Sep 19 '12 at 00:26
  • how can I change math.sqrt(-1) to represent and imaginary number? – xrocker15 Sep 19 '12 at 00:28
  • If you're defining your own `Complex` class, you can represent `i` any way you want. But you can't use `math.sqrt(-1)` to do it for you. – abarnert Sep 19 '12 at 00:29
  • I'm taking a Python Programming class and this was an old lab assignment I could never figure out. I really want to grasp this information before it gets really difficult... – xrocker15 Sep 19 '12 at 00:29

1 Answers1

3

Here's a simple implementation of just a subset of what you're trying to do:

import math

class Complex(object):

    def __init__(self, a, b):
        '''Creates Complex Number'''
        self.a = a
        self.b = b

    def __str__(self):
        '''Returns complex number as a string'''
        return '(%s, %s)' % (self.a, self.b) 

    def __add__(self, rhs):
        '''Adds complex numbers'''
        return Complex(self.a + rhs.a, self.b + rhs.b)

i = Complex(0, 1)

To break down the __add__ method a bit more for exposition:

    def __add__(self, rhs):
        '''Adds complex numbers'''
        new_a = self.a + rhs.a
        new_b = self.b + rhs.b
        return Complex(new_a, new_b)

Or, relating it more directly to your original:

    def __add__(self, rhs):
        '''Adds complex numbers'''
        a = self.a
        b = self.b
        c = rhs.a
        d = rhs.b
        new_real_part = a + c
        new_imag_part = b + d
        return Complex(new_real_part, new_imag_part)

This might all be simpler if you avoided calling your member variables a and b, which are pretty generic and meaningless, and can cause confusion when you're dealing with algorithms where the real and imaginary parts of an object might be referred to as a and b, or c and d, or various other things.

Can you figure out the rest from here?

Note that the only place you should need math is inside __abs__.

For a rundown of some of the things you got wrong in the original:

  • You defined your global variable i in terms of math.sqrt(-1), which raises an exception. And the only way this could possibly work would be to return a native complex number—since the whole point of what you're trying to do is create your own complex class instead of using the native support, this would be pointless. Instead, you want to define i as an instance of your class.
  • All instance methods—including __init__—should take self as the first parameter.
  • The only way to access instance variables—including setting them in __init__—is via the self parameter. a = 0 just creates a new local variable that goes away as soon as the function is over; self.a = 0 modifies the a member of the object.
  • The __str__ method doesn't take any extra parameters.
  • The __add__ method shouldn't be changing the object in-place, but returning a new one. If you want to change the object in-place, that's __iadd__. (It's pretty common to define __add__ in terms of __iadd__, as you might guess.) And the same is true for the next three methods.
  • The __add__ method has to take another parameter to operate on. Otherwise, what are you adding self to? And again, ditto for the next few methods.
  • You don't have an x member, so why are you setting one in __add__? (Of course this is legal, and will create a new one, but you're never going to use it anywhere.)
  • Your algorithms seem to be trying to create a native complex value. If you want to get a Complex whose real part is the sum of the real parts of self and rhs and whose imaginary part is the sum of the imaginary parts, you have to construct a Complex out of those two sums. (You don't have any way to construct a Complex out of a single combined value.)
  • What did you expect self.x = … = … to do? For example, are you really trying to assign the value of (a + c) + (b + d)i to the expression (a + bi) + (c + di)?
  • Juxtaposition doesn't mean multiplication in Python, or most other programming languages. So bi is an entirely separate variable, not b times i, and (b + d)i is a syntax error.
abarnert
  • 354,177
  • 51
  • 601
  • 671
  • Thanks for the start! What does the "rhs" mean? I haven't seen that before. In regards to the def__add__, do I just need to do the same thing for sub, mul, etc? – xrocker15 Sep 19 '12 at 00:36
  • `rhs` is an abbreviation for "right hand side". Everyone has their own favorite naming convention for what to call the other argument in binary numeric methods; this is one of the popular ones, although probably not the most popular. (In this convention, you also use `lhs` for reversed operations like `__radd__`.) – abarnert Sep 19 '12 at 00:42
  • One thing to think about: What happens if I construct a `Complex` object out of two `Complex` objects (`c = Complex(Complex(1, 1), Complex(2, 2))`), or two native complex objects (`c = Complex(1+1j, 2+2j)`)? Is all of your code going to do the right thing? (Is there even a right thing to do?) – abarnert Sep 19 '12 at 00:47
  • 1
    In the add function "return Complex(self.a + rhs.a, self.b + rhs.b) " Im not sure what it is exactly doing? It is supposed to take two complex numbers in (a + bi) form, and add them. As well as the same for mul, div, etc. I realize there are many mistakes thats why I came here for help – xrocker15 Sep 19 '12 at 00:56
  • Well, a mathematical complex number in `(a+bi)` is represented in your code as a `Complex` object `Complex(a, b)`. Both `self` and `rhs` are objects of that type. So, `self.a` and `rhs.a` are the real parts of the left and right numbers, and `self.b` and `rhs.b` are the imaginary parts of the left and right numbers. The mathematical answer is `((self.a + rhs.a) + (self.b + rhs.b)i)`, and that's represented as `Complex(self.a + rhs.a, self.b + rhs.b)`. So, that's what `__add__` should return. – abarnert Sep 19 '12 at 00:59
  • So "__sub__" should return (self.a - rhs.a, self.b - rhs.b)? and Mul should be same except with a *? – xrocker15 Sep 19 '12 at 01:06
  • Yes for `__sub__`, but not for `__mul__`, because that's not the algorithm for complex multiplication. The real part of `x` times `y` isn't the real part of `x` times the real part of `y`, it's that minus the imaginary part of `x` times the imaginary part of `y`. You wrote the algorithm (in mathematical form) in your initial post; you just need to convert that to using `rhs.b` instead of `d`, etc. – abarnert Sep 19 '12 at 01:11