Cette classe prend une chaîne polynomiale à corps fini, l'analyse, opère (+ - * /%), puis affiche le même format que l'entrée. Cela fonctionne bien (jusqu'à présent). Cependant, maintenant j'essaye d'implémenter des méthodes spéciales sur les opérateurs arithmétiques, et je ne peux pas passer le point de simplement concaténer les chaînes. Généralement, l'idée est d'initialiser l'entrée dans une instance de classe, mais dans ce cas, il y a une regex en entrée qui semble compliquer toute tentative de faire cela. Je m'enseigne Python donc c'est un film d'horreur pour moi, mais probablement juste un jouet pour tout programmeur Python chevronné.Python - arithmétique de méthodes spéciales utilisant des méthodes de classe existantes
Ceux-ci semblent avoir beaucoup d'informations, mais je ne sais pas combien ils sont utiles dans cette situation:
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
Voici la classe et les exemples que je suis en utilisant:
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)
le dernier exemple en bas montre le problème:
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
Et la sortie:
>>>
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
>>>
Comme vous pouvez le voir par smadd1
je dois ajouter ces 2 en utilisant + et pas seulement concaténer. De plus, j'aimerais savoir si je dois utiliser un arbre d'expression S dans cette situation.
EDIT:
Multiply() qui fonctionnait mais pas maintenant:
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)))
sa forme originale était:
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))
Mépris cette question avec multiply()
, Je l'ai corrigé. La ligne qui a été modifiée était:
bitsa = reversed("{0:b}".format(self.bin))
et la ligne avant celle-ci a été retirée.
oui merci, exactement ce dont j'avais besoin. Je ne sais pas pourquoi vous avez utilisé la méthode __str __ (self). est-ce seulement pour le __init __() et pourquoi? aussi pourquoi avez-vous déplacé parsePolyToListInput() en dehors de prepBinary() pour initialiser sur son propre dans la méthode __init __()? – stackuser
La méthode '__str__' est appelée lorsque vous utilisez' print'. Essayez de le supprimer et vous verrez que l'impression d'objets de votre classe donne un résultat moins utile.Je n'ai pas entièrement compris votre code car je refactoring, donc mon choix déplace parsePolyToListInput() de prepBinary() était quelque peu arbitraire. Je comprends mieux maintenant et j'ai quelques minutes gratuites, je vais donc refactoriser et éditer mon post. – jcrudy