여러 연산 작업이 함께 묶여있는 mix1 = bf2/bf4*bf1%bf5
에서와 같이 여러 작업을 동시에 호출 할 수 있도록 동일한 유형을 유지하기 위해 부모 클래스의 __div__()
을 사용하려고합니다. 웬일인지 __add__()
에 super()를 사용할 수 있지만 __div__()
에는 사용할 수 없습니다. 오류는 "IndexError : 목록 인덱스가 범위를 벗어났습니다."그리고 나는 아무런 진전없이이 일을 계속 반복하고 있습니다. 이것은 모두 유한 필드 내의 다항식 산술과 관련이 있습니다.파이썬 - 유한 필드의 다항식. 이 경우에 __add __() 만 super()를 사용하는 이유는 무엇입니까?
저는 parsePolyVariable()
을 포함하고 있습니다. (약간의 코드가있는 것처럼 보이면 죄송합니다. 그러나 좋은 원인과 빌드 문자를 모두 제공합니다.) 그 이유는 목록 오류가 원인 인 것으로 보입니다. 그러나 나는 모든 일이 매우 잘못되어 가고있는 상황을 이해할 수 없습니다. 나 자신에게 파이썬을 가르치기 때문에 다른 초보자들도 분명히 빠져있는 것을 볼 수있을 것이다.
http://docs.python.org/2/library/functions.html#super
Python super(Class, self).method vs super(Parent, self).method
How can I use Python's super() to update a parent value?
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)
#if self.parsePolyVariable(string) == "0": self.key,self.lst = "0",[0]
#else:
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
if sum(c) == 0: return "0",[0]
letter = [str(m.group(0)) for m in re.finditer(r'[a-z]', poly)]
degree = 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
lst = [1 if x in c else (1 if x==0 else (1 if x=='x' else 0)) for x in xrange(degree, -1, -1)]
return key,lst
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 __add__(self,other):
"""
__add__ is another special method, and is used to override the + operator. This will only
work for instances of gf2pim and its subclasses.
self,other are gf2infix instances; returns GF(2) polynomial in string format
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
return GF2Polynomial(self.outFormat(self.bin^other.bin))
def __sub__(self,other):
"""
__sub__ is the special method for overriding the - operator
same as addition in GF(2)
"""
return self.__add__(other)
def __mul__(self,other):
"""
__mul__ is the special method for overriding the * operator
returns product of 2 polynomials in gf2; self,other are values 10110011...
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
bitsa = reversed("{0:b}".format(self.bin))
g = [(other.bin<<i)*int(bit) for i,bit in enumerate(bitsa)]
return GF2Polynomial(self.outFormat(reduce(lambda x,y: x^y,g)))
def __div__(self,other):
"""
__div__ is the special method for overriding the/operator
returns quotient 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 1
return GF2Polynomial(self.outFormat(self.bin/other.bin))
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
class BinaryField(GF2Polynomial):
def __init__(self, poly, mod):
if mod == "0": self.string = "Error: modulus division by 0"
elif mod == "0": self.string = "%s is 0 so resulting mod is 0"%(poly)
fieldPoly = GF2Polynomial(poly) % mod
if fieldPoly == 0: self.string = "%s and %s are the same so resulting mod is 0"%(poly,mod)
else: super(BinaryField, self).__init__(fieldPoly.string)
#self.degree = len(str(fieldPoly))
def polyFieldCheck(self,other):
return self.degree() == other.degree()
def __add__(self, other):
"""
inherited from GF2Polynomial
"""
return super(BinaryField, self).__add__(other) % min(other,self)
def __sub__(self,other):
"""
inherited from GF2Polynomial
"""
return self.__add__(other)
def __mul__(self, other):
"""
special method of BinaryField, needed for format adjustments between classes
"""
#print "self = %s,%s other = %s,%s "%(self.degree(),type(self.degree()),other.degree(),type(other.degree()))
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.polyFieldCheck(other) == False:
return "error: fields of %s and %s do not match"%(self.string,other.string)
else: print "Operation will proceed: fields of %s and %s match"%(self.string,other.string)
bitsa = reversed("{0:b}".format(self.bin))
g = [(other.bin<<i)*int(bit) for i,bit in enumerate(bitsa)]
result = reduce(lambda x,y: x^y,g)%min(self.bin,other.bin)
return GF2Polynomial(self.outFormat(result))
def __div__(self, other):
"""
special method of BinaryField, needed for format adjustments between classes
"""
if self.polyVariableCheck(other) == False:
return "error: variables of %s and %s do not match"%(self.string,other.string)
if self.polyFieldCheck(other) == False:
return "error: fields of %s and %s do not match"%(self.string,other.string)
else: print "Operation will proceed: fields of %s and %s match"%(self.string,other.string)
if self.bin == other.bin: return 1
result = self.bin/other.bin
#return self.outFormat(result)
return super(BinaryField, self).__div__(other) #% min(other,self)
def degree(self):
return len(self.lst)-1
을 그리고 여기 main()
있어 :
if __name__ == '__main__':
## "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 = "x**8 + x**3 + 1"
d = GF2Polynomial(poly4); e = GF2Polynomial(poly5); f = GF2Polynomial(poly6)
poly7 = "x**9 + x**5 + 1"; poly8 = "x**11 + x**7 + x**4 + 1"; poly9 = "x**5 + x**4 + x**2 + x"
g = GF2Polynomial(poly7); h = GF2Polynomial(poly8); i = GF2Polynomial(poly9)
## g = GF2Polynomial("x**5 + x**4 + x**3 + 1"); h = GF2Polynomial("x**5 + x"); print "(g*h)%b = ",(g*h)%b
## dd = GF2Polynomial("x**0"); print "dd -- ",dd
## ee = GF2Polynomial("0"); print "ee -- ",ee
bf1 = BinaryField(poly1,b); print bf1; print "degree bf1 = ",bf1.degree()
bf2 = BinaryField(poly4,e); print "bf2 ",bf2; bf3 = BinaryField(poly4,d); print "bf3 ",bf3,type(bf3)
bf4 = BinaryField(poly4,h); bf5 = BinaryField(poly9,e); bf6 = BinaryField(poly8,i)
add1 = bf1+bf2
print "add1 ",add1
div1 = bf1/bf2
print "div1 ",div1,type(div1)
mix1 = bf2*bf1%bf5
print "mix1 ",mix1,type(mix1)
편집 : 전체 역 추적 -
Message File Name Line Position
Traceback
<module> C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 233
__div__ C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 197
__div__ C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 100
__init__ C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 20
parsePolyVariable C:\Users\win7pro-vm\Desktop\crypto\GF2BinaryField.py 48
IndexError: list index out of range
기준선 (48)의 경우는 degree = max(c); varmatch = True; key = letter[0]
입니다. 줄 번호를 조정하여 개인 메모와 정보를 삭제했습니다.
예외의 전체 * 추적은 무엇입니까? 예제 코드를 오류를 생성하는 코드로 줄일 수 있습니까? –
오류는'super'와 관련이 없으며 다항식의 내부 상태와 관련이 있습니다. 부모 메서드는 아마도 ...역 추적없이 나는 확실히 말할 수 없다) 제대로 호출했지만, 다른 이유로 실패했다. 당신은'__div__'의 구현이 올바른지 다시 한 번 확인해야합니다. (스타일 노트 :'== False'를 실제로 볼 수 없습니다.) 'not self.polyVariableCheck (other)'를 사용하면 실패했을 때'__div__' 메소드가 * 오류 * 문자열을 반환하는 이유를 이해할 수 없습니다. 예외 대신). – Bakuriu
전체 추적이 게시됩니다. 위에 게시 된 코드는 이미 주 범인 방법 및 부양 가족에게 상당히 축소되었습니다. '__mod__'은 클래스를 초기화하는 동안 필요하며'__mul__' (고칠 필요가 있음)은 리턴 타입을 다른 특별한 메소드와 비교하기 위해 존재합니다. 이 단일 문제를 아주 오랫동안 디버깅하면서 제공 할 수있는 도움을 주시면 감사하겠습니다. 기본적으로 부서 자체이므로'__div __() '에서 무엇을 확인할 것인지 확신 할 수 없습니다. 나는 부모로부터'__div __()'를 다시 쓰는 대신에 사용하고 싶습니다. 그래서'super()'를 사용하려고합니다. – stackuser