import math

# Klassen Complex representerar komplexa tal med rektangulära koordinater
class Complex (object):
    def __init__ (self, re, im):
        self.re = re
        self.im = im

# Dålig implementation av beräkning av impedance via Ohms lag Z = U / I
def impedance (u, i):
    # Dålig, oöverskådlig kod!
    #
    # * Dåliga variabelnamn
    #
    # * Idéer på olika nivåer (Ohms lag, division av komplexa tal,
    #   representation av komplexa tal) blandas
    #
    um = math.sqrt (u.re * u.re + u.im * u.im)
    im = math.sqrt (i.re * i.re + i.im * i.im) # kodupprepning
    ua = math.atan (u.im / u.re)
    ia = math.atan (i.im / i.re)               # kodupprepning
    return Complex (um / im * math.cos (ua - ia),
                    um / im * math.sin (ua - ia)) # kodupprepning + extra arbete

# Bättre:

# impedance (u, i) beräknar impedansen som funktion av växelspänning och växelström
#
# Parametrar:
# u: växelspänning (komplext tal)
# i: växelström (komplext tal)
#
# Returnerar impedansen (komplext tal)
#
def impedance (u, i):
    return div (u, i) # Ohms lag

# Komplex division
#
# Parametrar:
# x: täljare (komplext tal)
# y: nämnare (komplext tal)
#
# Returnerar kvoten x / y (komplext tal)
#
def div (x, y):
    return polarToRect (magnitude (x) / magnitude (y), argument (x) - argument (y))

# Följande funktioner hanterar representationen av komplexa tal

# Komplex magnitud
#
# c: Komplext tal
#
# Returnerar den komplexa magnituden |c|
#
def magnitude (c):
    return math.sqrt (c.re * c.re + c.im * c.im)

# Argument
#
# c: Komplext tal
#
# Returnerar arg (c)
#
def argument (c):
    return math.atan (c.im / c.re)

# Omvandling från polär till rektangulär representation
#
# magnitude: Komplex magnitud
# argument: Komplex fas (argumentet hos ett komplext tal)
#
# Returnerar motsvarande komplexa tal som objekt av typen Complex
#
def polarToRect (magnitude, argument):
    return Complex (magnitude * math.cos (argument),
                    magnitude * math.sin (argument))
