2 A Printer for generating readable representation of most sympy classes.
5 from printer
import Printer
6 from sympy
.printing
.precedence
import precedence
, PRECEDENCE
7 from sympy
.core
.basic
import S
8 from sympy
.core
.numbers
import One
, Rational
9 from sympy
.core
.power
import Pow
10 from sympy
.core
.symbol
import Symbol
, Wild
11 from sympy
.core
.basic
import Basic
13 import sympy
.mpmath
.lib
as mlib
15 class StrPrinter(Printer
):
16 def parenthesize(self
, item
, level
):
17 if precedence(item
) <= level
:
18 return "(%s)"%self
._print
(item
)
20 return self
._print
(item
)
22 def stringify(self
, args
, sep
, level
=0):
23 return sep
.join([self
.parenthesize(item
, level
) for item
in args
])
25 def emptyPrinter(self
, expr
):
26 if isinstance(expr
, str):
28 elif isinstance(expr
, Basic
):
29 if hasattr(expr
, args
):
36 def _print_Add(self
, expr
):
37 args
= list(expr
.args
)
39 # Now we need to sort the factors in Add, which are in "rest". Any
40 # ordering is fine, but some ordering looks better and some looks bad.
41 # This particular solution is slow, but it ensures a sane ordering. It
42 # can of course be improved:
44 args
.sort(Basic
._compare
_pretty
)
45 PREC
= precedence(expr
)
54 if precedence(term
) < PREC
:
55 l
.extend([sign
, "(%s)"%t
])
61 return sign
+ ' '.join(l
)
63 def _print_Basic(self
, expr
):
64 l
= [self
._print
(o
) for o
in expr
.args
]
65 return expr
.__class
__.__name
__ + "(%s)"%", ".join(l
)
67 def _print_Catalan(self
, expr
):
70 def _print_ComplexInfinity(self
, expr
):
73 def _print_Derivative(self
, expr
):
74 return 'D(%s)'%", ".join(map(self
._print
, expr
.args
))
76 def _print_dict(self
, expr
):
78 keys
.sort( Basic
.compare_pretty
)
82 item
= "%s: %s" % (self
._print
(key
), self
._print
(expr
[key
]))
85 return "{%s}"%", ".join(items
)
87 def _print_Dummy(self
, expr
):
88 return '_' + expr
.name
90 def _print_EulerGamma(self
, expr
):
93 def _print_Exp1(self
, expr
):
96 def _print_Factorial(self
, expr
):
97 return "%s!" % self
.parenthesize(expr
.args
[0], PRECEDENCE
["Pow"])
99 def _print_Function(self
, expr
):
100 return expr
.func
.__name
__ + "(%s)"%self
.stringify(expr
.args
, ", ")
102 def _print_GeometryEntity(self
, expr
):
103 # GeometryEntity is special -- it's base is tuple
106 def _print_GoldenRatio(self
, expr
):
109 def _print_ImaginaryUnit(self
, expr
):
112 def _print_Infinity(self
, expr
):
115 def _print_Integer(self
, expr
):
116 return self
._print
(expr
.p
)
118 def _print_Integral(self
, expr
):
122 return self
._print
(x
)
124 return self
._print
((x
,) + ab
)
125 L
= ', '.join([_xab_tostr(l
) for l
in expr
.limits
])
126 return 'Integral(%s, %s)' % (self
._print
(expr
.function
), L
)
128 def _print_Interval(self
, expr
):
129 return '[%s, %s]'%(expr
.start
, expr
.end
)
131 def _print_Limit(self
, expr
):
132 e
, z
, z0
, dir = expr
.args
134 return "Limit(%s, %s, %s)" % (e
, z
, z0
)
136 return "Limit(%s, %s, %s, dir='%s')" % (e
, z
, z0
, dir)
138 def _print_list(self
, expr
):
139 return "[%s]"%self
.stringify(expr
, ", ")
141 def _print_Matrix(self
, expr
):
142 return expr
._format
_str
(lambda elem
: self
._print
(elem
))
144 def _print_Mul(self
, expr
):
145 coeff
, terms
= expr
.as_coeff_terms()
146 if coeff
.is_negative
:
148 if coeff
is not S
.One
:
149 terms
= (coeff
,) + terms
152 terms
= (coeff
,) + terms
155 a
= [] # items in the numerator
156 b
= [] # items that are in the denominator (if any)
158 # Gather terms for numerator/denominator
160 if item
.is_Pow
and item
.exp
.is_Rational
and item
.exp
.is_negative
:
161 b
.append(Pow(item
.base
, -item
.exp
))
162 elif item
.is_Rational
:
164 a
.append(Rational(item
.p
))
166 b
.append(Rational(item
.q
))
173 a_str
= map(lambda x
:self
.parenthesize(x
, precedence(expr
)), a
)
174 b_str
= map(lambda x
:self
.parenthesize(x
, precedence(expr
)), b
)
177 return sign
+ '*'.join(a_str
)
179 if len(a
)==1 and not (a
[0].is_Atom
or a
[0].is_Add
):
180 return sign
+ "1/%s*"%b_str
[0] + '*'.join(a_str
)
182 return sign
+ '*'.join(a_str
) + "/%s"%b_str
[0]
184 return sign
+ '*'.join(a_str
) + "/(%s)"%'*'.join(b_str
)
186 def _print_NaN(self
, expr
):
189 def _print_NegativeInfinity(self
, expr
):
192 def _print_NegativeOne(self
, expr
):
195 def _print_Normal(self
, expr
):
196 return "Normal(%s, %s)"%(expr
.mu
, expr
.sigma
)
198 def _print_One(self
, expr
):
201 def _print_Order(self
, expr
):
202 if len(expr
.symbols
) <= 1:
203 return 'O(%s)'%self
._print
(expr
.expr
)
205 return 'O(%s)'%self
.stringify(expr
.args
, ', ', 0)
207 def _print_PDF(self
, expr
):
208 return 'PDF(%s, (%s, %s, %s))' % \
209 (self
._print
(expr
.pdf
.args
[1]), self
._print
(expr
.pdf
.args
[0]), \
210 self
._print
(expr
.domain
[0]), self
._print
(expr
.domain
[1]))
212 def _print_Pi(self
, expr
):
215 def _print_Poly(self
, expr
):
216 terms
, symbols
= [], [ self
._print
(s
) for s
in expr
.symbols
]
218 for coeff
, monom
in expr
.iter_terms():
221 for i
, exp
in enumerate(monom
):
224 s_monom
.append(symbols
[i
])
226 s_monom
.append(symbols
[i
] + "**%d" % exp
)
228 s_monom
= "*".join(s_monom
)
232 s_coeff
= "(" + self
._print
(coeff
) + ")"
234 s_coeff
= self
._print
(coeff
)
236 if s_monom
and abs(coeff
) is S
.One
:
237 if coeff
.is_negative
:
238 terms
.extend(['-', s_monom
])
240 terms
.extend(['+', s_monom
])
244 s_coeff
= self
._print
(coeff
)
249 s_term
= s_coeff
+ "*" + s_monom
251 if s_term
.startswith('-'):
252 terms
.extend(['-', s_term
[1:]])
254 terms
.extend(['+', s_term
])
256 if terms
[0] in ['-', '+']:
257 modifier
= terms
.pop(0)
260 terms
[0] = '-' + terms
[0]
262 format
= expr
.__class
__.__name
__ + "(%s, %s"
264 if expr
.is_multivariate
and expr
.order
!= 'grlex':
265 format
+= ", order='%s')" % expr
.order
269 return format
% (' '.join(terms
), ', '.join(symbols
))
271 def _print_Polynomial(self
, expr
):
272 return self
._print
(expr
.sympy_expr
)
274 def _print_Pow(self
, expr
):
275 PREC
= precedence(expr
)
276 if expr
.exp
is S
.NegativeOne
:
277 return '1/%s'%(self
.parenthesize(expr
.base
, PREC
))
279 return '%s**%s'%(self
.parenthesize(expr
.base
, PREC
),
280 self
.parenthesize(expr
.exp
, PREC
))
282 def _print_Rational(self
, expr
):
283 return '%s/%s'%(expr
.p
, expr
.q
)
285 def _print_Real(self
, expr
):
290 dps
= mlib
.prec_to_dps(expr
._prec
)
291 return mlib
.to_str(expr
._mpf
_, dps
, strip_zeros
=False)
293 def _print_Relational(self
, expr
):
294 return '%s %s %s'%(self
.parenthesize(expr
.lhs
, precedence(expr
)),
296 self
.parenthesize(expr
.rhs
, precedence(expr
)))
298 def _print_RootOf(self
, expr
):
299 poly
= self
._print
(expr
.poly
)
300 return "RootOf(%s, index=%d)" % \
301 (poly
[1+poly
.index("("):-1], expr
.index
)
303 def _print_RootsOf(self
, expr
):
304 poly
= self
._print
(expr
.poly
)
305 return "RootsOf(" + poly
[1+poly
.index("("):]
307 def _print_RootSum(self
, expr
):
308 func
= self
._print
(expr
.function
)
309 poly
= self
._print
(expr
.roots
.poly
)
310 return "RootSum(%s, %s)" % \
311 (func
, poly
[1+poly
.index("("):-1])
313 def _print_Sample(self
, expr
):
314 return "Sample([%s])"%self
.stringify(expr
, ", ", 0)
316 def __print_set(self
, expr
):
318 items
.sort( Basic
.compare_pretty
)
320 args
= ', '.join(self
._print
(item
) for item
in items
)
323 return '%s(%s)' % (type(expr
).__name
__, args
)
325 _print_set
= __print_set
326 _print_frozenset
= __print_set
328 def _print_SMatrix(self
, expr
):
329 return self
._print
(expr
.toMatrix())
331 def _print_Sum(self
, expr
):
332 return 'Sum(%s, (%s))'%(self
._print
(expr
.function
), self
.stringify(expr
.limits
[0], ', '))
334 def _print_Sum2(self
, expr
):
335 return "Sum2(%r, (%r, %r, %r))" % (expr
.f
, expr
.i
, expr
.a
, expr
.b
)
337 def _print_Symbol(self
, expr
):
340 def _print_tuple(self
, expr
):
342 return "(%s,)"%self
._print
(expr
[0])
344 return "(%s)"%self
.stringify(expr
, ", ")
346 def _print_Uniform(self
, expr
):
347 return "Uniform(%s, %s)"%(expr
.a
, expr
.b
)
349 def _print_Unit(self
, expr
):
352 def _print_Wild(self
, expr
):
353 return expr
.name
+ '_'
355 def _print_WildFunction(self
, expr
):
356 return expr
.name
+ '_'
358 def _print_Zero(self
, expr
):
363 """return expr in str form"""
371 class StrReprPrinter(StrPrinter
):
372 """(internal) -- see sstrrepr"""
374 def _print_basestring(self
, s
):
378 """return expr in mixed str/repr form
380 i.e. strings are returned in repr form with quotes, and everything else
381 is returned in str form.
383 This function could be useful for hooking into sys.displayhook