inheritance - Python -- polynomials in finite fields. Why does only __add__() work with super() in this case? -
i'm trying use parent class's __div__()
in order maintain same type many operations can called @ once in last example mix1 = bf2/bf4*bf1%bf5
in main()
below multiple arithmetic operations strung together. reason, can use super() in __add__()
not in __div__()
. error "indexerror: list index out of range" , i've been going on , on without progress. note related polynomial arithmetic within finite field.
i'm including parsepolyvariable()
, it's dependents (sorry if looks there's bit of code assure it's cause , builds character), since that's list error seems stemming can't life of me figure out going wrong. i'm teaching myself python, i'm sure there other beginners out there see i'm missing obvious.
i've been looking on these don't seem related situation:
http://docs.python.org/2/library/functions.html#super
python super(class, self).method vs super(parent, self).method
how can use python's super() update parent value?
import re class gf2polynomial(object): #classes should inherit object def __init__(self, string): '''__init__ standard special method used initialize objects. here __init__ initialize gf2infix object based on string.''' self.string = string #basically 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,....) input lists""" return [int(lst[i])%2 in range(len(lst))] def listtoint(self,lst): """converts list integer later use""" result = self.id(lst) return int(''.join(map(str,result))) def parsepolytolistinput(self,poly): """ replaced parsepolyvariable. still functional not needed. performs regex on raw string , converts list """ c = [int(i.group(0)) in re.finditer(r'\d+', poly)] return [1 if x in c else 0 x in xrange(max(c), -1, -1)] def parsepolyvariable(self,poly): """ performs regex on raw string, converts list. determines key (main variable used) in each polynomial on intake """ c = [int(m.group(0)) m in re.finditer(r'\d+', poly)] #re.finditer returns iterator if sum(c) == 0: return "0",[0] letter = [str(m.group(0)) m in re.finditer(r'[a-z]', poly)] degree = max(c); varmatch = true; key = letter[0] in range(len(letter)): if letter[i] != key: varmatch = false else: varmatch = true if varmatch == false: return "error: not variables in %s same"%a lst = [1 if x in c else (1 if x==0 else (1 if x=='x' else 0)) x in xrange(degree, -1, -1)] return key,lst def polyvariablecheck(self,other): return self.key == other.key def prepbinary(self,poly): """converts base 2; bina,binb binary values 110100101100.....""" x = self.lst; = self.listtoint(x) return int(str(a),2) def __add__(self,other): """ __add__ special method, , used override + operator. work instances of gf2pim , subclasses. self,other gf2infix instances; returns gf(2) polynomial in string format """ if self.polyvariablecheck(other) == false: return "error: variables of %s , %s not match"%(self.string,other.string) return gf2polynomial(self.outformat(self.bin^other.bin)) def __sub__(self,other): """ __sub__ special method overriding - operator same addition in gf(2) """ return self.__add__(other) def __mul__(self,other): """ __mul__ special method overriding * operator returns product of 2 polynomials in gf2; self,other values 10110011... """ if self.polyvariablecheck(other) == false: return "error: variables of %s , %s not match"%(self.string,other.string) bitsa = reversed("{0:b}".format(self.bin)) g = [(other.bin<<i)*int(bit) i,bit in enumerate(bitsa)] return gf2polynomial(self.outformat(reduce(lambda x,y: x^y,g))) def __div__(self,other): """ __div__ special method overriding / operator returns quotient formatted polynomial """ if self.polyvariablecheck(other) == false: return "error: variables of %s , %s 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__ special method overriding % operator returns remainder formatted polynomial """ if self.polyvariablecheck(other) == false: return "error: variables of %s , %s 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 polynomial format""" raw = "{0:b}".format(raw); raw = str(raw[::-1]); g = [] #reverse binary string enumeration g = [i 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 0" elif mod == "0": self.string = "%s 0 resulting mod 0"%(poly) fieldpoly = gf2polynomial(poly) % mod if fieldpoly == 0: self.string = "%s , %s same resulting mod 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 gf2polynomial """ return super(binaryfield, self).__add__(other) % min(other,self) def __sub__(self,other): """ inherited gf2polynomial """ return self.__add__(other) def __mul__(self, other): """ special method of binaryfield, needed 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 , %s not match"%(self.string,other.string) if self.polyfieldcheck(other) == false: return "error: fields of %s , %s not match"%(self.string,other.string) else: print "operation proceed: fields of %s , %s match"%(self.string,other.string) bitsa = reversed("{0:b}".format(self.bin)) g = [(other.bin<<i)*int(bit) 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 format adjustments between classes """ if self.polyvariablecheck(other) == false: return "error: variables of %s , %s not match"%(self.string,other.string) if self.polyfieldcheck(other) == false: return "error: fields of %s , %s not match"%(self.string,other.string) else: print "operation proceed: fields of %s , %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
and here's 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" = 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); = 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)
edit: full traceback --
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
for reference line 48 degree = max(c); varmatch = true; key = letter[0]
. personal notes , information removed, adjusting line numbers.
your return gf2polynomial(self.outformat(self.bin/other.bin))
line results in string 1
, passed gf2polynomial.parsepolyvariable()
method.
this value has no letters, line:
letter = [str(m.group(0)) m in re.finditer(r'[a-z]', poly)]
returns empty list. next line:
degree = max(c); varmatch = true; key = letter[0]
then fails because key = letter[0]
gives indexerror
exception.
your code hard read because use one-letter variables , put multiple statements on 1 line, hard make out expectations in function.
the exception has otherwise nothing super()
. there simple bug in own code somewhere.
Comments
Post a Comment