开发者

determining numerator and denominator in a relatively complex mathematical expression using python

开发者 https://www.devze.com 2023-02-09 04:49 出处:网络
I\'m trying to convert calculator input to LaTeX. if a user inputs this: (3x^(x+(5/x)+(x/33))+y)/(32 + 5)

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

精彩评论

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

关注公众号