#!/usr/bin/env python3
"""
 murd.py - t2isarvulise lugeja ja nimetajaga murd
"""


class Murd(object):
    
    __lugeja = 0
    __nimetaja = 1

    @staticmethod
    def suurim_yhistegur(a, b):
        m = int(max(abs(a), abs(b)))
        n = int(min(abs(a), abs(b)))
        if n == 0:
            raise ArithmeticError("Nullist ei saa leida suurimat yhistegurit")
        while n > 0:
            uus = m % n
            m = n
            n = uus
        return m

    def __init__(self, lugeja, nimetaja):
        lug = int(lugeja)
        nim = int(nimetaja)
        if nim == 0:
            raise ZeroDivisionError("Murru nimetaja ei saa olla null")
        if lug == 0:
            nim = 1
        else:
            syt = Murd.suurim_yhistegur(lug, nim)
            lug = lug // syt
            nim = nim // syt
        if nim < 0:
            lug = -lug
            nim = -nim
        self.__lugeja = lug
        self.__nimetaja = nim

    def lugeja(self):
        return self.__lugeja

    def nimetaja(self):
        return self.__nimetaja

    def real_value(self):
        return self.lugeja()/self.nimetaja()

    def __str__(self):
        return str(self.lugeja()) + "/" + str(self.nimetaja())

    def __repr__(self):
        return "Murd(" + str(self.lugeja()) + ", " + str(self.nimetaja()) + ")"

    def __eq__(self, other):
        # return self.real_value() == other.real_value()
        return self.lugeja()*other.nimetaja() == self.nimetaja()*other.lugeja()

    def __gt__(self, other):
        return self.lugeja()*other.nimetaja() > self.nimetaja()*other.lugeja()

    def __ge__(self, other):
        return self.__gt__(other) or self.__eq__(other)

    def __bool__(self):
        return self.lugeja() != 0

    def __hash__(self):
        return hash(str(self))

    def plus(self, other):
        return Murd(self.lugeja()*other.nimetaja() +
                    self.nimetaja()*other.lugeja(),
                    self.nimetaja()*other.nimetaja())

    def opposite(self):
        return Murd(-self.lugeja(), self.nimetaja())

    def inverse(self):
        return Murd(self.nimetaja(), self.lugeja())

    def minus(self, other):
        return self.plus(other.opposite())

    def times(self, other):
        return Murd(self.lugeja()*other.lugeja(),
                    self.nimetaja()*other.nimetaja())

    def divide_by(self, other):
        return self.times(other.inverse())

    @staticmethod
    def parse_murd(tekst):
        lug, nim = tekst.split("/")
        return Murd(lug, nim)


def main():
    """
    Main method.
    """
    m1 = Murd(2, 7)
    print(m1.real_value())
    print(m1.plus(m1))
    print(m1.__repr__())
    m2 = Murd.parse_murd("1/-3 ")
    print(m2)
    print(Murd(223372036854775806, 223372036854775807).real_value())


if __name__ == '__main__':
    main()
