
import numbers


class Polynom:

    def __init__(self, dp, Alg):

        assert all(isinstance(k, int) and k >= 0 for k in dp.keys()), \
            "Die Exponenten (keys) müssen natürliche Zahlen (einschl. 0) sein."
        self.dp = dp
        self.Alg = Alg
        self.degree = max(dp.keys())

    def __str__(self):
        pstr = ''
        for k, v in self.dp.items():
            pstr = pstr + f'{v}*X^{k}'
        return f'{__class__.__name__} {pstr}'

    def __add__(self, other):
        return self.__class__(self.Alg.add(self, other), self.Alg)


class PolyGruppe:

    def __init__(self, ring_str):
        self.ring_str = ring_str
        if ring_str == 'C':
            self.ring = numbers.Complex  # komplexe Zahlen
        elif ring_str == 'R':
            self.ring = numbers.Real  # reelle Zahlen
        elif ring_str == 'Z':  # ganze Zahlen
            self.ring = numbers.Integral
        else:
            raise ValueError(
                f"{ring_str} nicht erlaubt 'Ring' muss 'C' or 'R' or 'Z' sein")

    def __repr__(self):
        return f" ({self.ring_str}[X],+) "

    def __eq__(self, other):
        return self.ring == other.ring

    def add(self, p, q):
        erg = {n: p.dp.get(n, 0) + q.dp.get(n, 0)
               for n in p.dp.keys() | q.dp.keys()}
        return erg

if __name__ == '__main__':

    CXg = PolyGruppe('C')

    print(CXg.__class__.__name__, CXg)

    try:
        print('\nFehlermeldung')
        CXg = PolyGruppe('N')
    except BaseException as e:
        print(e,'\n')

    p = Polynom({0: -1, 99: 1}, CXg)
    q = Polynom({0: 2, 2: 1}, CXg)
    print(p)
    print(f'Summe p+q {p+q}')

    # try:
    #     ZXg = PolyGruppe('Z')
    #     pg = ZXg({0: 1j, 1: 1})
    #     print(f' p {pg}')
    # except BaseException as e:
    #     print(f'{e}')

    # print(f'Subtraktion p-q {pg-qg}')
    # print(f'Inverses von {pg} : {-pg}')
    # try:
    #     print(f'Produkt p*q {pg*qg}')
    # except BaseException as e:
    #     print(
    #         f'{e} \np*q ist daher in der {CXg.__class__.__name__} nicht definiert')
