Не выровненный 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']
, но это не будет работа.
Ответы
Ответ 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)