Python - использование __init__ с унаследованным методом для класса полиномов
Это класс, который будет принимать в качестве входных данных, а затем выводить полином в строковой форме (оба способа одинакового формата). Некоторая арифметика выполняется различными способами. Я пытался унаследовать этот класс в другой класс, который затем будет использовать специальный метод __mod__() первого класса (или создать его собственный специальный метод, если это необходимо, но я не вижу, как вы не можете просто использовать оригинал метод) выполнить мод на приеме. Похоже, что это входит в __init__(), но я пробовал 5 разных версий этого, даже заходя так далеко, чтобы сменить родительский класс, и я ничего не получаю. Я учу себя Python, так что я уверен, что даже младший разработчик Python может видеть, где я иду совершенно неправильно.
import re
class GF2Polynomial(object): #classes should generally inherit from object
def __init__(self, string):
'''__init__ is a standard special method used to initialize objects.
Here __init__ will initialize a gf2infix object based on a string.'''
self.string = string #basically the initial string (polynomial)
self.key,self.lst = self.parsePolyVariable(string) # key determines polynomial compatibility
self.bin = self.prepBinary(string) #main value used in operations
def id(self,lst):
"""returns modulus 2 (1,0,0,1,1,....) for input lists"""
return [int(lst[i])%2 for i in range(len(lst))]
def listToInt(self,lst):
"""converts list to integer for later use"""
result = self.id(lst)
return int(''.join(map(str,result)))
def parsePolyToListInput(self,poly):
"""
replaced by parsePolyVariable. still functional but not needed.
performs regex on raw string and converts to list
"""
c = [int(i.group(0)) for i in re.finditer(r'\d+', poly)]
return [1 if x in c else 0 for x in xrange(max(c), -1, -1)]
def parsePolyVariable(self,poly):
"""
performs regex on raw string, converts to list.
also determines key (main variable used) in each polynomial on intake
"""
c = [int(m.group(0)) for m in re.finditer(r'\d+', poly)] #re.finditer returns an iterator
letter = [str(m.group(0)) for m in re.finditer(r'[a-z]', poly)]
m = max(c); varmatch = True; key = letter[0]
for i in range(len(letter)):
if letter[i] != key: varmatch = False
else: varmatch = True
if varmatch == False: return "error: not all variables in %s are the same"%a
d = [1 if x in c else (1 if x==0 else (1 if x=='x' else 0)) for x in xrange(m, -1, -1)]
return key,d
def polyVariableCheck(self,other):
return self.key == other.key
def prepBinary(self,poly):
"""converts to base 2; bina,binb are binary values like 110100101100....."""
x = self.lst; a = self.listToInt(x)
return int(str(a),2)
def __mod__(self,other):
"""
__mod__ is the special method for overriding the % operator
returns remainder formatted as polynomial
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.bin == other.bin: return 0
return GF2Polynomial(self.outFormat(self.bin%other.bin))
def __str__(self):
return self.string
def outFormat(self,raw):
"""process resulting values into polynomial format"""
raw = "{0:b}".format(raw); raw = str(raw[::-1]); g = [] #reverse binary string for enumeration
g = [i for i,c in enumerate(raw) if c == '1']
processed = "x**"+" + x**".join(map(str, g[::-1]))
proc1 = processed.replace("x**1","x"); proc2 = proc1.replace("x**0","1")
if len(g) == 0: return 0 #return 0 if list empty
return proc2 #returns result in gf(2) polynomial form
Желаемый результат - иметь возможность вызывать его в новом (дочернем) классе с родительским типом и при минимальном изменении родительского класса (если вообще вообще). Обратите внимание, что класс "BinaryField" является предполагаемым дочерним классом:
p=GF2Polynomial("x**2+x**1+x**0")
a=BinaryField("x**1+x**0", p)
b=BinaryField("x**1", p)
При приеме данный полином должен быть модулем, деленным на 2-й элемент (здесь это 'p'). Это необходимо для математики конечных полей.
РЕДАКТИРОВАТЬ: при запуске с -
## "x**1 + x**0" polynomial string style input
poly1 = "x**14 + x**1 + x**0"; poly2 = "x**6 + x**2 + x**1"; poly3 = "y**6 + y**2 + y**1"
a = GF2Polynomial(poly1); b = GF2Polynomial(poly2); c = GF2Polynomial(poly3)
## "x+1" polynomial string style input
poly4 = "x**14 + x + 1"; poly5 = "x**6 + x**2 + x"; poly6 = "y**6 + y**2 + 1"
d = GF2Polynomial(poly4); e = GF2Polynomial(poly5); f = GF2Polynomial(poly6)
bf1 = BinaryField(poly1,b); print bf1
bf2 = BinaryField(poly4,e); print bf2
Оба эти стиля возможны из-за того, как я их кодировал, но они оба должны возвращать один и тот же ответ. Однако результат в этом коде:
>>>
x**5 + x**4 + x**3 + 1
x**5 + x
Кроме того, при использовании BinaryField(poly4,d), который является той же самой строкой с его инициализацией GF2Polynomial(), эта ошибка как:AttributeError: 'int' object has no attribute 'string'
1 ответ
Решает ли это вашу проблему?
class BinaryField(GF2Polynomial):
def __init__(self, string, mod):
modded = GF2Polynomial(string) % mod
super(BinaryField, self).__init__(modded.string)
>>> p = GF2Polynomial("x**2+x**1+x**0")
>>> a = BinaryField("x**1+x**0", p)
>>> print a
x + 1
Вы также можете сделать BinaryField
класс, чтобы быть просто фабричным методом:
def BinaryField(string, mod):
return GF2Polynomial(string) % mod