2015-05-12 10 views
13

Sto provando a stampare alcune divisioni con Sympy ma ho notato che non è stata allineata.Non allineato Simpatia della divisione di 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". 

Motivo/correzione per questo?

EDIT: ho fatto un sacco di reverse-engineering utilizzando inspect.getsource e inspect.getsourcefile ma non ha davvero aiutare alla fine.

Pretty Printing in Sympy sembra fare affidamento sulla Prettyprinter di Jurjen Bos.

import sympy 

from sympy.printing.pretty.stringpict import * 

sympy.init_printing(use_unicode=True) 

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

in modo che non visualizzare allineati, ma non posso farlo da utilizzare unicode.

Il PrettyPrinter viene chiamata dal file sympy/printing/pretty/pretty.py nel metodo PrettyPrinter._print_Mul che semplicemente return prettyForm.__mul__(*a)/prettyForm.__mul__(*b) con, ho pensato, e ab semplicemente essere ['-1'] e ['-5'], ma che non avrebbe funzionato.

+0

Confermo questo comportamento. Sembra che si verifichi quando sia il numeratore che il denominatore sono valori a una cifra negativa. – dlask

+2

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

risposta

2

scoperto dove la parte strana è venuta da:

stringpict.py linea 417:

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

Questo è stato fatto solo per il numeratore. Aggiunge uno spazio dopo il numeratore se il numeratore è negativo ... Strano!

Non sono sicuro che possa esserci un errore diverso dalla modifica diretta del file. Ho intenzione di segnalarlo su Github.

Grazie a tutti per il vostro aiuto e il vostro suggerimento.

PS: Alla fine, ho utilizzato pdb per aiutarmi a eseguire il debug e capire cosa stava effettivamente uscendo!

EDIT: Hotfix se non/possibile non si vuole modificare il codice sorgente:

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 

Io ho semplicemente copiato la funzione dal codice sorgente e rimosso la linea incriminata.

Il possibile miglioramento potrebbe essere la functools.wraps la nuova funzione con quella originale.

0

Non ero abbastanza sicuro di quello che stai cercando, ma penso che mi stavo occupando di qualcosa di simile qualche tempo fa. Ho ottenuto una lista di comprensione e ho usato questo per la stampa. Potresti trovarlo utile.

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

I denominatori negativi non sono standard e mal gestiti. Se davvero bisogno di loro, è possibile modificare la stringa outpout data dalla funzione abbastanza:

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) 

Questa estendere il bar e il numeratore di un'unità per denominatori negativi. Nessuna garanzia di robustezza su grandi espressioni.

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

"Sporco" hack ma, questo è un (ottimo) inizio !, penso che potremmo anche provare a renderlo più "intelligente" approssimando la dimensione di entrambe le parti e prova ad aggiustare se davvero ne abbiamo bisogno. – JeromeJ