Python -- using __init__ with an inherited method for polynomials class - python

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?
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:
def BinaryField(string, mod):
return GF2Polynomial(string) % mod

Related

Creating custom printing for sympy.Derivative

Say I have a function f(x,y), I want partial derivative of f w.r.t to x appear as
\partial_{x}^{n} f(x,y) so I created the following class
class D(sp.Derivative):
def _latex(self,printer=None):
func = printer.doprint(self.args[0])
b = self.args[1]
if b[1] == 1 :
return r"\partial_{%s}%s"%(printer.doprint(b[0]),func)
else :
return r"\partial_{%s}^{%s}%s"%(printer.doprint(b[0]),printer.doprint(b[1]),func)
which works fine, but goes back to default behavior when I evaluate the derivative by using doit() method. Say I have
x,y = sp.symbols('x,y')
f = sp.Function('f')(x,y)
Then sp.print_latex(D(f,x)) gives \partial_{x}f{\left(x,y \right)} which is correct, but sp.print_latex(D(x*f,x).doit()) yields x \frac{\partial}{\partial x} f{\left(x,y \right)} + f{\left(x,y \right)}, which is the old behavior. How can I fix this issue?
The problem is that you haven't overridden doit from the parent class and it returns plain Derivative objects rather than your subclass. Rather than creating a new Derivative class I suggest to create a new printer class:
from sympy import *
from sympy.printing.latex import LatexPrinter
class MyLatexPrinter(LatexPrinter):
def _print_Derivative(self, expr):
differand, *(wrt_counts) = expr.args
if len(wrt_counts) > 1 or wrt_counts[0][1] != 1:
raise NotImplementedError('More code needed...')
((wrt, count),) = wrt_counts
return '\partial_{%s} %s)' % (self._print(wrt), self._print(differand))
x, y = symbols('x, y')
f = Function('f')
expr = (x*f(x, y)).diff(x)
printer = MyLatexPrinter()
print(printer.doprint(expr))
That gives x \partial_{x} f{\left(x,y \right)}) + f{\left(x,y \right)}
You can use init_printing(latex_printer=printer.doprint) to make this the default output.

Creating a rational class and operator overloading in python

I'm defining rational class, so for example a = Rational(1,2) #1/2, and b = Rational(2,3) #2/3, and I want to have c = a + b so that c = Rational(7,6) #7/6. My code so far is:
class Rational(object):
def __init__(self, v1, v2):
self.value = v1/v2
def __add__(self, value2):
return Rational(self.value + value2.value)
a = Rational(1,2)
b = Rational(2,3)
c = a+b
But I get the TypeError message that init requires 3 arguments (2 given), where did it get wrong in the coding above pls? Thank you!
class RationalNumber:
numerator=1
denominator=1
lcm=1
def __init__(self,numerator,denominator):
if(denominator<=0):
print('Denominator can not be <=0')
else:
gcd=1
divisorsOfNum1 = []
divisorsOfNum2 = []
gotlcm=False
for i in range(1, int(numerator)+1):
if numerator % i == 0:
divisorsOfNum1.append(i)
for i in range(1, int(denominator)+1):
if denominator % i == 0:
divisorsOfNum2.append(i)
for i in range(0, len(divisorsOfNum1)):
for j in range(0, len(divisorsOfNum2)):
if divisorsOfNum1[i] == divisorsOfNum2[j]:
if(gotlcm==False):
gotlcm=True
self.lcm=divisorsOfNum1[i]
gcd = divisorsOfNum1[i]
continue
self.numerator=numerator/gcd
self.denominator=denominator/gcd
print(self.numerator,self.denominator)
def __add__(self,other):
numeratr=self.numerator*other.denominator + other.numerator*self.denominator
denominatr=self.denominator*other.denominator
return RationalNumber(numeratr,denominatr)
def __sub__(self,other):
numeratr=self.numerator*other.denominator - other.numerator*self.denominator
denominatr=self.denominator*other.denominator
return RationalNumber(numeratr,denominatr)
def __truediv__(self,other):
numeratr=self.numerator*other.denominator
denominatr=other.numerator*self.denominator
return RationalNumber(numeratr,denominatr)
def __mul__(self,other):
numeratr=self.numerator*other.numerator
denominatr=other.denominator*self.denominator
return RationalNumber(numeratr,denominatr)
def __ne__(self,other):
if self.numerator!=other.numerator and other.denominator!=self.denominator:
return True
else:
return False
def __eq__(self,other):
if self.numerator==other.numerator and other.denominator==self.denominator:
return True
else:
return False
def __gt__(self,other):
if (self.numerator/self.denominator)>(other.numerator/other.denominator):
return True
else:
return False
def __lt__(self,other):
if (self.numerator/self.denominator)<(other.numerator/other.denominator):
return True
else:
return False
def __ge__(self,other):
if (self.numerator/self.denominator)>=(other.numerator/other.denominator):
return True
else:
return False
def __le__(self,other):
if (self.numerator/self.denominator)<=(other.numerator/other.denominator):
return True
else:
return False
r1=RationalNumber(48,36)
r2=RationalNumber(48,36)
print(r1+r2)
you can perform
addition, subtraction, multiplication, division, relational and equality operations
According to your class, you create an instance of Rational by passing the numerator and denominator to it, but here you're trying to create one just by passing its (floating-point) value. Of course, it's possible to find a rational equivalent to a float, but you haven't taught your class how to do it, and it's not going to magically reverse-engineer itself.
Given the definition of adding fractions: p/q + r/s = (ps + qr) / qs, your addition function should return Rational(ps + qr, qs). The problem is, you haven't kept track of your numerator and denominator in your class, so you have no way of retrieving this information.
As things stand, the best you can do with your addition function is return a self.value + value2.value as a float. So as it stands, your class is basically a long-winded way to do division! To have a meaningful Rational class, I would strongly suggest you keep everything in terms of the numerator and denominator as far as possible.
Edit: I forgot to mention - if you're using Python 2.x your division won't work as it should unless you either convert one (or both) of v1 or v2 to float before doing division, or better still, include the line from __future__ import division at the top, so that division behaves as you'd expect.

Print the entire expression object of sympy when changes in internal structure occur

So as the question says i want to print an entire expression object when internal structure of its tree changes, but as the sympy objects are immutable i cannot to do this with the name the object is bound to
Here is an example of Code on how i am changing the Internal Structure
from sympy import *
from sympy.abc import x,y
input = 'x*(x+4)+3*x'
expr = sympify(input,evaluate=False)
def traverse(expr):
if(expr.is_Number):
return 1,True
oldexpr = expr
args = expr.args
sargs = []
hit = False
for arg in args:
arg,arghit = traverse(arg)
hit |= arghit
sargs.append(arg)
if(hit):
expr = expr.func(*sargs)
return expr,True
else:
return oldexpr,False
print(srepr(expr))
expr,hit = traverse(expr)
print(expr)
here i am changing the number to 1 whenever i encounter a number in the expression tree. And i want to print the complete expression when i made the change like this: x*(x+1)+3*x and then x*(x+1)+x
Can anyone suggest me on how to achieve this.
Just a slight mod to what you have might be what you are looking for:
def traverse(expr):
if any(a.is_Number and abs(a) != 1 for a in expr.args):
print(expr,'->',expr.func(*[(a if not a.is_Number else 1) for a in expr.args]))
if expr.is_Number and abs(expr) != 1:
return 1, True
oldexpr = expr
args = expr.args
sargs = []
hit = False
for arg in args:
arg,arghit = traverse(arg)
hit |= arghit
sargs.append(arg)
if(hit):
expr = expr.func(*sargs)
return expr, True
else:
return oldexpr, False
This produces
>>> traverse(2*x+3)
(2*x + 3, '->', 2*x + 1)
(2*x, '->', x)
(x + 1, True)
/c

Printing an object python class

I wrote the following program:
def split_and_add(invoer):
rij = invoer.split('=')
rows = []
for line in rij:
rows.append(process_row(line))
return rows
def process_row(line):
temp_coordinate_row = CoordinatRow()
rij = line.split()
for coordinate in rij:
coor = process_coordinate(coordinate)
temp_coordinate_row.add_coordinaterow(coor)
return temp_coordinate_row
def process_coordinate(coordinate):
cords = coordinate.split(',')
return Coordinate(int(cords[0]),int(cords[1]))
bestand = file_input()
rows = split_and_add(bestand)
for row in range(0,len(rows)-1):
rij = rows[row].weave(rows[row+1])
print rij
With this class:
class CoordinatRow(object):
def __init__(self):
self.coordinaterow = []
def add_coordinaterow(self, coordinate):
self.coordinaterow.append(coordinate)
def weave(self,other):
lijst = []
for i in range(len(self.coordinaterow)):
lijst.append(self.coordinaterow[i])
try:
lijst.append(other.coordinaterow[i])
except IndexError:
pass
self.coordinaterow = lijst
return self.coordinaterow
However there is an error in
for row in range(0,len(rows)-1):
rij = rows[row].weave(rows[row+1])
print rij
The outcome of the print statement is as follows:
[<Coordinates.Coordinate object at 0x021F5630>, <Coordinates.Coordinate object at 0x021F56D0>]
It seems as if the program doesn't acces the actual object and printing it. What am i doing wrong here ?
This isn't an error. This is exactly what it means for Python to "access the actual object and print it". This is what the default string representation for a class looks like.
If you want to customize the string representation of your class, you do that by defining a __repr__ method. The typical way to do it is to write a method that returns something that looks like a constructor call for your class.
Since you haven't shown us the definition of Coordinate, I'll make some assumptions here:
class Coordinate(object):
def __init__(self, x, y):
self.x, self.y = x, y
# your other existing methods
def __repr__(self):
return '{}({}, {})'.format(type(self).__name__, self.x, self.y)
If you don't define this yourself, you end up inheriting __repr__ from object, which looks something like:
return '<{} object at {:#010x}>'.format(type(self).__qualname__, id(self))
Sometimes you also want a more human-readable version of your objects. In that case, you also want to define a __str__ method:
def __str__(self):
return '<{}, {}>'.format(self.x, self.y)
Now:
>>> c = Coordinate(1, 2)
>>> c
Coordinate(1, 2)
>>> print(c)
<1, 2>
But notice that the __str__ of a list calls __repr__ on all of its members:
>>> cs = [c]
>>> print(cs)
[Coordinate(1, 2)]

Mathematical equation manipulation in Python

I want to develop a GUI application which displays a given mathematical equation. When you click upon a particular variable in the equation to signify that it is the unknown variable ie., to be calculated, the equation transforms itself to evaluate the required unknown variable.
For example:
a = (b+c*d)/e
Let us suppose that I click upon "d" to signify that it is the unknown variable. Then the equation should be re-structured to:
d = (a*e - b)/c
As of now, I just want to know how I can go about rearranging the given equation based on user input. One suggestion I got from my brother was to use pre-fix/post-fix notational representation in back end to evaluate it.
Is that the only way to go or is there any simpler suggestion?
Also, I will be using not only basic mathematical functions but also trignometric and calculus (basic I think. No partial differential calculus and all that) as well. I think that the pre/post-fix notation evaluation might not be helpful in evaluation higher mathematical functions.
But that is just my opinion, so please point out if I am wrong.
Also, I will be using SymPy for mathematical evaluation so evaluation of a given mathematical equation is not a problem, creating a specific equation from a given generic one is my main problem.
Using SymPy, your example would go something like this:
>>> import sympy
>>> a,b,c,d,e = sympy.symbols('abcde')
>>> r = (b+c*d)/e
>>> l = a
>>> r = sympy.solve(l-r,d)
>>> l = d
>>> r
[(-b + a*e)/c]
>>>
It seems to work for trigonometric functions too:
>>> l = a
>>> r = b*sympy.sin(c)
>>> sympy.solve(l-r,c)
[asin(a/b)]
>>>
And since you are working with a GUI, you'll (probably) want to convert back and forth from strings to expressions:
>>> r = '(b+c*d)/e'
>>> sympy.sympify(r)
(b + c*d)/e
>>> sympy.sstr(_)
'(b + c*d)/e'
>>>
or you may prefer to display them as rendered LaTeX or MathML.
If you want to do this out of the box, without relying on librairies, I think that the problems you will find are not Python related. If you want to find such equations, you have to describe the heuristics necessary to solve these equations.
First, you have to represent your equation. What about separating:
operands:
symbolic operands (a,b)
numeric operands (1,2)
operators:
unary operators (-, trig functions)
binary operators (+,-,*,/)
Unary operators will obviously enclose one operand, binary ops will enclose two.
What about types?
I think that all of these components should derivate from a single common expression type.
And this class would have a getsymbols method to locate quickly symbols in your expressions.
And then distinguish between unary and binary operators, add a few basic complement/reorder primitives...
Something like:
class expression(object):
def symbols(self):
if not hasattr(self, '_symbols'):
self._symbols = self._getsymbols()
return self._symbols
def _getsymbols(self):
"""
return type: list of strings
"""
raise NotImplementedError
class operand(expression): pass
class symbolicoperand(operand):
def __init__(self, name):
self.name = name
def _getsymbols(self):
return [self.name]
def __str__(self):
return self.name
class numericoperand(operand):
def __init__(self, value):
self.value = value
def _getsymbols(self):
return []
def __str__(self):
return str(self.value)
class operator(expression): pass
class binaryoperator(operator):
def __init__(self, lop, rop):
"""
#type lop, rop: expression
"""
self.lop = lop
self.rop = rop
def _getsymbols(self):
return self.lop._getsymbols() + self.rop._getsymbols()
#staticmethod
def complementop():
"""
Return complement operator:
op.complementop()(op(a,b), b) = a
"""
raise NotImplementedError
def reorder():
"""
for op1(a,b) return op2(f(b),g(a)) such as op1(a,b) = op2(f(a),g(b))
"""
raise NotImplementedError
def _getstr(self):
"""
string representing the operator alone
"""
raise NotImplementedError
def __str__(self):
lop = str(self.lop)
if isinstance(self.lop, operator):
lop = '(%s)' % lop
rop = str(self.rop)
if isinstance(self.rop, operator):
rop = '(%s)' % rop
return '%s%s%s' % (lop, self._getstr(), rop)
class symetricoperator(binaryoperator):
def reorder(self):
return self.__class__(self.rop, self.lop)
class asymetricoperator(binaryoperator):
#staticmethod
def _invert(operand):
"""
div._invert(a) -> 1/a
sub._invert(a) -> -a
"""
raise NotImplementedError
def reorder(self):
return self.complementop()(self._invert(self.rop), self.lop)
class div(asymetricoperator):
#staticmethod
def _invert(operand):
if isinstance(operand, div):
return div(self.rop, self.lop)
else:
return div(numericoperand(1), operand)
#staticmethod
def complementop():
return mul
def _getstr(self):
return '/'
class mul(symetricoperator):
#staticmethod
def complementop():
return div
def _getstr(self):
return '*'
class add(symetricoperator):
#staticmethod
def complementop():
return sub
def _getstr(self):
return '+'
class sub(asymetricoperator):
#staticmethod
def _invert(operand):
if isinstance(operand, min):
return operand.op
else:
return min(operand)
#staticmethod
def complementop():
return add
def _getstr(self):
return '-'
class unaryoperator(operator):
def __init__(self, op):
"""
#type op: expression
"""
self.op = op
#staticmethod
def complement(expression):
raise NotImplementedError
def _getsymbols(self):
return self.op._getsymbols()
class min(unaryoperator):
#staticmethod
def complement(expression):
if isinstance(expression, min):
return expression.op
else:
return min(expression)
def __str__(self):
return '-' + str(self.op)
With this basic structure set up, you should be able to describe a simple heuristic to solve very simple equations. Just think of the simple rules you learned to solve equations, and write them down. That should work :)
And then a very naive solver:
def solve(left, right, symbol):
"""
#type left, right: expression
#type symbol: string
"""
if symbol not in left.symbols():
if symbol not in right.symbols():
raise ValueError('%s not in expressions' % symbol)
left, right = right, left
solved = False
while not solved:
if isinstance(left, operator):
if isinstance(left, unaryoperator):
complementor = left.complement
right = complementor(right)
left = complementor(left)
elif isinstance(left, binaryoperator):
if symbol in left.rop.symbols():
left = left.reorder()
else:
right = left.complementop()(right, left.rop)
left = left.lop
elif isinstance(left, operand):
assert isinstance(left, symbolicoperand)
assert symbol==left.name
solved = True
print symbol,'=',right
a,b,c,d,e = map(symbolicoperand, 'abcde')
solve(a, div(add(b,mul(c,d)),e), 'd') # d = ((a*e)-b)/c
solve(numericoperand(1), min(min(a)), 'a') # a = 1
Things have sure changed since 2009. I don't know how your GUI application is going, but this is now possible directly in IPython qtconsole (which one could embed inside a custom PyQt/PySide application, and keep track of all the defined symbols, to allow GUI interaction in a separate listbox, etc.)
(Uses the sympyprt extension for IPython)
What you want to do isn't easy. Some equations are quite straight forward to rearrange (like make b the subject of a = b*c+d, which is b = (a-d)/c), while others are not so obvious (like make x the subject of y = x*x + 4*x + 4), while others are not possible (especially when you trigonometric functions and other complications).
As other people have said, check out Sage. It does what you want:
You can solve equations for one variable in terms of others:
sage: x, b, c = var('x b c')
sage: solve([x^2 + b*x + c == 0],x)
[x == -1/2*b - 1/2*sqrt(b^2 - 4*c), x == -1/2*b + 1/2*sqrt(b^2 - 4*c)]
Sage has support for symbolic math. You could just use some of the equation manipulating functions built-in:
http://sagemath.org/

Categories