[docs]deffilldedent(s,w=70):""" Strips leading and trailing empty lines from a copy of `s`, then dedents, fills and returns it. Empty line stripping serves to deal with docstrings like this one that start with a newline after the initial triple quote, inserting an empty line at the beginning of the string."""return'\n'+fill(dedent(str(s)).strip('\n'),width=w)

[docs]defrawlines(s):"""Return a cut-and-pastable string that, when printed, is equivalent to the input. The string returned is formatted so it can be indented nicely within tests; in some cases it is wrapped in the dedent function which has to be imported from textwrap. Examples ======== Note: because there are characters in the examples below that need to be escaped because they are themselves within a triple quoted docstring, expressions below look more complicated than they would be if they were printed in an interpreter window. >>> from sympy.utilities.misc import rawlines >>> from sympy import TableForm >>> s = str(TableForm([[1, 10]], headings=(None, ['a', 'bee']))) >>> print(rawlines(s)) # the \\ appears as \ when printed ( 'a bee\\n' '-----\\n' '1 10 ' ) >>> print(rawlines('''this ... that''')) dedent('''\\ this that''') >>> print(rawlines('''this ... that ... ''')) dedent('''\\ this that ''') >>> s = \"\"\"this ... is a triple ''' ... \"\"\" >>> print(rawlines(s)) dedent(\"\"\"\\ this is a triple ''' \"\"\") >>> print(rawlines('''this ... that ... ''')) ( 'this\\n' 'that\\n' ' ' ) """lines=s.split('\n')iflen(lines)==1:returnrepr(lines[0])triple=["'''"ins,'"""'ins]ifany(li.endswith(' ')forliinlines)or'\\'insorall(triple):rv=["("]# add on the newlinestrailing=s.endswith('\n')last=len(lines)-1fori,liinenumerate(lines):ifi!=lastortrailing:rv.append(repr(li)[:-1]+'\\n\'')else:rv.append(repr(li))return'\n '.join(rv)+'\n)'else:rv='\n '.join(lines)iftriple[0]:return'dedent("""\\\n%s""")'%rvelse:return"dedent('''\\\n%s''')"%rv

[docs]defdebug_decorator(func):"""If SYMPY_DEBUG is True, it will print a nice execution tree with arguments and results of all decorated functions, else do nothing. """fromsympyimportSYMPY_DEBUGifnotSYMPY_DEBUG:returnfuncdefmaketree(f,*args,**kw):global_debug_tmpglobal_debug_iteroldtmp=_debug_tmp_debug_tmp=[]_debug_iter+=1deftree(subtrees):defindent(s,type=1):x=s.split("\n")r="+-%s\n"%x[0]forainx[1:]:ifa=="":continueiftype==1:r+="| %s\n"%aelse:r+=" %s\n"%areturnriflen(subtrees)==0:return""f=[]forainsubtrees[:-1]:f.append(indent(a))f.append(indent(subtrees[-1],2))return''.join(f)# If there is a bug and the algorithm enters an infinite loop, enable the# following lines. It will print the names and parameters of all major functions# that are called, *before* they are called#from sympy.core.compatibility import reduce#print("%s%s %s%s" % (_debug_iter, reduce(lambda x, y: x + y, \# map(lambda x: '-', range(1, 2 + _debug_iter))), get_function_name(f), args))r=f(*args,**kw)_debug_iter-=1s="%s%s = %s\n"%(get_function_name(f),args,r)if_debug_tmp!=[]:s+=tree(_debug_tmp)_debug_tmp=oldtmp_debug_tmp.append(s)if_debug_iter==0:print((_debug_tmp[0]))_debug_tmp=[]returnrdefdecorated(*args,**kwargs):returnmaketree(func,*args,**kwargs)returndecorated

[docs]deffind_executable(executable,path=None):"""Try to find 'executable' in the directories listed in 'path' (a string listing directories separated by 'os.pathsep'; defaults to os.environ['PATH']). Returns the complete filename or None if not found """ifpathisNone:path=os.environ['PATH']paths=path.split(os.pathsep)extlist=['']ifos.name=='os2':(base,ext)=os.path.splitext(executable)# executable files on OS/2 can have an arbitrary extension, but# .exe is automatically appended if no dot is present in the nameifnotext:executable=executable+".exe"elifsys.platform=='win32':pathext=os.environ['PATHEXT'].lower().split(os.pathsep)(base,ext)=os.path.splitext(executable)ifext.lower()notinpathext:extlist=pathextforextinextlist:execname=executable+extifos.path.isfile(execname):returnexecnameelse:forpinpaths:f=os.path.join(p,execname)ifos.path.isfile(f):returnfelse:returnNone

[docs]deffunc_name(x):'''Return function name of `x` (if defined) else the `type(x)`. See Also ======== sympy.core.compatibility get_function_name '''returngetattr(getattr(x,'func',x),'__name__',type(x))

def_replace(reps):"""Return a function that can make the replacements, given in ``reps``, on a string. The replacements should be given as mapping. Examples ======== >>> from sympy.utilities.misc import _replace >>> f = _replace(dict(foo='bar', d='t')) >>> f('food') 'bart' >>> f = _replace({}) >>> f('food') 'food' """ifnotreps:returnlambdax:xD=lambdamatch:reps[match.group(0)]pattern=_re.compile("|".join([_re.escape(k)fork,vinreps.items()]),_re.M)returnlambdastring:pattern.sub(D,string)

[docs]defreplace(string,*reps):"""Return ``string`` with all keys in ``reps`` replaced with their corresponding values, longer strings first, irrespective of the order they are given. ``reps`` may be passed as tuples or a single mapping. Examples ======== >>> from sympy.utilities.misc import replace >>> replace('foo', {'oo': 'ar', 'f': 'b'}) 'bar' >>> replace("spamham sha", ("spam", "eggs"), ("sha","md5")) 'eggsham md5' There is no guarantee that a unique answer will be obtained if keys in a mapping overlap (i.e. are the same length and have some identical sequence at the beginning/end): >>> reps = [ ... ('ab', 'x'), ... ('bc', 'y')] >>> replace('abc', *reps) in ('xc', 'ay') True References ========== .. [1] http://stackoverflow.com/questions/6116978/python-replace-multiple-strings """iflen(reps)==1:kv=reps[0]iftype(kv)isdict:reps=kvelse:returnstring.replace(*kv)else:reps=dict(reps)return_replace(reps)(string)

[docs]deftranslate(s,a,b=None,c=None):"""Return ``s`` where characters have been replaced or deleted. SYNTAX ====== translate(s, None, deletechars): all characters in ``deletechars`` are deleted translate(s, map [,deletechars]): all characters in ``deletechars`` (if provided) are deleted then the replacements defined by map are made; if the keys of map are strings then the longer ones are handled first. Multicharacter deletions should have a value of ''. translate(s, oldchars, newchars, deletechars) all characters in ``deletechars`` are deleted then each character in ``oldchars`` is replaced with the corresponding character in ``newchars`` Examples ======== >>> from sympy.utilities.misc import translate >>> from sympy.core.compatibility import unichr >>> abc = 'abc' >>> translate(abc, None, 'a') 'bc' >>> translate(abc, {'a': 'x'}, 'c') 'xb' >>> translate(abc, {'abc': 'x', 'a': 'y'}) 'x' >>> translate('abcd', 'ac', 'AC', 'd') 'AbC' There is no guarantee that a unique answer will be obtained if keys in a mapping overlap are the same length and have some identical sequences at the beginning/end: >>> translate(abc, {'ab': 'x', 'bc': 'y'}) in ('xc', 'ay') True """fromsympy.core.compatibilityimportmaketrans# when support for Python 2 is dropped, this try/except can be#removedtry:''.translate(None,'')py3=FalseexceptTypeError:py3=Truemr={}ifaisNone:assertcisNoneifnotb:returnsc=ba=b=''else:iftype(a)isdict:short={}forkinlist(a.keys()):if(len(k)==1andlen(a[k])==1):short[k]=a.pop(k)mr=ac=bifshort:a,b=[''.join(i)foriinlist(zip(*short.items()))]else:a=b=''else:assertlen(a)==len(b)ifpy3:ifc:s=s.translate(maketrans('','',c))s=replace(s,mr)returns.translate(maketrans(a,b))else:# when support for Python 2 is dropped, this if-else-block# can be replaced with the if-clauseifc:c=list(c)rem={}foriinrange(-1,-1-len(c),-1):iford(c[i])>255:rem[c[i]]=''c.pop(i)s=s.translate(None,''.join(c))s=replace(s,rem)ifa:a=list(a)b=list(b)foriinrange(-1,-1-len(a),-1):iford(a[i])>255orord(b[i])>255:mr[a.pop(i)]=b.pop(i)a=''.join(a)b=''.join(b)s=replace(s,mr)table=maketrans(a,b)# s may have become unicode which uses the py3 syntax for translateiftype(table)isstrandtype(s)isstr:s=s.translate(table)else:s=s.translate(dict([(i,ord(c))fori,cinenumerate(table)]))returns