이 클래스는 유한 필드 다항 문자열을 가져 와서 구문 분석하고 (+ - */%) 연산 한 다음 입력과 같은 형식으로 출력합니다. 그것은 잘 작동합니다 (지금까지). 그러나 이제는 산술 연산자에 대한 특수 메서드를 구현하려고하는데 단순히 문자열을 연결하는 지점을 지나칠 수 없습니다. 일반적으로, 그 아이디어는 클래스 인스턴스로 입력을 초기화하는 것이지만,이 경우에는 입력을 정규식으로 처리하는 시도가 복잡해 보입니다. 저는 제 스스로에게 파이썬을 가르치고 있습니다. 그래서 이것은 나를위한 공포 영화이지만, 노련한 파이썬 프로그래머를위한 장난감 일 것입니다. Python - 기존 클래스 메서드를 사용하는 특수 메서드 산술
이
은 많은 정보를 갖고있는 것 같다, 그러나 나는 그들이이 상황에서 도움이있어 얼마나 확실하지 않다 :http://stackoverflow.com/questions/10842166/programmatically-create-arithmetic-special-methods-in-python-aka-factory-funct
http://rosettacode.org/wiki/S-Expressions
http://www.greenteapress.com/thinkpython/thinkCSpy/html/chap14.html
http://docs.cython.org/src/userguide/special_methods.html
여기에 클래스의와 예 내가 사용 :
obj = gf2pim()
a = "x**14 + x**1 + x**0"; b = "x**6 + x**2 + x**1"
c = "x**2 + x**1 + x**0"; d = "x**3 + x**1 + x**0"
e = "x**3 + x**2 + x**1 + x**0"; f = "x**2"; g = "x**1 + x**0"; h = "x**3 + x**2 + x**0"
p = "x**13 + x**1 + x**0"; q = "x**12 + x**1"; j = "x**4 + x**3 + x**1 + x**0"
print "add: [%s] + [%s] = %s "%(a,b,obj.add(a,b))
print "add: [%s] + [%s] = %s "%(c,d,obj.add(c,d))
print "quotient (max(a,b)/min(a,b): [%s]/[%s] = %s "%(a,b,obj.quotient(a,b))
print "remainder (max(a,b) mod min(a,b)): [%s] mod [%s] = %s "%(a,b,obj.remainder(a,b))
print "quotient (max(a,b)/min(a,b): [%s]/[%s] = %s "%(c,d,obj.quotient(c,d))
print "remainder (max(a,b) mod min(a,b): [%s] mod [%s] = %s "%(c,d,obj.remainder(c,d))
print "quotient (max(a,b)/min(a,b): [%s]/[%s] = %s "%(q,q,obj.quotient(q,q))
print "remainder (max(a,b) mod min(a,b): [%s] mod [%s] = %s "%(q,q,obj.remainder(q,q))
print "modular_inverse: [%s] * [%s] mod [%s] = 1 [%s]"%(p,valuemi2[0],q,valuemi2[1])
sum1 = obj.add(a,b); quotient1 = obj.quotient(sum1,c)
### HERE THE PROBLEM IS CLEAR
print "[(a+b)/c] = ",quotient1
smadd1 = a+b
print "smadd1 ",smadd1
출력 :
import re
class gf2pim:
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):
"""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 prepBinary(self,x,y):
"""converts to base 2; bina,binb are binary values like 110100101100....."""
x = self.parsePolyToListInput(x); y = self.parsePolyToListInput(y)
a = self.listToInt(x); b = self.listToInt(y)
bina = int(str(a),2); binb = int(str(b),2)
return bina,binb #
def add(self,a,b):
"""a,b are GF(2) polynomials like x**7 + x**3 + x**0 ...; returns binary string"""
bina,binb = self.prepBinary(a,b)
return self.outFormat(bina^binb)
def subtract(self,x,y):
"""same as addition in GF(2)"""
return self.add(x,y)
def quotient(self,a,b):
"""a,b are GF(2) polynomials like x**7 + x**3 + x**0 ...; returns quotient formatted as polynomial"""
a,b = self.prepBinary(a,b)
return self.outFormat(a/b)
def remainder(self,a,b):
"""a,b are GF(2) polynomials like x**7 + x**3 + x**0 ...; returns remainder formatted as polynomial"""
a,b = self.prepBinary(a,b)
return self.outFormat(a%b)
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]))
if len(g) == 0: return 0 #return 0 if list empty
return processed #returns result in gf(2) polynomial form
def __add__(self,other):
return gf2pim.add(self,other)
하단 마지막 예는 문제점을 나타내는
>>>
add: [x**14 + x**1 + x**0] + [x**6 + x**2 + x**1] = x**14 + x**6 + x**2 + x**0
add: [x**2 + x**1 + x**0] + [x**3 + x**1 + x**0] = x**3 + x**2
quotient (max(a,b)/min(a,b): [x**14 + x**1 + x**0]/[x**6 + x**2 + x**1] = x**7 + x**6 + x**5 + x**3 + x**1
remainder (max(a,b) mod min(a,b)): [x**14 + x**1 + x**0] mod [x**6 + x**2 + x**1] = x**2 + x**1 + x**0
quotient (max(a,b)/min(a,b): [x**2 + x**1 + x**0]/[x**3 + x**1 + x**0] = 0
remainder (max(a,b) mod min(a,b): [x**2 + x**1 + x**0] mod [x**3 + x**1 + x**0] = x**2 + x**1 + x**0
quotient (max(a,b)/min(a,b): [x**12 + x**1]/[x**12 + x**1] = x**0
remainder (max(a,b) mod min(a,b): [x**12 + x**1] mod [x**12 + x**1] = 0
[(a+b)/c]*d = x**14 + x**12 + x**9 + x**1
smadd1 x**14 + x**1 + x**0x**6 + x**2 + x**1
>>>
smadd1
에서 볼 수 있듯이이 두 가지를 +를 사용하여 연결해야합니다. 또한이 상황에서 S-expression 트리를 사용해야하는지 알고 싶습니다.
편집 :
def __mul__(self,other):
"""
__multiply__ is the special method for overriding the - operator
returns product of 2 polynomials in gf2; self,other are values 10110011...
"""
self = int(str(self),2)
bitsa = reversed("{0:b}".format(self))
g = [(other<<i)*int(bit) for i,bit in enumerate(bitsa)]
return gf2infix(self.outFormat(reduce(lambda x,y: x^y,g)))
그것은 원래의 형태였다 것 : 작동하지만 지금은 아니다 된
곱하기()
def multiply(self,a,b):
"""a,b are GF(2) polynomials like x**7 + x**3 + x**0... ; returns product of 2 polynomials in gf2"""
a = self.prepBinary(a); b = self.prepBinary(b)
bitsa = reversed("{0:b}".format(a))
g = [(b<<i)*int(bit) for i,bit in enumerate(bitsa)]
return self.outFormat(reduce(lambda x,y: x^y,g))
무시하는 문제 multiply()
으로, 나는 그것을 고쳤다. 변경된 행은 다음과 같습니다.
bitsa = reversed("{0:b}".format(self.bin))
및 그 이전 행은 다음과 같습니다.
네, 감사드립니다. 왜 __str __ (self) 메소드를 사용했는지 모르겠습니다. 그것은 __init __()와 그 이유에 대해서만 무엇입니까? 또한 왜 prepBinary() 외부에서 parsePolyToListInput()을 이동하여 __init __() 메서드 내에서 초기화되도록 했습니까? – stackuser
'print'를 사용할 때'__str__' 메쏘드가 호출됩니다. 이를 제거하면 클래스의 인쇄 객체가 덜 유용한 결과를 얻게됩니다.내가 리팩토링 할 때 코드를 완전히 이해하지 못했기 때문에 prepBinary()에서 parsePolyToListInput()을 사용하는 것이 다소 임의적이었습니다. 지금은 더 잘 이해하고 몇 분 정도 무료로 사용할 수 있으므로 다시 수정하고 내 게시물을 편집 할 것입니다. – jcrudy