Preventing a multiplication expression evaluating in Sympy

我是研究僧i 提交于 2021-02-08 15:07:51

问题


I am generating an expression with two fractions, and want to pretty print as a whole expression with LaTeX, to then put on a worksheet.

E.g. in the form:

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

However, when I do the following:

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

It returns

5*3/(7*4)

Clearly it is combining the fraction but not actually evaluating, but I want to be able to produce it in a format suitable as a question for a maths worksheet.


回答1:


The next SymPy version will have UnevaluatedExpr:

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

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

To release and evaluate it, just use .doit():

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

LaTeX output looks like:

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

This feature is available since SymPy 1.1. See the documentation to find out more.




回答2:


Very hackish way to do it (just for your case of two fractions):

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

Works like this:

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)

You can check with srepr that the fractions are actually not combined in expr, it's just the way sympy decides to print it:

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

Another approach is to extend sympy.Mul overriding __str__ method:

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

Then you'll have:

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

Eidt: how to make latex() to work

Hackish approach again, but:

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

Now:

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)

Of course, you can change what exactly you're outputting in the definition of _latex above.



来源:https://stackoverflow.com/questions/42486283/preventing-a-multiplication-expression-evaluating-in-sympy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!