防止Sympy中的乘法表达式求值

时间:2017-02-27 12:52:33

标签: python python-3.x numpy latex sympy

我正在生成一个包含两个分数的表达式,并希望使用LaTeX将整个表达式打印出来,然后放入工作表。

E.g。形式如下:

(5/7) * (3/4). 

但是,当我执行以下操作时:

fract1 = sympy.sympify(Fraction(5,7))
fract2 = sympy.sympify(Fraction(3,4))
expression = sympy.Mul(fract1,fract2,evaluate=False)

返回

5*3/(7*4)

显然它正在组合分数而不是实际评估,但我希望能够以适合作为数学工作表问题的格式生成它。

2 个答案:

答案 0 :(得分:2)

非常讨厌的方式(仅适用于两个分数的情况):

def print_fractions(expr):
    print("({}) * ({})".format(*expr.args))

像这样工作:

In:  expr = sympy.Mul(sympy.S("5/7"), sympy.S("3/4"), evaluate=False)
In:  expr
Out: 5*3/(7*4)
In:  print_fractions(expr)
Out: (5/7) * (3/4)

您可以与srepr核实,expr中的分数实际上没有合并,这只是sympy决定打印它的方式:

In:  sympy.srepr(expr)
Out: 'Mul(Rational(5, 7), Rational(3, 4))'

另一种方法是扩展sympy.Mul覆盖__str__方法:

class MyMul(sympy.Mul):
    def __str__(self):
        return "({}) * ({})".format(*self.args)

然后你会:

In:  expr = MyMul(sympy.S("5/7"), sympy.S("3/4"), evaluate=False)
In:  print(expr)
Out: (5/7) * (3/4)

Eidt:如何让latex()工作

Hackish再次接近,但是:

class MyMul(Mul):
    def _latex(self, _):
        return r"\left({} \cdot {}\right)".format(*map(latex, self.args))

现在:

In:  a = S("5/7")
In:  b = S("3/4")
In:  c = MyMul(a, b, evaluate=False)
In:  print(latex(c))
Out: \left(\frac{5}{7} \cdot \frac{3}{4}\right)

当然,您可以在上面_latex的定义中更改您输出的确切内容。

答案 1 :(得分:2)

下一个SymPy版本将有UnevaluatedExpr

In [4]: uexpr = UnevaluatedExpr(S.One*5/7)*UnevaluatedExpr(S.One*3/4)

In [7]: uexpr
Out[7]: 5/7⋅3/4

要发布和评估它,只需使用.doit()

In [8]: uexpr.doit()
Out[8]: 
15
──
28

LaTeX输出如下:

In [10]: print(latex(uexpr))
\frac{5}{7} \frac{3}{4}

自SymPy 1.1起,此功能可用。请参阅documentation to find out more