开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜