# Jared Wasserman
# 5/19/2013
# Python translation of Chris Poon's
# Java Complex Numbers Class (converted from Arup's C++ example)

from math import sqrt

class Complex:
    # real holds real part
    # img holds imaginary part

    def __init__(self, x=0.0, y=0.0):
        # Constructor that sets the real and img components to the two parameters x
        # and y respectively.
        self.real = x
        self.img = y

    @staticmethod
    def create_copy(copy):
        # Copy Constructor copies each component of the Complex object.
        return Complex(copy.real, copy.img)

    def conj(self):
        # Returns the complex conjugate of the current object.
        return Complex(self.real, -1.0 * self.img)

    def absVal(self):
        # Returns the magnitute of the current object.
        return sqrt(self.real * self.real + self.img * self.img)

    def __str__(self):
        # Converts the object to a readable String (for output)
        if (self.img <= 0):
            return (str(self.real) + (str(self.img) + "i"))
        else:
            return (str(self.real) + "+" + str(self.img) + "i")

    def multfactor(self, f):
        # This methods takes in a real value f and multiplies the current object
        # by this factor.
        self.real *= f
        self.img *= f

    @staticmethod
    def add_static(num1, num2):
        # This methods takes in two Complex objects and returns a third
        # Complex object containing their sum.
        return Complex(num1.real + num2.real, num1.img + num2.img)

    def add(self, num2):
        return Complex(self.real + num2.real, self.img + num2.img)

    @staticmethod
    def mult_static(num1, num2):
        # This methods takes in two Complex objects and returns a third
        # Complex object containing their product.
        return Complex(num1.real * num2.real - num1.img * num2.img, num1.real * num2.img + num1.img * num2.real)

    def mult(self, num2):
        # This methods takes in two Complex objects and returns a third
        # Complex object containing their product.
        return Complex(self.real * num2.real - self.img * num2.img, self.real * num2.img + self.img * num2.real)

def main():
    # Create three Complex objects.
    m = Complex(3, 4)
    j = Complex(1, -2)
    n = Complex.create_copy(m.conj())

    # Print out information about each.
    print("m = " + str(m))
    print(" |m| = " + str(m.absVal()))
    print("")

    print("j = " + str(j))
    print(" |j| = " + str(j.absVal()))
    print("")

    print("n = " + str(n))
    print(" |n| = " + str(n.absVal()))
    print("")

    # Test static multiplication method.
    j = Complex.mult(m, j)
    print("j = " + str(j))
    print(" |j| = " + str(j.absVal()))
    print("")

    # Test instance multiplication method.
    j = j.mult(m)
    print("j = " + str(j))
    print(" |j| = " + str(j.absVal()))
    print("")

    n.multfactor(4)
    print("n = " + str(n))
    print(" |n| = " + str(n.absVal()))
    print("")
    
# runs main module on startup
if __name__ == "__main__":
    main()


''' Sample I/O:

C:\src\BHSCI\1>java Complex
m = Real: 3.0, Imaginary:4.0
 |m| = 5.0

j = Real: 1.0, Imaginary:-2.0
 |j| = 2.23606797749979

n = Real: 3.0, Imaginary:-4.0
 |n| = 5.0

j = Real: 11.0, Imaginary:-2.0
 |j| = 11.180339887498949

j = Real: 41.0, Imaginary:38.0
 |j| = 55.90169943749474

n = Real: 12.0, Imaginary:-16.0
 |n| = 20.0


'''
