PythonでModintをつくったよ

## コード
```Python
"""Modint

・つかい方
mint = Modint(998244353)
value = mint(10)
"""


class Modint():
    def __init__(self, mod: int):
        self.mod: int = mod

    def __call__(self, num: int):
        return NumberMint(num, self.mod)


class NumberMint():
    def __init__(self, num: int, mod: int):
        self.num: int = num
        self.mod: int = mod
        if self.num < 0 or self.mod <= self.num:
            self.num %= self.mod
        self.__inverse = None  # 逆数

    def __int__(self) -> int:
        return self.num

    def __str__(self) -> str:
        return str(self.num)

    def __repr__(self) -> str:
        return "Modint({})".format(self.num)

    def __add__(self, other):
        if isinstance(other, NumberMint):
            new_value = self.num + other.num
        else:
            new_value = self.num + other
        if self.mod <= new_value:
            new_value -= self.mod
        return NumberMint(new_value, self.mod)

    def __sub__(self, other):
        if isinstance(other, NumberMint):
            new_value = self.num - other.num
        else:
            new_value = self.num - other
        if new_value < 0:
            new_value += self.mod
        return NumberMint(new_value, self.mod)

    def __mul__(self, other):
        if isinstance(other, NumberMint):
            new_value = self.num * other.num % self.mod
        else:
            new_value = other % self.mod * self.num % self.mod
        return NumberMint(new_value, self.mod)

    def __truediv__(self, other):
        if isinstance(other, NumberMint):
            new_value = self.num * other.inverse % self.mod
        else:
            other_inverse = pow(other, self.mod - 2, self.mod)
            new_value = self.num * other_inverse % self.mod
        return NumberMint(new_value, self.mod)

    def __floordiv__(self, other):
        return self / other

    def __pow__(self, power):
        return pow(self.num, power, self.mod)

    def __iadd__(self, other):
        return self + other

    def __isub__(self, other):
        return self - other

    def __imul__(self, other):
        return self * other

    def __itruediv__(self, other):
        return self / other

    def __ifloordiv__(self, other):
        return self / other

    def __radd__(self, other):
        return self + other

    def __rsub__(self, other):
        return NumberMint(other, self.mod) - self

    def __rmul__(self, other):
        return self * other

    def __rtruediv__(self, other):
        return NumberMint(other, self.mod) / self

    def __rfloordiv__(self, other):
        return NumberMint(other, self.mod) / self

    def __eq__(self, other) -> bool:
        if isinstance(other, NumberMint):
            return self.num == other.num
        return self.num == other % self.mod

    def __ne__(self, other) -> bool:
        if isinstance(other, NumberMint):
            return self.num != other.num
        return self.num != other % self.mod

    def __inverse_generator(self):
        return pow(self.num, self.mod - 2, self.mod)

    @property
    def inverse(self) -> int:
        if self.__inverse is None:
            self.__inverse = self.__inverse_generator()
        return self.__inverse
```

## つかい方

### インスタンス作成
```Python
mint = Modint(998244353)  # MODをセットする。
x = mint(15)  # これ以降は、xを使った演算はすべて998244353を法にしてくれる。
```

### できる演算の一覧
```Python
mint = Modint(998244353)
x = mint(10)
y = mint(7)

print(x + y)  # 17
print(x - y)  # 3
print(x * y)  # 70
print(x / y)  # 570425346
print(x // y)  # 570425346
print(y ** 5)  # 16807
print(x == y)  # False
print(x != y)  # True

# こういうタイプのもできます！
x += y
x -= y
x *= y
x /= y
x //= y

# 片方だけでもModintだったら、演算結果もModintになります！
print(x + 5)  # 15
print(22 + y)  # 29

# 逆数
print(x.inverse)  # 99824436
```

## コメント
わざわざ % mod を書く手間がはぶけます！
割り算(分数)が直感的に書けます！
mod $998244353$ や mod $10^9+7$ が問題で出てきたら、とりあえずこれを使っておけばmodのことを気にせずに問題に集中できます。
気に入ったら、ぜひつかってみてね。

## こだわりポイント (オタク向け)
逆数に関しては、実はクラスの中ではself.__inverse という変数にして外部アクセスができないようにしていて、初期値はNoneにしてあります。
inverseメソッドを使うと、もしself.__inverse がNoneのときは下のようにself.__inverseをちゃんと計算します。Noneでなければ、その値をそのまま返します。
```Python
self.__inverse = pow(self.num, self.mod - 2, self.mod)
```

.inverse() と書くとメソッドの雰囲気が出ちゃうので、propertyデコレータを使うことで変数を扱っている感じにしました。
```Python
@property
def inverse(self) -> int:
    if self.__inverse is None:
        self.__inverse = self.__inverse_generator()
    return self.__inverse
```

問題によってはたくさん逆数が呼び出されることがあって、その度に逆数を計算してたらTLEしちゃうこともあるので、逆数をクラス内の変数に持っておく工夫をしました。