2013-08-13 4 views
0

여러 연산 작업이 함께 묶여있는 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]입니다. 줄 번호를 조정하여 개인 메모와 정보를 삭제했습니다.

+4

예외의 전체 * 추적은 무엇입니까? 예제 코드를 오류를 생성하는 코드로 줄일 수 있습니까? –

+1

오류는'super'와 관련이 없으며 다항식의 내부 상태와 관련이 있습니다. 부모 메서드는 아마도 ...역 추적없이 나는 확실히 말할 수 없다) 제대로 호출했지만, 다른 이유로 실패했다. 당신은'__div__'의 구현이 올바른지 다시 한 번 확인해야합니다. (스타일 노트 :'== False'를 실제로 볼 수 없습니다.) 'not self.polyVariableCheck (other)'를 사용하면 실패했을 때'__div__' 메소드가 * 오류 * 문자열을 반환하는 이유를 이해할 수 없습니다. 예외 대신). – Bakuriu

+0

전체 추적이 게시됩니다. 위에 게시 된 코드는 이미 주 범인 방법 및 부양 가족에게 상당히 축소되었습니다. '__mod__'은 클래스를 초기화하는 동안 필요하며'__mul__' (고칠 필요가 있음)은 리턴 타입을 다른 특별한 메소드와 비교하기 위해 존재합니다. 이 단일 문제를 아주 오랫동안 디버깅하면서 제공 할 수있는 도움을 주시면 감사하겠습니다. 기본적으로 부서 자체이므로'__div __() '에서 무엇을 확인할 것인지 확신 할 수 없습니다. 나는 부모로부터'__div __()'를 다시 쓰는 대신에 사용하고 싶습니다. 그래서'super()'를 사용하려고합니다. – stackuser

답변

3

return GF2Polynomial(self.outFormat(self.bin/other.bin)) 행의 결과는 1 문자열이되고, GF2Polynomial.parsePolyVariable() 메서드로 전달됩니다.

이 값은 문자가없는, 그래서 라인 :

letter = [str(m.group(0)) for m in re.finditer(r'[a-z]', poly)] 

목록을 반환합니다. 다음 라인 : key = letter[0]IndexError 예외를 제공하기 때문에

degree = max(c); varmatch = True; key = letter[0] 

는 실패합니다.

한 문자 변수를 사용하고 한 줄에 여러 개의 문을 입력했기 때문에 코드를 읽기가 어렵습니다. 따라서 해당 함수에서 기대하는 바가 무엇인지 확인하기가 어렵습니다.

예외는 super()과 별개입니다. 어딘가 자신의 코드에 간단한 버그가 있습니다.

+0

감사! +1. if letter == [] : 48 행에 "1", [1]'을 반환하고 실제로 'mix1 = bf5/bf2 * bf1 % bf5'를 시도하고 오류가 발생할 때까지 잘 진행된 것처럼 보였습니다. '메시지 \t 파일 이름 \t 라인 \t 위치 \t 역 추적은 \t \t \t \t \t C는 : 사용자 \ \ win7pro-VM \ 바탕 화면 \는 암호화 \ GF2BinaryField.py는 \t 형식 오류가 : 비에 의해 순서를 곱 수 없습니다 'BinaryField'타입의 정수 \t \t \t \t '내가 전에 가지고있는 오류이기 때문에, 우리를 내버려 두지 않습니다. 내가하는 것처럼 여러 작업을 함께 전자 (내 원래 질문 당). – stackuser

+0

@stackuser : 그럼 하나 이상의 버그가 있습니다. –

+0

수정과 함께 나는 또한 'mix1 오류 : 변수 x와 x ​​** 5 + x ** 4 + x ** 2 + 1은 '과 일치하지 않습니다. –