2015-05-12 8 views
13

Próbuję ładnie wydrukować niektóre działy za pomocą Sympy, ale zauważyłem, że nie są wyrównane.Niewyrównana sympatyczne sympatyczne podszycie 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". 

Powód/poprawka w tym?

EDIT: Zrobiłem dużo reverse-engineering, używając inspect.getsource i inspect.getsourcefile ale tak naprawdę nie angażować się w końcu.

Pretty Drukowanie w Sympy wydaje się polegać na Prettyprinter przez Jurjen Bos.

import sympy 

from sympy.printing.pretty.stringpict import * 

sympy.init_printing(use_unicode=True) 

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

Wyświetlane wyrównanie, ale nie mogę go użyć do unikodu.

PrettyPrinter jest wywoływana z pliku sympy/printing/pretty/pretty.py w metodzie PrettyPrinter._print_Mul który po prostu return prettyForm.__mul__(*a)/prettyForm.__mul__(*b) z pomyślałem a i b prostu będąc ['-1'] i ['-5'] ale to nie będzie działać.

+0

Potwierdzam to zachowanie. Wydaje się, że występuje, gdy licznik i mianownik są ujemnymi wartościami jednocyfrowymi. – dlask

+2

https://github.com/sympy/sympy/issues/9450 – JeromeJ

Odpowiedz

2

dowiedział się, gdzie dziwne część pochodzi z:

stringpict.py linii 417:

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

ta jest wykonywana tylko dla liczniku. Dodaje spację po liczniku, jeśli licznik jest ujemny ... Dziwne!

Nie jestem pewien, czy może istnieć ustalona inna opcja niż bezpośrednia edycja pliku. Zamierzam to zgłosić na Github.

Dziękuję wszystkim za pomoc i sugestię.

PS: W końcu użyłem pdb mi pomóc debug i dowiedzieć się, co faktycznie dzieje się!

EDIT: poprawki, jeśli nie możesz/nie chcesz edytować kod źródłowy:

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 

po prostu kopiowane z funkcji z kodu źródłowego i usunięciu zakwestionowanych linię.

Możliwe ulepszenie może być functools.wraps nowa funkcja z oryginalną.

0

Nie byłem całkiem pewien, czego szukasz, ale myślę, że miałem do czynienia z czymś podobnym jakiś czas temu. Mam listę zrozumiałą i użyłem jej do drukowania. Może się przydać.

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) 
1

Nieliniowe mianowniki nie są standardowe i źle obsługiwane. Jeśli naprawdę ich potrzebują, można zmodyfikować ciąg outpout podane przez funkcję ładna:

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) 

To rozszerzenie bar i licznik z jednej jednostki do negatywnych mianowników. Brak gwarancji odporności na duże wyrażenia.

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

"Dirty" hack, ale to (świetny) początek !, myślę, że moglibyśmy nawet spróbować uczynić go bardziej "sprytnym" poprzez przybliżenie rozmiaru obu części i postaraj się dostosować, jeśli naprawdę tego potrzebujemy. – JeromeJ

Powiązane problemy