def _print_nth_root(self, base, expt): bpretty = self._print(base) # Construct root sign, start with the \/ shape _zZ = xobj('/', 1) rootsign = xobj('\\', 1) + _zZ # Make exponent number to put above it if isinstance(expt, C.Rational): exp = str(expt.q) if exp == '2': exp = '' else: exp = str(expt.args[0]) exp = exp.ljust(2) if len(exp) > 2: rootsign = ' ' * (len(exp) - 2) + rootsign # Stack the exponent rootsign = stringPict(exp + '\n' + rootsign) rootsign.baseline = 0 # Diagonal: length is one less than height of base linelength = bpretty.height() - 1 diagonal = stringPict('\n'.join(' ' * (linelength - i - 1) + _zZ + ' ' * i for i in range(linelength))) # Put baseline just below lowest line: next to exp diagonal.baseline = linelength - 1 # Make the root symbol rootsign = prettyForm(*rootsign.right(diagonal)) # Det the baseline to match contents to fix the height # but if the height of bpretty is one, the rootsign must be one higher rootsign.baseline = max(1, bpretty.baseline) #build result s = prettyForm(hobj('_', 2 + bpretty.width())) s = prettyForm(*bpretty.above(s)) s = prettyForm(*s.left(rootsign)) return s
def _print_Product(self, expr): func = expr.term pretty_func = self._print(func) horizontal_chr = xobj('_', 1) corner_chr = xobj('_', 1) vertical_chr = xobj('|', 1) if self._use_unicode: # use unicode corners horizontal_chr = xobj('-', 1) corner_chr = u'\u252c' func_height = pretty_func.height() first = True max_upper = 0 sign_height = 0 for lim in expr.limits: width = (func_height + 2) * 5 // 3 - 2 sign_lines = [] sign_lines.append(corner_chr + (horizontal_chr * width) + corner_chr) for i in range(func_height + 1): sign_lines.append(vertical_chr + (' ' * width) + vertical_chr) pretty_sign = stringPict('') pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) pretty_upper = self._print(lim[2]) pretty_lower = self._print(C.Equality(lim[0], lim[1])) max_upper = max(max_upper, pretty_upper.height()) if first: sign_height = pretty_sign.height() pretty_sign = prettyForm(*pretty_sign.above(pretty_upper)) pretty_sign = prettyForm(*pretty_sign.below(pretty_lower)) if first: pretty_func.baseline = 0 first = False height = pretty_sign.height() padding = stringPict('') padding = prettyForm(*padding.stack(*[' '] * (height - 1))) pretty_sign = prettyForm(*pretty_sign.right(padding)) pretty_func = prettyForm(*pretty_sign.right(pretty_func)) #pretty_func.baseline = 0 pretty_func.baseline = max_upper + sign_height // 2 return pretty_func
def _print_Product(self, expr): func = expr.term pretty_func = self._print(func) horizontal_chr = xobj('_', 1) corner_chr = xobj('_', 1) vertical_chr = xobj('|', 1) if self._use_unicode: # use unicode corners horizontal_chr = xobj('-', 1) corner_chr = u'\u252c' func_height = pretty_func.height() first = True max_upper = 0 sign_height = 0 for lim in expr.limits: width = (func_height + 2) * 5 // 3 - 2 sign_lines = [] sign_lines.append(corner_chr+(horizontal_chr*width)+corner_chr) for i in range(func_height+1): sign_lines.append(vertical_chr+(' '*width)+vertical_chr) pretty_sign = stringPict('') pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) pretty_upper = self._print(lim[2]) pretty_lower = self._print(C.Equality(lim[0], lim[1])) max_upper = max(max_upper, pretty_upper.height()) if first: sign_height = pretty_sign.height() pretty_sign = prettyForm(*pretty_sign.above(pretty_upper)) pretty_sign = prettyForm(*pretty_sign.below(pretty_lower)) if first: pretty_func.baseline = 0 first = False height = pretty_sign.height() padding = stringPict('') padding = prettyForm(*padding.stack(*[' ']*(height-1))) pretty_sign = prettyForm(*pretty_sign.right(padding)) pretty_func = prettyForm(*pretty_sign.right(pretty_func)) #pretty_func.baseline = 0 pretty_func.baseline = max_upper + sign_height//2 return pretty_func
def _print_KroneckerDelta(self, e): pform = self._print(e.args[0]) pform = prettyForm(*pform.right((prettyForm(',')))) pform = prettyForm(*pform.right((self._print(e.args[1])))) if self._use_unicode: a = stringPict(pretty_symbol('delta')) else: a = stringPict('d') b = pform top = stringPict(*b.left(' '*a.width())) bot = stringPict(*a.right(' '*b.width())) return prettyForm(binding=prettyForm.POW, *bot.below(top))
def _print_KroneckerDelta(self, e): pform = self._print(e.args[0]) pform = prettyForm(*pform.right((prettyForm(',')))) pform = prettyForm(*pform.right((self._print(e.args[1])))) if self._use_unicode: a = stringPict(pretty_symbol('delta')) else: a = stringPict('d') b = pform top = stringPict(*b.left(' ' * a.width())) bot = stringPict(*a.right(' ' * b.width())) return prettyForm(binding=prettyForm.POW, *bot.below(top))
def _print_Pow(self, power): # square roots, other roots or n-th roots # test for fraction 1/n or power x**-1 if power.is_commutative: if (isinstance(power.exp, C.Rational) and power.exp.p == 1 and power.exp.q != 1) or ( isinstance(power.exp, C.Pow) and isinstance(power.exp.args[0], C.Symbol) and power.exp.args[1] == S.NegativeOne ): bpretty = self._print(power.base) # construct root sign, start with the \/ shape _zZ = xobj("/", 1) rootsign = xobj("\\", 1) + _zZ # make exponent number to put above it if isinstance(power.exp, C.Rational): exp = str(power.exp.q) if exp == "2": exp = "" else: exp = str(power.exp.args[0]) exp = exp.ljust(2) if len(exp) > 2: rootsign = " " * (len(exp) - 2) + rootsign # stack the exponent rootsign = stringPict(exp + "\n" + rootsign) rootsign.baseline = 0 # diagonal: length is one less than height of base linelength = bpretty.height() - 1 diagonal = stringPict("\n".join(" " * (linelength - i - 1) + _zZ + " " * i for i in range(linelength))) # put baseline just below lowest line: next to exp diagonal.baseline = linelength - 1 # make the root symbol rootsign = prettyForm(*rootsign.right(diagonal)) # set the baseline to match contents to fix the height # but if the height of bpretty is one, the rootsign must be one higher rootsign.baseline = max(1, bpretty.baseline) # build result s = prettyForm(hobj("_", 2 + bpretty.width())) s = prettyForm(*bpretty.above(s)) s = prettyForm(*s.left(rootsign)) return s elif power.exp.is_Rational and power.exp.is_negative: # Things like 1/x return prettyForm("1") / self._print(C.Pow(power.base, -power.exp)) # None of the above special forms, do a standard power b, e = power.as_base_exp() return self._print(b) ** self._print(e)
def _print_Pow(self, power): # square roots, other roots or n-th roots #test for fraction 1/n or power x**-1 if power.is_commutative: if (isinstance(power.exp, C.Rational) and power.exp.p==1 and power.exp.q !=1) or \ ( isinstance(power.exp, C.Pow) and isinstance(power.exp.args[0], C.Symbol) and power.exp.args[1]==S.NegativeOne): bpretty = self._print(power.base) #construct root sign, start with the \/ shape _zZ = xobj('/', 1) rootsign = xobj('\\', 1) + _zZ #make exponent number to put above it if isinstance(power.exp, C.Rational): exp = str(power.exp.q) if exp == '2': exp = '' else: exp = str(power.exp.args[0]) exp = exp.ljust(2) if len(exp) > 2: rootsign = ' ' * (len(exp) - 2) + rootsign #stack the exponent rootsign = stringPict(exp + '\n' + rootsign) rootsign.baseline = 0 #diagonal: length is one less than height of base linelength = bpretty.height() - 1 diagonal = stringPict('\n'.join(' ' * (linelength - i - 1) + _zZ + ' ' * i for i in range(linelength))) #put baseline just below lowest line: next to exp diagonal.baseline = linelength - 1 #make the root symbol rootsign = prettyForm(*rootsign.right(diagonal)) #set the baseline to match contents to fix the height #but if the height of bpretty is one, the rootsign must be one higher rootsign.baseline = max(1, bpretty.baseline) #build result s = prettyForm(hobj('_', 2 + bpretty.width())) s = prettyForm(*bpretty.above(s)) s = prettyForm(*s.left(rootsign)) return s elif power.exp.is_Rational and power.exp.is_negative: # Things like 1/x return prettyForm("1") / self._print( C.Pow(power.base, -power.exp)) # None of the above special forms, do a standard power b, e = power.as_base_exp() return self._print(b)**self._print(e)
def _print_seq(self, seq, left=None, right=None, delimiter=', ', parenthesize=lambda x: False): s = None for item in seq: pform = self._print(item) if parenthesize(item): pform = prettyForm(*pform.parens()) if s is None: # first element s = pform else: s = prettyForm(*stringPict.next(s, delimiter)) s = prettyForm(*stringPict.next(s, pform)) if s is None: s = stringPict('') s = prettyForm(*s.parens(left, right, ifascii_nougly=True)) return s
def _print_Product(self, expr): func = expr.term pretty_func = self._print(func) horizontal_chr = xobj('_', 1) corner_chr = xobj('_', 1) vertical_chr = xobj('|', 1) if self._use_unicode: # use unicode corners horizontal_chr = xobj('-', 1) corner_chr = u'\u252c' func_height = pretty_func.height() width = (func_height + 2) * 5 // 3 - 2 sign_lines = [] sign_lines.append(corner_chr + (horizontal_chr * width) + corner_chr) for i in range(func_height + 1): sign_lines.append(vertical_chr + (' ' * width) + vertical_chr) pretty_sign = stringPict('') pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) pretty_upper = self._print(expr.upper) pretty_lower = self._print(C.Equality(expr.index, expr.lower)) pretty_sign = prettyForm(*pretty_sign.above(pretty_upper)) pretty_sign = prettyForm(*pretty_sign.below(pretty_lower)) height = pretty_sign.height() padding = stringPict('') padding = prettyForm(*padding.stack(*[' '] * (height - 1))) pretty_sign = prettyForm(*pretty_sign.right(padding)) pretty_func.baseline = 0 pretty_func = prettyForm(*pretty_sign.right(pretty_func)) return pretty_func
def _print_Product(self, expr): func = expr.term pretty_func = self._print(func) horizontal_chr = xobj('_', 1) corner_chr = xobj('_', 1) vertical_chr = xobj('|', 1) if self._use_unicode: # use unicode corners horizontal_chr = xobj('-', 1) corner_chr = u'\u252c' func_height = pretty_func.height() width = (func_height + 2) * 5 // 3 - 2 sign_lines = [] sign_lines.append(corner_chr+(horizontal_chr*width)+corner_chr) for i in range(func_height+1): sign_lines.append(vertical_chr+(' '*width)+vertical_chr) pretty_sign = stringPict('') pretty_sign = prettyForm(*pretty_sign.stack(*sign_lines)) pretty_upper = self._print(expr.upper) pretty_lower = self._print(C.Equality(expr.index, expr.lower)) pretty_sign = prettyForm(*pretty_sign.above(pretty_upper)) pretty_sign = prettyForm(*pretty_sign.below(pretty_lower)) height = pretty_sign.height() padding = stringPict('') padding = prettyForm(*padding.stack(*[' ']*(height-1))) pretty_sign = prettyForm(*pretty_sign.right(padding)) pretty_func.baseline = 0 pretty_func = prettyForm(*pretty_sign.right(pretty_func)) return pretty_func
def _hprint_vec(self, v): D = None for a in v: p = a if D is None: D = p else: D = prettyForm(*D.right(', ')) D = prettyForm(*D.right(p)) if D is None: D = stringPict(' ') return D
def _print_nth_root (self, base, expt): bpretty = self._print(base) # Construct root sign, start with the \/ shape _zZ = xobj('/',1) rootsign = xobj('\\',1) + _zZ # Make exponent number to put above it if isinstance(expt, C.Rational): exp = str(expt.q) if exp == '2': exp = '' else: exp = str(expt.args[0]) exp = exp.ljust(2) if len(exp) > 2: rootsign = ' '*(len(exp) - 2) + rootsign # Stack the exponent rootsign = stringPict(exp + '\n' + rootsign) rootsign.baseline = 0 # Diagonal: length is one less than height of base linelength = bpretty.height() - 1 diagonal = stringPict('\n'.join( ' '*(linelength - i - 1) + _zZ + ' '*i for i in range(linelength) )) # Put baseline just below lowest line: next to exp diagonal.baseline = linelength - 1 # Make the root symbol rootsign = prettyForm(*rootsign.right(diagonal)) # Det the baseline to match contents to fix the height # but if the height of bpretty is one, the rootsign must be one higher rootsign.baseline = max(1, bpretty.baseline) #build result s = prettyForm(hobj('_', 2 + bpretty.width())) s = prettyForm(*bpretty.above(s)) s = prettyForm(*s.left(rootsign)) return s
def _print_Subs(self, e): pform = self._print(e.expr) pform = prettyForm(*pform.parens()) h = pform.height() if pform.height() > 1 else 2 rvert = stringPict(vobj('|', h), baseline=pform.baseline) pform = prettyForm(*pform.right(rvert)) b = pform.baseline pform.baseline = pform.height() - 1 pform = prettyForm(*pform.right(self._print_seq([ self._print_seq((self._print(v[0]), xsym('=='), self._print(v[1])), delimiter='') for v in zip(e.variables, e.point) ]))) pform.baseline = b return pform
def _print_seq(self, seq, left=None, right=None): S = None for item in seq: pform = self._print(item) if S is None: # first element S = pform else: S = prettyForm(*stringPict.next(S, ', ')) S = prettyForm(*stringPict.next(S, pform)) if S is None: S = stringPict('') S = prettyForm(*S.parens(left, right, ifascii_nougly=True)) return S
def _print_seq(self, seq, left=None, right=None, delimiter=', '): s = None for item in seq: pform = self._print(item) if s is None: # first element s = pform else: s = prettyForm(*stringPict.next(s, delimiter)) s = prettyForm(*stringPict.next(s, pform)) if s is None: s = stringPict('') s = prettyForm(*s.parens(left, right, ifascii_nougly=True)) return s
def _print_seq(self, seq, left=None, right=None, delimiter=", ", parenthesize=lambda x: False): s = None for item in seq: pform = self._print(item) if parenthesize(item): pform = prettyForm(*pform.parens()) if s is None: # first element s = pform else: s = prettyForm(*stringPict.next(s, delimiter)) s = prettyForm(*stringPict.next(s, pform)) if s is None: s = stringPict("") s = prettyForm(*s.parens(left, right, ifascii_nougly=True)) return s
def _hprint_vseparator(self, p1, p2): tmp = prettyForm(*p1.right(p2)) sep = stringPict(vobj('|', tmp.height()), baseline=tmp.baseline) return prettyForm(*p1.right(sep, p2))
def _print_Sum(self, expr): def asum(hrequired, lower, upper): def adjust(s, wid=None, how='<^>'): if not wid or len(s)>wid: return s need = wid - len(s) if how == '<^>' or how == "<" or how not in list('<^>'): return s + ' '*need half = need//2 lead = ' '*half if how == ">": return " "*need + s return lead + s + ' '*(need - len(lead)) h = max(hrequired, 2) d = h//2 wrequired = max(lower, upper) w = d + 1 more = hrequired % 2 lines = [] lines.append("_"*(w) + ' ') lines.append("\%s`" % (' '*(w - 1))) for i in range(1, d): lines.append('%s\\%s' % (' '*i, ' '*(w - i))) if more: lines.append('%s)%s' % (' '*(d), ' '*(w - d))) for i in reversed(range(1, d)): lines.append('%s/%s' % (' '*i, ' '*(w - i))) lines.append("/" + "_"*(w - 1) + ',') return d, h + more, lines f = expr.function prettyF = self._print(f) if f.is_Add: # add parens prettyF = prettyForm(*prettyF.parens()) H = prettyF.height() + 2 # \sum \sum \sum ... first = True max_upper = 0 sign_height = 0 for lim in expr.limits: if len(lim) == 3: prettyUpper = self._print(lim[2]) prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 2: prettyUpper = self._print("") prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 1: prettyUpper = self._print("") prettyLower = self._print(lim[0]) max_upper = max(max_upper, prettyUpper.height()) # Create sum sign based on the height of the argument d, h, slines = asum(H, prettyLower.width(), prettyUpper.width()) prettySign = stringPict('') prettySign = prettyForm(*prettySign.stack(*slines)) if first: sign_height = prettySign.height() prettySign = prettyForm(*prettySign.above(prettyUpper)) prettySign = prettyForm(*prettySign.below(prettyLower)) if first: # change F baseline so it centers on the sign prettyF.baseline -= d - (prettyF.height()//2 - prettyF.baseline) first = False # put padding to the right pad = stringPict('') pad = prettyForm(*pad.stack(*[' ']*h)) prettySign = prettyForm(*prettySign.right(pad)) # put the present prettyF to the right prettyF = prettyForm(*prettySign.right(prettyF)) prettyF.baseline = max_upper + sign_height//2 return prettyF
def _print_Sum(self, expr): ascii_mode = not self._use_unicode def asum(hrequired, lower, upper, use_ascii): def adjust(s, wid=None, how='<^>'): if not wid or len(s)>wid: return s need = wid - len(s) if how == '<^>' or how == "<" or how not in list('<^>'): return s + ' '*need half = need//2 lead = ' '*half if how == ">": return " "*need + s return lead + s + ' '*(need - len(lead)) h = max(hrequired, 2) d = h//2 wrequired = max(lower, upper) w = d + 1 more = hrequired % 2 lines = [] if use_ascii: lines.append("_"*(w) + ' ') lines.append("\%s`" % (' '*(w - 1))) for i in range(1, d): lines.append('%s\\%s' % (' '*i, ' '*(w - i))) if more: lines.append('%s)%s' % (' '*(d), ' '*(w - d))) for i in reversed(range(1, d)): lines.append('%s/%s' % (' '*i, ' '*(w - i))) lines.append("/" + "_"*(w - 1) + ',') return d, h + more, lines else: vsum = vobj('sum', 4) # contains all characters necessary lines.append("_"*(w + more)) for i in range(0, d + more): # only even number of lines lines.append('%s%s%s' % (' '*i, vsum[2], ' '*(w - i))) for i in reversed(range(0, d + more)): lines.append('%s%s%s' % (' '*i, vsum[4], ' '*(w - i))) lines.append(vsum[8]*(w + more)) return d, h + 2*more, lines f = expr.function prettyF = self._print(f) if f.is_Add: # add parens prettyF = prettyForm(*prettyF.parens()) H = prettyF.height() + 2 # \sum \sum \sum ... first = True max_upper = 0 sign_height = 0 for lim in expr.limits: if len(lim) == 3: prettyUpper = self._print(lim[2]) prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 2: prettyUpper = self._print("") prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 1: prettyUpper = self._print("") prettyLower = self._print(lim[0]) max_upper = max(max_upper, prettyUpper.height()) # Create sum sign based on the height of the argument d, h, slines = asum(H, prettyLower.width(), prettyUpper.width(), ascii_mode) prettySign = stringPict('') prettySign = prettyForm(*prettySign.stack(*slines)) if first: sign_height = prettySign.height() prettySign = prettyForm(*prettySign.above(prettyUpper)) prettySign = prettyForm(*prettySign.below(prettyLower)) # In UNICODE mode we need to modify vertical adjustment a bit unicode_shift = 0 if first: # change F baseline so it centers on the sign prettyF.baseline -= d - (prettyF.height()//2 - prettyF.baseline) - unicode_shift first = False # put padding to the right pad = stringPict('') pad = prettyForm(*pad.stack(*[' ']*h)) prettySign = prettyForm(*prettySign.right(pad)) # put the present prettyF to the right prettyF = prettyForm(*prettySign.right(prettyF)) prettyF.baseline = max_upper + sign_height//2 return prettyF
def _print_Sum(self, expr): ascii_mode = not self._use_unicode def asum(hrequired, lower, upper, use_ascii): def adjust(s, wid=None, how='<^>'): if not wid or len(s) > wid: return s need = wid - len(s) if how == '<^>' or how == "<" or how not in list('<^>'): return s + ' ' * need half = need // 2 lead = ' ' * half if how == ">": return " " * need + s return lead + s + ' ' * (need - len(lead)) h = max(hrequired, 2) d = h // 2 wrequired = max(lower, upper) w = d + 1 more = hrequired % 2 lines = [] if use_ascii: lines.append("_" * (w) + ' ') lines.append("\%s`" % (' ' * (w - 1))) for i in range(1, d): lines.append('%s\\%s' % (' ' * i, ' ' * (w - i))) if more: lines.append('%s)%s' % (' ' * (d), ' ' * (w - d))) for i in reversed(range(1, d)): lines.append('%s/%s' % (' ' * i, ' ' * (w - i))) lines.append("/" + "_" * (w - 1) + ',') return d, h + more, lines, 0 else: w = w + more d = d + more vsum = vobj('sum', 4) lines.append("_" * (w)) for i in range(0, d): lines.append('%s%s%s' % (' ' * i, vsum[2], ' ' * (w - i - 1))) for i in reversed(range(0, d)): lines.append('%s%s%s' % (' ' * i, vsum[4], ' ' * (w - i - 1))) lines.append(vsum[8] * (w)) return d, h + 2 * more, lines, more f = expr.function prettyF = self._print(f) if f.is_Add: # add parens prettyF = prettyForm(*prettyF.parens()) H = prettyF.height() + 2 # \sum \sum \sum ... first = True max_upper = 0 sign_height = 0 for lim in expr.limits: if len(lim) == 3: prettyUpper = self._print(lim[2]) prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 2: prettyUpper = self._print("") prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 1: prettyUpper = self._print("") prettyLower = self._print(lim[0]) max_upper = max(max_upper, prettyUpper.height()) # Create sum sign based on the height of the argument d, h, slines, adjustment = asum(H, prettyLower.width(), prettyUpper.width(), ascii_mode) prettySign = stringPict('') prettySign = prettyForm(*prettySign.stack(*slines)) if first: sign_height = prettySign.height() prettySign = prettyForm(*prettySign.above(prettyUpper)) prettySign = prettyForm(*prettySign.below(prettyLower)) if first: # change F baseline so it centers on the sign prettyF.baseline -= d - (prettyF.height() // 2 - prettyF.baseline) - adjustment first = False # put padding to the right pad = stringPict('') pad = prettyForm(*pad.stack(*[' '] * h)) prettySign = prettyForm(*prettySign.right(pad)) # put the present prettyF to the right prettyF = prettyForm(*prettySign.right(prettyF)) prettyF.baseline = max_upper + sign_height // 2 return prettyF
def _print_Sum(self, expr): ascii_mode = not self._use_unicode def asum(hrequired, lower, upper, use_ascii): def adjust(s, wid=None, how="<^>"): if not wid or len(s) > wid: return s need = wid - len(s) if how == "<^>" or how == "<" or how not in list("<^>"): return s + " " * need half = need // 2 lead = " " * half if how == ">": return " " * need + s return lead + s + " " * (need - len(lead)) h = max(hrequired, 2) d = h // 2 wrequired = max(lower, upper) w = d + 1 more = hrequired % 2 lines = [] if use_ascii: lines.append("_" * (w) + " ") lines.append("\%s`" % (" " * (w - 1))) for i in range(1, d): lines.append("%s\\%s" % (" " * i, " " * (w - i))) if more: lines.append("%s)%s" % (" " * (d), " " * (w - d))) for i in reversed(range(1, d)): lines.append("%s/%s" % (" " * i, " " * (w - i))) lines.append("/" + "_" * (w - 1) + ",") return d, h + more, lines, 0 else: w = w + more d = d + more vsum = vobj("sum", 4) lines.append("_" * (w)) for i in range(0, d): lines.append("%s%s%s" % (" " * i, vsum[2], " " * (w - i - 1))) for i in reversed(range(0, d)): lines.append("%s%s%s" % (" " * i, vsum[4], " " * (w - i - 1))) lines.append(vsum[8] * (w)) return d, h + 2 * more, lines, more f = expr.function prettyF = self._print(f) if f.is_Add: # add parens prettyF = prettyForm(*prettyF.parens()) H = prettyF.height() + 2 # \sum \sum \sum ... first = True max_upper = 0 sign_height = 0 for lim in expr.limits: if len(lim) == 3: prettyUpper = self._print(lim[2]) prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 2: prettyUpper = self._print("") prettyLower = self._print(C.Equality(lim[0], lim[1])) elif len(lim) == 1: prettyUpper = self._print("") prettyLower = self._print(lim[0]) max_upper = max(max_upper, prettyUpper.height()) # Create sum sign based on the height of the argument d, h, slines, adjustment = asum(H, prettyLower.width(), prettyUpper.width(), ascii_mode) prettySign = stringPict("") prettySign = prettyForm(*prettySign.stack(*slines)) if first: sign_height = prettySign.height() prettySign = prettyForm(*prettySign.above(prettyUpper)) prettySign = prettyForm(*prettySign.below(prettyLower)) if first: # change F baseline so it centers on the sign prettyF.baseline -= d - (prettyF.height() // 2 - prettyF.baseline) - adjustment first = False # put padding to the right pad = stringPict("") pad = prettyForm(*pad.stack(*[" "] * h)) prettySign = prettyForm(*prettySign.right(pad)) # put the present prettyF to the right prettyF = prettyForm(*prettySign.right(prettyF)) prettyF.baseline = max_upper + sign_height // 2 return prettyF