没有对齐 Sympy 的漂亮分裂

Not aligned Sympy's nice pritting of division

我正在尝试使用 Sympy 打印一些分区,但我注意到它没有对齐显示。

import sympy
sympy.init_printing(use_unicode=True)

sympy.pprint(sympy.Mul(-1, sympy.Pow(-5, -1, evaluate=False), evaluate=False))
# Output:
# -1 
# ───
#  -5  # Note that "-5" is displayed slightly more on the right than "-1".

Reason/fix为了这个?

编辑: 我使用 inspect.getsourceinspect.getsourcefile 做了很多逆向工程,但最终并没有真​​正帮助。

Sympy 中的 Pretty Printing 似乎依赖于 Jurjen Bos 的 Prettyprinter

import sympy

from sympy.printing.pretty.stringpict import *

sympy.init_printing(use_unicode=True)

prettyForm("-1")/prettyForm("-5")
# Displays:
# -1
# --
# -5

所以它确实显示对齐,但我无法让它使用 unicode。

PrettyPrinter 是在方法 PrettyPrinter._print_Mul 中从文件 sympy/printing/pretty/pretty.py 调用的,我认为 return prettyForm.__mul__(*a)/prettyForm.__mul__(*b) 只是 ab 只是['-1']['-5'] 但它不起作用。

我不太确定你在搜索什么,但我想我刚才正在处理类似的事情。 我得到了一个理解列表并将其用于打印。 您可能会发现它很有用。

    x =  amp * np.sin( 2 * np.pi * 200 * times            ) + nse1
    x2 = np.array_split(x,epochs(
    Rxy[i], freqs_xy = mlab.csd(x2[i], y2[i], NFFT=nfft, Fs=sfreq)
    Rxy_mean0 = [complex(sum(x)/len(x)) for x in Rxy]
    import pprint
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(Rxy_mean0)

负分母不标准且处理不当。如果你真的需要它们,你可以修改漂亮函数给出的字符串输出:

import sympy
sympy.init_printing(use_unicode=True)
def ppprint(expr):
    p=sympy.pretty(expr)
    s=p.split('\n')
    if len(s)==3 and int(s[2])<0:
        s[0]=" "+s[0]
        s[1]=s[1][0]+s[1]
        p2="\n".join(s)
        print(p2) 
    else: print(p)

这扩展了负分母的一个单位的条形和分子。不保证大表达式的稳健性。

>>>> ppprint(sympy.Mul(sympy.Pow(-5, -1,evaluate=False),-1,evaluate=False))
 -1 
────
 -5

找出奇怪部分的来源:

stringpict.py 第 417 行:

        if num.binding==prettyForm.NEG:
            num = num.right(" ")[0]

这只是针对分子进行的。如果分子为负数,它会在分子后添加一个 space……奇怪!

除了直接编辑文件之外,我不确定是否可以修复。我将在 Github.

上报告此事

感谢大家的帮助和建议。

PS: 最后,我用 pdb 帮助我调试并弄清楚到底发生了什么!

编辑: 如果您不能/不想编辑代码源,请修复:

import sympy
sympy.init_printing(use_unicode=True)

from sympy.printing.pretty.stringpict import prettyForm, stringPict

def newDiv(self, den, slashed=False):
    if slashed:
        raise NotImplementedError("Can't do slashed fraction yet")
    num = self
    if num.binding == prettyForm.DIV:
        num = stringPict(*num.parens())
    if den.binding == prettyForm.DIV:
        den = stringPict(*den.parens())

    return prettyForm(binding=prettyForm.DIV, *stringPict.stack(
        num,
        stringPict.LINE,
        den))

prettyForm.__div__ = newDiv

sympy.pprint(sympy.Mul(-1, sympy.Pow(-5, -1, evaluate=False), evaluate=False))

# Displays properly:
# -1
# ──
# -5

我刚刚从代码源中复制了函数并删除了相关行。

可能的改进是 functools.wraps 新功能与原来的功能。