This is a class which will take in as input and then output a polynomial in string form (both ways same format). Some arithmetic is performed in the various methods. I've been trying to inherit this class into another class that will then use the __mod__() special method of the first class (or make it's own special method if necessary but I don't see how you can't just use the original method) to perform the mod on intake. Seems like this goes into __init__() but I've tried 5 different versions of this, even going so far as to change the parent class, and I'm getting nowhere. I'm teaching myself Python so I'm sure that even a junior Python dev can see where I'm going totally wrong.
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
The desired result is to be able to call it on a new (child) class with the parent type and while changing the parent class as little as possible (if even at all). Note that class "BinaryField" is the intended child class:
p=GF2Polynomial("x**2+x**1+x**0")
a=BinaryField("x**1+x**0", p)
b=BinaryField("x**1", p)
On intake, the given polynomial should be modulus divided by the 2nd element (here it's 'p'). This is necessary for finite field math.
EDIT: when running it with --
## "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
Both of these styles are possible because of the way I coded it, but they should both return the same answer. However the result on that code is:
>>>
x**5 + x**4 + x**3 + 1
x**5 + x
Also, when using BinaryField(poly4,d), which is just the same string with it's GF2Polynomial() initialization, this errors as:
AttributeError: 'int' object has no attribute 'string'
Does this solves your problem?
You can also make the
BinaryField
class to be just a factory method: