I am trying to create a Python class that does operations mod n. For example using mod 100:
11*11==21
66+39==5
1+2+3-30==73
2**10==24
This is how I am doing it:
class ModInteger:
def __init__(self, value, mod):
self.mod = mod
self.value = value % mod
def __add__(self, other):
return ModInteger((self.value + other.value) % self.mod, self.mod)
def __sub__(self, other):
return ModInteger((self.value - other.value) % self.mod, self.mod)
def __mul__(self, other):
return ModInteger((self.value * other.value) % self.mod, self.mod)
def __pow__(self, other):
return ModInteger((self.value ** other.value) % self.mod, self.mod)
#...
It works, but is there a less tedious and repetitive way of doing it?
I am trying to create a Python class that does operations mod n. For example using mod 100:
11*11==21
66+39==5
1+2+3-30==73
2**10==24
This is how I am doing it:
class ModInteger:
def __init__(self, value, mod):
self.mod = mod
self.value = value % mod
def __add__(self, other):
return ModInteger((self.value + other.value) % self.mod, self.mod)
def __sub__(self, other):
return ModInteger((self.value - other.value) % self.mod, self.mod)
def __mul__(self, other):
return ModInteger((self.value * other.value) % self.mod, self.mod)
def __pow__(self, other):
return ModInteger((self.value ** other.value) % self.mod, self.mod)
#...
It works, but is there a less tedious and repetitive way of doing it?
Share Improve this question edited Mar 21 at 12:35 Username260138 asked Mar 20 at 16:02 Username260138Username260138 235 bronze badges 02 Answers
Reset to default 1A more generic approach would be to build ModInteger
with a metaclass that creates wrapper methods around relevant int
methods.
To allow compatibility with both int
and ModInteger
objects the wrapper methods should convert arguments of ModInteger
objects into int
objects before passing them to int
methods, and convert returning values back to ModInteger
objects if they are int
.
The demo below shows how wrapper methods work for both unary and binary operations, as well as methods such as __repr__
, which doesn't take an argument and doesn't return an int
object:
class ModIntegerMeta(type):
def __new__(metacls, name, bases, members):
cls = super().__new__(metacls, name, bases, members)
for name in '__add__', '__sub__', '__mul__', '__neg__', '__repr__':
setattr(cls, name, cls.create_method(name))
return cls
def create_method(cls, name):
def method(self, *args):
value = getattr(self.value, name)(*(
arg.value if isinstance(arg, cls) else arg for arg in args
))
if type(value) is int:
return cls(value, self.mod)
return value
return method
class ModInteger(metaclass=ModIntegerMeta):
def __init__(self, value, mod):
self.mod = mod
self.value = value % mod
print((-ModInteger(66, 100) + ModInteger(39, 100) * 5))
This outputs 29 because (-66 + (39 * 5) % 100) % 100 == 29
Demo: https://ideone/m5upVv
you can do something like this, where you inherit existing int class and modify the behaviour which you want and return thing as it .
class ModInteger(int):
def __init__(self, value, mod=100):
self._value = value
self.mod = mod
def __add__(self, value):
return super().__add__(value) % self.mod
def __sub__(self, value):
return super().__sub__(value) % self.mod
def __mul__(self, value):
return super().__mul__(value) % self.mod
def __pow__(self, value):
return super().__pow__(value) % self.mod
x = ModInteger(122)
y = ModInteger(333)
print((x + y) == (122 + 333) % 100) # True
print((x - y) == (122 - 333) % 100) # True
print((x * y) == (122 * 333) % 100) # True
print((x ** y) == (122 ** 333) % 100) # True
print((x + 22) == (122 + 22) % 100) # True
print((x - 22) == (122 - 22) % 100) # True
print((x * 22) == (122 * 22) % 100) # True
print((x ** 22) == (122 ** 22) % 100) # True
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744397336a4572209.html
评论列表(0条)