Подтвердить что ты не робот

Не выровненный Sympy приятный прием деления

Я пытаюсь смириться с некоторыми разделами с 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".

Причина/исправление для этого?

РЕДАКТИРОВАТЬ: Я сделал много обратного проектирования с использованием inspect.getsource и inspect.getsourcefile, но в конце концов это не помогло.

Pretty Printing в Sympy, похоже, полагается на Prettyprinter Jurjen Bos.

import sympy

from sympy.printing.pretty.stringpict import *

sympy.init_printing(use_unicode=True)

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

Таким образом, он отображает выравнивание, но я не могу заставить его использовать unicode.

PrettyPrinter вызывается из файла sympy/printing/pretty/pretty.py в методе PrettyPrinter._print_Mul, который просто return prettyForm.__mul__(*a)/prettyForm.__mul__(*b) с, я думал, a и b просто был ['-1'] и ['-5'], но это не будет работа.

4b9b3361

Ответ 1

Обнаружено, откуда происходит странная часть:

stringpict.py строка 417:

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

Это делается ТОЛЬКО для числителя. Он добавляет пробел после числителя, если числитель отрицательный... Weird!

Я не уверен, может ли быть фиксированное, кроме прямого редактирования файла. Я собираюсь сообщить об этом в Github.

Спасибо всем за вашу помощь и предложение.

PS: В конце я использовал pdb, чтобы помочь мне отладить и выяснить, что на самом деле происходит!

EDIT: Исправление, если вы не можете/не хотите редактировать источник кода:

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 новой функции с исходной.

Ответ 2

Отрицательные знаменатели не являются стандартными и плохо обрабатываются. Если вы действительно в них нуждаетесь, вы можете изменить строку outpout, заданную красивой функцией:

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

Ответ 3

Я не совсем понял, что вы ищете, но я думаю, что я имел дело с чем-то подобным некоторое время назад. Я получил список понятий и использовал это для печати. Вы можете найти это полезным.

    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)