# -*- coding: utf-8 -*-

# #  Name:           complexe.py
# #  Modification:   CFV
##  Date: 	         février 2020
##  Description:     programme de modélisation de la classe complexe

from math import sqrt


class Complexe:
    """ modelise des nombres complexes """

    def __init__(self, preelle, pimaginaire):
        """

        :param preelle:     partie réelle du complexe (reel)
        :param pimaginaire: paertie imaginaire du complexe (reel)
        """
        self.pr_ = preelle
        self.pim_ = pimaginaire

    def __repr__(self):
        """

        Affichage (surcharge de print) du nombre
        complexe sous la forme x+yi .
        """

        if self.pim_ >= 0.:
            return str(self.pr_) + ' + ' + str(self.pim_) + ' i'
        else:
            return str(self.pr_) + ' - ' + str(-self.pim_) + ' i'

    def norme(self):
        """

        :return:    la norme d'un complexe
        """
        return sqrt(self.pr_ ** 2 + self.pim_ ** 2)

    def multiplie(self, facteur):
        """

        :param facteur: facteur de multiplication
        :return: modifie le complexe courant en le multipliant par facteur
        """
        self.pr_ *= facteur
        self.pim_ *= facteur

    def conjugue(self):
        """

        :return: le complexe conjugue du complexe courant
        """
        # on retourne un nouveau complexe
        return Complexe(self.pr_, -self.pim_)

    def inverse(self):
        """

        :return:    l'inverse du complexe, soit le complexe divisé par la norme
        """
        norm = self.norme()
        if not norm:
             # pour éviter des erreurs quand la norme est nulle on retourne None
            return None

        conj = self.conjugue()  # retourne le complexe conjugue
        conj.multiplie(1 / norm ** 2)       # modifie le complexe conj en le multipliant par 1/norm **2

        # on retourne le nouveau complexe conj modifié
        return conj

    def __add__(self, other):
        """

        :param other:   autre complexe
        :return:        la somme des deux complexes
        """
        return Complexe(self.pr_ + other.pr_, self.pim_ + other.pim_)

    def __eq__(self, other):
        """

        :param other:   autre complexe
        :return:        True si les parties réelles et imaginaires des deux complexes sont égales
        """
        # version concise
        # return self.pr_==other.pr_ and self.pim_==other.pim_

        if self.pr_==other.pr_ and self.pim_==other.pim_:
            return True

        return False

# main
if __name__ == "__main__":
    cpx = Complexe(3, 2)
    print(cpx)

    conj = cpx.conjugue()
    print(cpx)

    cpx.multiplie(4)
    print(cpx)

    cpx_som = cpx + conj
    print(cpx)

    cpx2 = Complexe(3, 2)
    print(cpx == cpx2)

    cpx_inverse = cpx.inverse()
    print(cpx)


