简体   繁体   English

Python —将__init__与继承的方法用于多项式类

[英]Python — using __init__ with an inherited method for polynomials class

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. 我一直在尝试将该类继承为另一个类,该类随后将使用第一个类的__mod __()特殊方法(或在必要时使其成为自己的特殊方法,但我看不到如何不能只使用原始类方法)对摄入量进行修改。 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. 似乎是这样的__init __(),但是我尝试了5个不同的版本,甚至更改了父类,但我一无所获。 I'm teaching myself Python so I'm sure that even a junior Python dev can see where I'm going totally wrong. 我正在自学Python,因此我敢肯定,即使是初级Python开发人员也可以看到我要去哪里完全错了。

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: 请注意,类“ BinaryField”是预期的子类:

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'). 进气时,给定的多项式应为模数除以第二个元素(此处为“ 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' 此外,当使用BinaryField(poly4,d)(与GF2Polynomial()初始化是相同的字符串)时,出现以下错误: AttributeError: 'int' object has no attribute 'string'

Does this solves your problem? 这样可以解决您的问题吗?

class BinaryField(GF2Polynomial):
    def __init__(self, string, mod):
        modded = GF2Polynomial(string) % mod
        super(BinaryField, self).__init__(modded.string)


>>> p = GF2Polynomial("x**2+x**1+x**0")
>>> a = BinaryField("x**1+x**0", p)
>>> print a
x + 1

You can also make the BinaryField class to be just a factory method: 您还可以使BinaryField类只是一种工厂方法:

def BinaryField(string, mod):
    return GF2Polynomial(string) % mod

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM