determining numerator and denominator in a relatively complex mathematical expression using python
I'm trying to convert calculator input to LaTeX. if a user inputs this:
(3x^(x+(5/x)+(x/33))+y)/(32 + 5)
I have to convert it to this:
frac{3x^(x+frac{5}{x}+frac{x}{33})+y}{32 + 5x}
however I am having issues 开发者_C百科with determining when a numerator begins and ends. Any suggestions?
Have a look at compiler
compiler.parse('(3*x**(x+(5/x)+(x/33))+y)/(32 + 5)')
returns
Module(None, Stmt([Discard(Div((Add((Mul((Const(3), Power((Name('x'), Add((Add((Name('x'), Div((Const(5), Name('x'))))), Div((Name('x'), Const(33))))))))), Name('y'))), Add((Const(32), Const(5))))))]))
which could be more easily converted to LaTeX code. You will have to write methods, that handle each code (Div, Add, Const, Name, Power,...) and its parameters recursively and return appropriate LateX code.
A package already exists for this kind of transformation : Py2Tex
If you want to reuse this package, you can use the py2tex.Interpret
class to do so.
If you'd like to use the exact syntax from your question then you could write a parser for the calculator:
#!/usr/bin/env python
from operator import add, div, mul, sub
from lepl import Any, Delayed, Digit, Drop, DroppedSpace, Eos
from sympy import Symbol, latex, pprint
def Power(tokens):
"""x**(y**z)"""
return reduce(lambda p, b: pow(b, p), reversed(tokens))
def Arithm(tokens):
"""(x op1 y) op2 z ..."""
OP = { '*': mul, '/': div, '+': add, '-': sub, }
tokens = iter(tokens)
a = next(tokens)
for op, b in zip(tokens, tokens):
a = OP[op](a, b)
return a
def makeparser():
expr = Delayed()
number = Digit()[1:,...] >> int # \d+
symbol = Any('xyz') >> (lambda x: Symbol(bytes(x))) # unicode -> str
muldiv_op = Any('*/')[:1] > (lambda x: x[0] if x else '*') # xy -> x*y
power_op = Drop('^') | Drop('**') # both stand for pow(x, y)
with DroppedSpace(): # ignore spaces
term = number | symbol | Drop('(') & expr & Drop(')')
power = term & (power_op & term)[:] > Power
factor = power & (muldiv_op & power)[:] > Arithm
expr += factor & (Any('-+') & factor)[:] > Arithm
line = expr & Eos()
return line.get_parse()
parse = makeparser()
[expr] = parse('(3x^(x+(5/x)+(x/33))+y)/(32 + 5)')
pprint(expr)
print(latex(expr))
Output
34⋅x 5
──── + ─
33 x
y 3⋅x
── + ───────────
37 37
$\frac{1}{37} y + \frac{3}{37} x^{\frac{34}{33} x + \frac{5}{x}}$
In general it might be preferable to use syntax for an existing language such as Python.
精彩评论