1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030 |
- """
- A Printer for generating readable representation of most SymPy classes.
- """
- from typing import Any, Dict as tDict
- from sympy.core import S, Rational, Pow, Basic, Mul, Number
- from sympy.core.mul import _keep_coeff
- from sympy.core.relational import Relational
- from sympy.core.sorting import default_sort_key
- from sympy.core.sympify import SympifyError
- from sympy.sets.sets import FiniteSet
- from sympy.utilities.iterables import sift
- from .precedence import precedence, PRECEDENCE
- from .printer import Printer, print_function
- from mpmath.libmp import prec_to_dps, to_str as mlib_to_str
- class StrPrinter(Printer):
- printmethod = "_sympystr"
- _default_settings = {
- "order": None,
- "full_prec": "auto",
- "sympy_integers": False,
- "abbrev": False,
- "perm_cyclic": True,
- "min": None,
- "max": None,
- } # type: tDict[str, Any]
- _relationals = dict() # type: tDict[str, str]
- def parenthesize(self, item, level, strict=False):
- if (precedence(item) < level) or ((not strict) and precedence(item) <= level):
- return "(%s)" % self._print(item)
- else:
- return self._print(item)
- def stringify(self, args, sep, level=0):
- return sep.join([self.parenthesize(item, level) for item in args])
- def emptyPrinter(self, expr):
- if isinstance(expr, str):
- return expr
- elif isinstance(expr, Basic):
- return repr(expr)
- else:
- return str(expr)
- def _print_Add(self, expr, order=None):
- terms = self._as_ordered_terms(expr, order=order)
- PREC = precedence(expr)
- l = []
- for term in terms:
- t = self._print(term)
- if t.startswith('-'):
- sign = "-"
- t = t[1:]
- else:
- sign = "+"
- if precedence(term) < PREC:
- l.extend([sign, "(%s)" % t])
- else:
- l.extend([sign, t])
- sign = l.pop(0)
- if sign == '+':
- sign = ""
- return sign + ' '.join(l)
- def _print_BooleanTrue(self, expr):
- return "True"
- def _print_BooleanFalse(self, expr):
- return "False"
- def _print_Not(self, expr):
- return '~%s' %(self.parenthesize(expr.args[0],PRECEDENCE["Not"]))
- def _print_And(self, expr):
- args = list(expr.args)
- for j, i in enumerate(args):
- if isinstance(i, Relational) and (
- i.canonical.rhs is S.NegativeInfinity):
- args.insert(0, args.pop(j))
- return self.stringify(args, " & ", PRECEDENCE["BitwiseAnd"])
- def _print_Or(self, expr):
- return self.stringify(expr.args, " | ", PRECEDENCE["BitwiseOr"])
- def _print_Xor(self, expr):
- return self.stringify(expr.args, " ^ ", PRECEDENCE["BitwiseXor"])
- def _print_AppliedPredicate(self, expr):
- return '%s(%s)' % (
- self._print(expr.function), self.stringify(expr.arguments, ", "))
- def _print_Basic(self, expr):
- l = [self._print(o) for o in expr.args]
- return expr.__class__.__name__ + "(%s)" % ", ".join(l)
- def _print_BlockMatrix(self, B):
- if B.blocks.shape == (1, 1):
- self._print(B.blocks[0, 0])
- return self._print(B.blocks)
- def _print_Catalan(self, expr):
- return 'Catalan'
- def _print_ComplexInfinity(self, expr):
- return 'zoo'
- def _print_ConditionSet(self, s):
- args = tuple([self._print(i) for i in (s.sym, s.condition)])
- if s.base_set is S.UniversalSet:
- return 'ConditionSet(%s, %s)' % args
- args += (self._print(s.base_set),)
- return 'ConditionSet(%s, %s, %s)' % args
- def _print_Derivative(self, expr):
- dexpr = expr.expr
- dvars = [i[0] if i[1] == 1 else i for i in expr.variable_count]
- return 'Derivative(%s)' % ", ".join(map(lambda arg: self._print(arg), [dexpr] + dvars))
- def _print_dict(self, d):
- keys = sorted(d.keys(), key=default_sort_key)
- items = []
- for key in keys:
- item = "%s: %s" % (self._print(key), self._print(d[key]))
- items.append(item)
- return "{%s}" % ", ".join(items)
- def _print_Dict(self, expr):
- return self._print_dict(expr)
- def _print_RandomDomain(self, d):
- if hasattr(d, 'as_boolean'):
- return 'Domain: ' + self._print(d.as_boolean())
- elif hasattr(d, 'set'):
- return ('Domain: ' + self._print(d.symbols) + ' in ' +
- self._print(d.set))
- else:
- return 'Domain on ' + self._print(d.symbols)
- def _print_Dummy(self, expr):
- return '_' + expr.name
- def _print_EulerGamma(self, expr):
- return 'EulerGamma'
- def _print_Exp1(self, expr):
- return 'E'
- def _print_ExprCondPair(self, expr):
- return '(%s, %s)' % (self._print(expr.expr), self._print(expr.cond))
- def _print_Function(self, expr):
- return expr.func.__name__ + "(%s)" % self.stringify(expr.args, ", ")
- def _print_GoldenRatio(self, expr):
- return 'GoldenRatio'
- def _print_Heaviside(self, expr):
- # Same as _print_Function but uses pargs to suppress default 1/2 for
- # 2nd args
- return expr.func.__name__ + "(%s)" % self.stringify(expr.pargs, ", ")
- def _print_TribonacciConstant(self, expr):
- return 'TribonacciConstant'
- def _print_ImaginaryUnit(self, expr):
- return 'I'
- def _print_Infinity(self, expr):
- return 'oo'
- def _print_Integral(self, expr):
- def _xab_tostr(xab):
- if len(xab) == 1:
- return self._print(xab[0])
- else:
- return self._print((xab[0],) + tuple(xab[1:]))
- L = ', '.join([_xab_tostr(l) for l in expr.limits])
- return 'Integral(%s, %s)' % (self._print(expr.function), L)
- def _print_Interval(self, i):
- fin = 'Interval{m}({a}, {b})'
- a, b, l, r = i.args
- if a.is_infinite and b.is_infinite:
- m = ''
- elif a.is_infinite and not r:
- m = ''
- elif b.is_infinite and not l:
- m = ''
- elif not l and not r:
- m = ''
- elif l and r:
- m = '.open'
- elif l:
- m = '.Lopen'
- else:
- m = '.Ropen'
- return fin.format(**{'a': a, 'b': b, 'm': m})
- def _print_AccumulationBounds(self, i):
- return "AccumBounds(%s, %s)" % (self._print(i.min),
- self._print(i.max))
- def _print_Inverse(self, I):
- return "%s**(-1)" % self.parenthesize(I.arg, PRECEDENCE["Pow"])
- def _print_Lambda(self, obj):
- expr = obj.expr
- sig = obj.signature
- if len(sig) == 1 and sig[0].is_symbol:
- sig = sig[0]
- return "Lambda(%s, %s)" % (self._print(sig), self._print(expr))
- def _print_LatticeOp(self, expr):
- args = sorted(expr.args, key=default_sort_key)
- return expr.func.__name__ + "(%s)" % ", ".join(self._print(arg) for arg in args)
- def _print_Limit(self, expr):
- e, z, z0, dir = expr.args
- if str(dir) == "+":
- return "Limit(%s, %s, %s)" % tuple(map(self._print, (e, z, z0)))
- else:
- return "Limit(%s, %s, %s, dir='%s')" % tuple(map(self._print,
- (e, z, z0, dir)))
- def _print_list(self, expr):
- return "[%s]" % self.stringify(expr, ", ")
- def _print_List(self, expr):
- return self._print_list(expr)
- def _print_MatrixBase(self, expr):
- return expr._format_str(self)
- def _print_MatrixElement(self, expr):
- return self.parenthesize(expr.parent, PRECEDENCE["Atom"], strict=True) \
- + '[%s, %s]' % (self._print(expr.i), self._print(expr.j))
- def _print_MatrixSlice(self, expr):
- def strslice(x, dim):
- x = list(x)
- if x[2] == 1:
- del x[2]
- if x[0] == 0:
- x[0] = ''
- if x[1] == dim:
- x[1] = ''
- return ':'.join(map(lambda arg: self._print(arg), x))
- return (self.parenthesize(expr.parent, PRECEDENCE["Atom"], strict=True) + '[' +
- strslice(expr.rowslice, expr.parent.rows) + ', ' +
- strslice(expr.colslice, expr.parent.cols) + ']')
- def _print_DeferredVector(self, expr):
- return expr.name
- def _print_Mul(self, expr):
- prec = precedence(expr)
- # Check for unevaluated Mul. In this case we need to make sure the
- # identities are visible, multiple Rational factors are not combined
- # etc so we display in a straight-forward form that fully preserves all
- # args and their order.
- args = expr.args
- if args[0] is S.One or any(
- isinstance(a, Number) or
- a.is_Pow and all(ai.is_Integer for ai in a.args)
- for a in args[1:]):
- d, n = sift(args, lambda x:
- isinstance(x, Pow) and bool(x.exp.as_coeff_Mul()[0] < 0),
- binary=True)
- for i, di in enumerate(d):
- if di.exp.is_Number:
- e = -di.exp
- else:
- dargs = list(di.exp.args)
- dargs[0] = -dargs[0]
- e = Mul._from_args(dargs)
- d[i] = Pow(di.base, e, evaluate=False) if e - 1 else di.base
- pre = []
- # don't parenthesize first factor if negative
- if n and n[0].could_extract_minus_sign():
- pre = [str(n.pop(0))]
- nfactors = pre + [self.parenthesize(a, prec, strict=False)
- for a in n]
- if not nfactors:
- nfactors = ['1']
- # don't parenthesize first of denominator unless singleton
- if len(d) > 1 and d[0].could_extract_minus_sign():
- pre = [str(d.pop(0))]
- else:
- pre = []
- dfactors = pre + [self.parenthesize(a, prec, strict=False)
- for a in d]
- n = '*'.join(nfactors)
- d = '*'.join(dfactors)
- if len(dfactors) > 1:
- return '%s/(%s)' % (n, d)
- elif dfactors:
- return '%s/%s' % (n, d)
- return n
- c, e = expr.as_coeff_Mul()
- if c < 0:
- expr = _keep_coeff(-c, e)
- sign = "-"
- else:
- sign = ""
- a = [] # items in the numerator
- b = [] # items that are in the denominator (if any)
- pow_paren = [] # Will collect all pow with more than one base element and exp = -1
- if self.order not in ('old', 'none'):
- args = expr.as_ordered_factors()
- else:
- # use make_args in case expr was something like -x -> x
- args = Mul.make_args(expr)
- # Gather args for numerator/denominator
- def apow(i):
- b, e = i.as_base_exp()
- eargs = list(Mul.make_args(e))
- if eargs[0] is S.NegativeOne:
- eargs = eargs[1:]
- else:
- eargs[0] = -eargs[0]
- e = Mul._from_args(eargs)
- if isinstance(i, Pow):
- return i.func(b, e, evaluate=False)
- return i.func(e, evaluate=False)
- for item in args:
- if (item.is_commutative and
- isinstance(item, Pow) and
- bool(item.exp.as_coeff_Mul()[0] < 0)):
- if item.exp is not S.NegativeOne:
- b.append(apow(item))
- else:
- if (len(item.args[0].args) != 1 and
- isinstance(item.base, (Mul, Pow))):
- # To avoid situations like #14160
- pow_paren.append(item)
- b.append(item.base)
- elif item.is_Rational and item is not S.Infinity:
- if item.p != 1:
- a.append(Rational(item.p))
- if item.q != 1:
- b.append(Rational(item.q))
- else:
- a.append(item)
- a = a or [S.One]
- a_str = [self.parenthesize(x, prec, strict=False) for x in a]
- b_str = [self.parenthesize(x, prec, strict=False) for x in b]
- # To parenthesize Pow with exp = -1 and having more than one Symbol
- for item in pow_paren:
- if item.base in b:
- b_str[b.index(item.base)] = "(%s)" % b_str[b.index(item.base)]
- if not b:
- return sign + '*'.join(a_str)
- elif len(b) == 1:
- return sign + '*'.join(a_str) + "/" + b_str[0]
- else:
- return sign + '*'.join(a_str) + "/(%s)" % '*'.join(b_str)
- def _print_MatMul(self, expr):
- c, m = expr.as_coeff_mmul()
- sign = ""
- if c.is_number:
- re, im = c.as_real_imag()
- if im.is_zero and re.is_negative:
- expr = _keep_coeff(-c, m)
- sign = "-"
- elif re.is_zero and im.is_negative:
- expr = _keep_coeff(-c, m)
- sign = "-"
- return sign + '*'.join(
- [self.parenthesize(arg, precedence(expr)) for arg in expr.args]
- )
- def _print_ElementwiseApplyFunction(self, expr):
- return "{}.({})".format(
- expr.function,
- self._print(expr.expr),
- )
- def _print_NaN(self, expr):
- return 'nan'
- def _print_NegativeInfinity(self, expr):
- return '-oo'
- def _print_Order(self, expr):
- if not expr.variables or all(p is S.Zero for p in expr.point):
- if len(expr.variables) <= 1:
- return 'O(%s)' % self._print(expr.expr)
- else:
- return 'O(%s)' % self.stringify((expr.expr,) + expr.variables, ', ', 0)
- else:
- return 'O(%s)' % self.stringify(expr.args, ', ', 0)
- def _print_Ordinal(self, expr):
- return expr.__str__()
- def _print_Cycle(self, expr):
- return expr.__str__()
- def _print_Permutation(self, expr):
- from sympy.combinatorics.permutations import Permutation, Cycle
- from sympy.utilities.exceptions import sympy_deprecation_warning
- perm_cyclic = Permutation.print_cyclic
- if perm_cyclic is not None:
- sympy_deprecation_warning(
- f"""
- Setting Permutation.print_cyclic is deprecated. Instead use
- init_printing(perm_cyclic={perm_cyclic}).
- """,
- deprecated_since_version="1.6",
- active_deprecations_target="deprecated-permutation-print_cyclic",
- stacklevel=7,
- )
- else:
- perm_cyclic = self._settings.get("perm_cyclic", True)
- if perm_cyclic:
- if not expr.size:
- return '()'
- # before taking Cycle notation, see if the last element is
- # a singleton and move it to the head of the string
- s = Cycle(expr)(expr.size - 1).__repr__()[len('Cycle'):]
- last = s.rfind('(')
- if not last == 0 and ',' not in s[last:]:
- s = s[last:] + s[:last]
- s = s.replace(',', '')
- return s
- else:
- s = expr.support()
- if not s:
- if expr.size < 5:
- return 'Permutation(%s)' % self._print(expr.array_form)
- return 'Permutation([], size=%s)' % self._print(expr.size)
- trim = self._print(expr.array_form[:s[-1] + 1]) + ', size=%s' % self._print(expr.size)
- use = full = self._print(expr.array_form)
- if len(trim) < len(full):
- use = trim
- return 'Permutation(%s)' % use
- def _print_Subs(self, obj):
- expr, old, new = obj.args
- if len(obj.point) == 1:
- old = old[0]
- new = new[0]
- return "Subs(%s, %s, %s)" % (
- self._print(expr), self._print(old), self._print(new))
- def _print_TensorIndex(self, expr):
- return expr._print()
- def _print_TensorHead(self, expr):
- return expr._print()
- def _print_Tensor(self, expr):
- return expr._print()
- def _print_TensMul(self, expr):
- # prints expressions like "A(a)", "3*A(a)", "(1+x)*A(a)"
- sign, args = expr._get_args_for_traditional_printer()
- return sign + "*".join(
- [self.parenthesize(arg, precedence(expr)) for arg in args]
- )
- def _print_TensAdd(self, expr):
- return expr._print()
- def _print_ArraySymbol(self, expr):
- return self._print(expr.name)
- def _print_ArrayElement(self, expr):
- return "%s[%s]" % (
- self.parenthesize(expr.name, PRECEDENCE["Func"], True), ", ".join([self._print(i) for i in expr.indices]))
- def _print_PermutationGroup(self, expr):
- p = [' %s' % self._print(a) for a in expr.args]
- return 'PermutationGroup([\n%s])' % ',\n'.join(p)
- def _print_Pi(self, expr):
- return 'pi'
- def _print_PolyRing(self, ring):
- return "Polynomial ring in %s over %s with %s order" % \
- (", ".join(map(lambda rs: self._print(rs), ring.symbols)),
- self._print(ring.domain), self._print(ring.order))
- def _print_FracField(self, field):
- return "Rational function field in %s over %s with %s order" % \
- (", ".join(map(lambda fs: self._print(fs), field.symbols)),
- self._print(field.domain), self._print(field.order))
- def _print_FreeGroupElement(self, elm):
- return elm.__str__()
- def _print_GaussianElement(self, poly):
- return "(%s + %s*I)" % (poly.x, poly.y)
- def _print_PolyElement(self, poly):
- return poly.str(self, PRECEDENCE, "%s**%s", "*")
- def _print_FracElement(self, frac):
- if frac.denom == 1:
- return self._print(frac.numer)
- else:
- numer = self.parenthesize(frac.numer, PRECEDENCE["Mul"], strict=True)
- denom = self.parenthesize(frac.denom, PRECEDENCE["Atom"], strict=True)
- return numer + "/" + denom
- def _print_Poly(self, expr):
- ATOM_PREC = PRECEDENCE["Atom"] - 1
- terms, gens = [], [ self.parenthesize(s, ATOM_PREC) for s in expr.gens ]
- for monom, coeff in expr.terms():
- s_monom = []
- for i, e in enumerate(monom):
- if e > 0:
- if e == 1:
- s_monom.append(gens[i])
- else:
- s_monom.append(gens[i] + "**%d" % e)
- s_monom = "*".join(s_monom)
- if coeff.is_Add:
- if s_monom:
- s_coeff = "(" + self._print(coeff) + ")"
- else:
- s_coeff = self._print(coeff)
- else:
- if s_monom:
- if coeff is S.One:
- terms.extend(['+', s_monom])
- continue
- if coeff is S.NegativeOne:
- terms.extend(['-', s_monom])
- continue
- s_coeff = self._print(coeff)
- if not s_monom:
- s_term = s_coeff
- else:
- s_term = s_coeff + "*" + s_monom
- if s_term.startswith('-'):
- terms.extend(['-', s_term[1:]])
- else:
- terms.extend(['+', s_term])
- if terms[0] in ('-', '+'):
- modifier = terms.pop(0)
- if modifier == '-':
- terms[0] = '-' + terms[0]
- format = expr.__class__.__name__ + "(%s, %s"
- from sympy.polys.polyerrors import PolynomialError
- try:
- format += ", modulus=%s" % expr.get_modulus()
- except PolynomialError:
- format += ", domain='%s'" % expr.get_domain()
- format += ")"
- for index, item in enumerate(gens):
- if len(item) > 2 and (item[:1] == "(" and item[len(item) - 1:] == ")"):
- gens[index] = item[1:len(item) - 1]
- return format % (' '.join(terms), ', '.join(gens))
- def _print_UniversalSet(self, p):
- return 'UniversalSet'
- def _print_AlgebraicNumber(self, expr):
- if expr.is_aliased:
- return self._print(expr.as_poly().as_expr())
- else:
- return self._print(expr.as_expr())
- def _print_Pow(self, expr, rational=False):
- """Printing helper function for ``Pow``
- Parameters
- ==========
- rational : bool, optional
- If ``True``, it will not attempt printing ``sqrt(x)`` or
- ``x**S.Half`` as ``sqrt``, and will use ``x**(1/2)``
- instead.
- See examples for additional details
- Examples
- ========
- >>> from sympy import sqrt, StrPrinter
- >>> from sympy.abc import x
- How ``rational`` keyword works with ``sqrt``:
- >>> printer = StrPrinter()
- >>> printer._print_Pow(sqrt(x), rational=True)
- 'x**(1/2)'
- >>> printer._print_Pow(sqrt(x), rational=False)
- 'sqrt(x)'
- >>> printer._print_Pow(1/sqrt(x), rational=True)
- 'x**(-1/2)'
- >>> printer._print_Pow(1/sqrt(x), rational=False)
- '1/sqrt(x)'
- Notes
- =====
- ``sqrt(x)`` is canonicalized as ``Pow(x, S.Half)`` in SymPy,
- so there is no need of defining a separate printer for ``sqrt``.
- Instead, it should be handled here as well.
- """
- PREC = precedence(expr)
- if expr.exp is S.Half and not rational:
- return "sqrt(%s)" % self._print(expr.base)
- if expr.is_commutative:
- if -expr.exp is S.Half and not rational:
- # Note: Don't test "expr.exp == -S.Half" here, because that will
- # match -0.5, which we don't want.
- return "%s/sqrt(%s)" % tuple(map(lambda arg: self._print(arg), (S.One, expr.base)))
- if expr.exp is -S.One:
- # Similarly to the S.Half case, don't test with "==" here.
- return '%s/%s' % (self._print(S.One),
- self.parenthesize(expr.base, PREC, strict=False))
- e = self.parenthesize(expr.exp, PREC, strict=False)
- if self.printmethod == '_sympyrepr' and expr.exp.is_Rational and expr.exp.q != 1:
- # the parenthesized exp should be '(Rational(a, b))' so strip parens,
- # but just check to be sure.
- if e.startswith('(Rational'):
- return '%s**%s' % (self.parenthesize(expr.base, PREC, strict=False), e[1:-1])
- return '%s**%s' % (self.parenthesize(expr.base, PREC, strict=False), e)
- def _print_UnevaluatedExpr(self, expr):
- return self._print(expr.args[0])
- def _print_MatPow(self, expr):
- PREC = precedence(expr)
- return '%s**%s' % (self.parenthesize(expr.base, PREC, strict=False),
- self.parenthesize(expr.exp, PREC, strict=False))
- def _print_Integer(self, expr):
- if self._settings.get("sympy_integers", False):
- return "S(%s)" % (expr)
- return str(expr.p)
- def _print_Integers(self, expr):
- return 'Integers'
- def _print_Naturals(self, expr):
- return 'Naturals'
- def _print_Naturals0(self, expr):
- return 'Naturals0'
- def _print_Rationals(self, expr):
- return 'Rationals'
- def _print_Reals(self, expr):
- return 'Reals'
- def _print_Complexes(self, expr):
- return 'Complexes'
- def _print_EmptySet(self, expr):
- return 'EmptySet'
- def _print_EmptySequence(self, expr):
- return 'EmptySequence'
- def _print_int(self, expr):
- return str(expr)
- def _print_mpz(self, expr):
- return str(expr)
- def _print_Rational(self, expr):
- if expr.q == 1:
- return str(expr.p)
- else:
- if self._settings.get("sympy_integers", False):
- return "S(%s)/%s" % (expr.p, expr.q)
- return "%s/%s" % (expr.p, expr.q)
- def _print_PythonRational(self, expr):
- if expr.q == 1:
- return str(expr.p)
- else:
- return "%d/%d" % (expr.p, expr.q)
- def _print_Fraction(self, expr):
- if expr.denominator == 1:
- return str(expr.numerator)
- else:
- return "%s/%s" % (expr.numerator, expr.denominator)
- def _print_mpq(self, expr):
- if expr.denominator == 1:
- return str(expr.numerator)
- else:
- return "%s/%s" % (expr.numerator, expr.denominator)
- def _print_Float(self, expr):
- prec = expr._prec
- if prec < 5:
- dps = 0
- else:
- dps = prec_to_dps(expr._prec)
- if self._settings["full_prec"] is True:
- strip = False
- elif self._settings["full_prec"] is False:
- strip = True
- elif self._settings["full_prec"] == "auto":
- strip = self._print_level > 1
- low = self._settings["min"] if "min" in self._settings else None
- high = self._settings["max"] if "max" in self._settings else None
- rv = mlib_to_str(expr._mpf_, dps, strip_zeros=strip, min_fixed=low, max_fixed=high)
- if rv.startswith('-.0'):
- rv = '-0.' + rv[3:]
- elif rv.startswith('.0'):
- rv = '0.' + rv[2:]
- if rv.startswith('+'):
- # e.g., +inf -> inf
- rv = rv[1:]
- return rv
- def _print_Relational(self, expr):
- charmap = {
- "==": "Eq",
- "!=": "Ne",
- ":=": "Assignment",
- '+=': "AddAugmentedAssignment",
- "-=": "SubAugmentedAssignment",
- "*=": "MulAugmentedAssignment",
- "/=": "DivAugmentedAssignment",
- "%=": "ModAugmentedAssignment",
- }
- if expr.rel_op in charmap:
- return '%s(%s, %s)' % (charmap[expr.rel_op], self._print(expr.lhs),
- self._print(expr.rhs))
- return '%s %s %s' % (self.parenthesize(expr.lhs, precedence(expr)),
- self._relationals.get(expr.rel_op) or expr.rel_op,
- self.parenthesize(expr.rhs, precedence(expr)))
- def _print_ComplexRootOf(self, expr):
- return "CRootOf(%s, %d)" % (self._print_Add(expr.expr, order='lex'),
- expr.index)
- def _print_RootSum(self, expr):
- args = [self._print_Add(expr.expr, order='lex')]
- if expr.fun is not S.IdentityFunction:
- args.append(self._print(expr.fun))
- return "RootSum(%s)" % ", ".join(args)
- def _print_GroebnerBasis(self, basis):
- cls = basis.__class__.__name__
- exprs = [self._print_Add(arg, order=basis.order) for arg in basis.exprs]
- exprs = "[%s]" % ", ".join(exprs)
- gens = [ self._print(gen) for gen in basis.gens ]
- domain = "domain='%s'" % self._print(basis.domain)
- order = "order='%s'" % self._print(basis.order)
- args = [exprs] + gens + [domain, order]
- return "%s(%s)" % (cls, ", ".join(args))
- def _print_set(self, s):
- items = sorted(s, key=default_sort_key)
- args = ', '.join(self._print(item) for item in items)
- if not args:
- return "set()"
- return '{%s}' % args
- def _print_FiniteSet(self, s):
- items = sorted(s, key=default_sort_key)
- args = ', '.join(self._print(item) for item in items)
- if any(item.has(FiniteSet) for item in items):
- return 'FiniteSet({})'.format(args)
- return '{{{}}}'.format(args)
- def _print_Partition(self, s):
- items = sorted(s, key=default_sort_key)
- args = ', '.join(self._print(arg) for arg in items)
- return 'Partition({})'.format(args)
- def _print_frozenset(self, s):
- if not s:
- return "frozenset()"
- return "frozenset(%s)" % self._print_set(s)
- def _print_Sum(self, expr):
- def _xab_tostr(xab):
- if len(xab) == 1:
- return self._print(xab[0])
- else:
- return self._print((xab[0],) + tuple(xab[1:]))
- L = ', '.join([_xab_tostr(l) for l in expr.limits])
- return 'Sum(%s, %s)' % (self._print(expr.function), L)
- def _print_Symbol(self, expr):
- return expr.name
- _print_MatrixSymbol = _print_Symbol
- _print_RandomSymbol = _print_Symbol
- def _print_Identity(self, expr):
- return "I"
- def _print_ZeroMatrix(self, expr):
- return "0"
- def _print_OneMatrix(self, expr):
- return "1"
- def _print_Predicate(self, expr):
- return "Q.%s" % expr.name
- def _print_str(self, expr):
- return str(expr)
- def _print_tuple(self, expr):
- if len(expr) == 1:
- return "(%s,)" % self._print(expr[0])
- else:
- return "(%s)" % self.stringify(expr, ", ")
- def _print_Tuple(self, expr):
- return self._print_tuple(expr)
- def _print_Transpose(self, T):
- return "%s.T" % self.parenthesize(T.arg, PRECEDENCE["Pow"])
- def _print_Uniform(self, expr):
- return "Uniform(%s, %s)" % (self._print(expr.a), self._print(expr.b))
- def _print_Quantity(self, expr):
- if self._settings.get("abbrev", False):
- return "%s" % expr.abbrev
- return "%s" % expr.name
- def _print_Quaternion(self, expr):
- s = [self.parenthesize(i, PRECEDENCE["Mul"], strict=True) for i in expr.args]
- a = [s[0]] + [i+"*"+j for i, j in zip(s[1:], "ijk")]
- return " + ".join(a)
- def _print_Dimension(self, expr):
- return str(expr)
- def _print_Wild(self, expr):
- return expr.name + '_'
- def _print_WildFunction(self, expr):
- return expr.name + '_'
- def _print_WildDot(self, expr):
- return expr.name
- def _print_WildPlus(self, expr):
- return expr.name
- def _print_WildStar(self, expr):
- return expr.name
- def _print_Zero(self, expr):
- if self._settings.get("sympy_integers", False):
- return "S(0)"
- return "0"
- def _print_DMP(self, p):
- try:
- if p.ring is not None:
- # TODO incorporate order
- return self._print(p.ring.to_sympy(p))
- except SympifyError:
- pass
- cls = p.__class__.__name__
- rep = self._print(p.rep)
- dom = self._print(p.dom)
- ring = self._print(p.ring)
- return "%s(%s, %s, %s)" % (cls, rep, dom, ring)
- def _print_DMF(self, expr):
- return self._print_DMP(expr)
- def _print_Object(self, obj):
- return 'Object("%s")' % obj.name
- def _print_IdentityMorphism(self, morphism):
- return 'IdentityMorphism(%s)' % morphism.domain
- def _print_NamedMorphism(self, morphism):
- return 'NamedMorphism(%s, %s, "%s")' % \
- (morphism.domain, morphism.codomain, morphism.name)
- def _print_Category(self, category):
- return 'Category("%s")' % category.name
- def _print_Manifold(self, manifold):
- return manifold.name.name
- def _print_Patch(self, patch):
- return patch.name.name
- def _print_CoordSystem(self, coords):
- return coords.name.name
- def _print_BaseScalarField(self, field):
- return field._coord_sys.symbols[field._index].name
- def _print_BaseVectorField(self, field):
- return 'e_%s' % field._coord_sys.symbols[field._index].name
- def _print_Differential(self, diff):
- field = diff._form_field
- if hasattr(field, '_coord_sys'):
- return 'd%s' % field._coord_sys.symbols[field._index].name
- else:
- return 'd(%s)' % self._print(field)
- def _print_Tr(self, expr):
- #TODO : Handle indices
- return "%s(%s)" % ("Tr", self._print(expr.args[0]))
- def _print_Str(self, s):
- return self._print(s.name)
- def _print_AppliedBinaryRelation(self, expr):
- rel = expr.function
- return '%s(%s, %s)' % (self._print(rel),
- self._print(expr.lhs),
- self._print(expr.rhs))
- @print_function(StrPrinter)
- def sstr(expr, **settings):
- """Returns the expression as a string.
- For large expressions where speed is a concern, use the setting
- order='none'. If abbrev=True setting is used then units are printed in
- abbreviated form.
- Examples
- ========
- >>> from sympy import symbols, Eq, sstr
- >>> a, b = symbols('a b')
- >>> sstr(Eq(a + b, 0))
- 'Eq(a + b, 0)'
- """
- p = StrPrinter(settings)
- s = p.doprint(expr)
- return s
- class StrReprPrinter(StrPrinter):
- """(internal) -- see sstrrepr"""
- def _print_str(self, s):
- return repr(s)
- def _print_Str(self, s):
- # Str does not to be printed same as str here
- return "%s(%s)" % (s.__class__.__name__, self._print(s.name))
- @print_function(StrReprPrinter)
- def sstrrepr(expr, **settings):
- """return expr in mixed str/repr form
- i.e. strings are returned in repr form with quotes, and everything else
- is returned in str form.
- This function could be useful for hooking into sys.displayhook
- """
- p = StrReprPrinter(settings)
- s = p.doprint(expr)
- return s
|