[docs]classDummy(Symbol):"""Dummy symbols are each unique, identified by an internal count index: >>> from sympy import Dummy >>> bool(Dummy("x") == Dummy("x")) == True False If a name is not supplied then a string value of the count index will be used. This is useful when a temporary variable is needed and the name of the variable used in the expression is not important. >>> Dummy() #doctest: +SKIP _Dummy_10 """_count=0__slots__=['dummy_index']is_Dummy=Truedef__new__(cls,name=None,**assumptions):ifnameisNone:name="Dummy_"+str(Dummy._count)cls._sanitize(assumptions,cls)obj=Symbol.__xnew__(cls,name,**assumptions)Dummy._count+=1obj.dummy_index=Dummy._countreturnobjdef__getstate__(self):return{'_assumptions':self._assumptions,'dummy_index':self.dummy_index}@cacheitdefsort_key(self,order=None):returnself.class_key(),(2,(str(self),self.dummy_index)),S.One.sort_key(),S.Onedef_hashable_content(self):returnSymbol._hashable_content(self)+(self.dummy_index,)

[docs]defsymbols(names,**args):""" Transform strings into instances of :class:`Symbol` class. :func:`symbols` function returns a sequence of symbols with names taken from ``names`` argument, which can be a comma or whitespace delimited string, or a sequence of strings:: >>> from sympy import symbols, Function >>> x, y, z = symbols('x,y,z') >>> a, b, c = symbols('a b c') The type of output is dependent on the properties of input arguments:: >>> symbols('x') x >>> symbols('x,') (x,) >>> symbols('x,y') (x, y) >>> symbols(('a', 'b', 'c')) (a, b, c) >>> symbols(['a', 'b', 'c']) [a, b, c] >>> symbols(set(['a', 'b', 'c'])) set([a, b, c]) If an iterable container is needed for a single symbol, set the ``seq`` argument to ``True`` or terminate the symbol name with a comma:: >>> symbols('x', seq=True) (x,) To reduce typing, range syntax is supported to create indexed symbols. Ranges are indicated by a colon and the type of range is determined by the character to the right of the colon. If the character is a digit then all contiguous digits to the left are taken as the nonnegative starting value (or 0 if there is no digit left of the colon) and all contiguous digits to the right are taken as 1 greater than the ending value:: >>> symbols('x:10') (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) >>> symbols('x5:10') (x5, x6, x7, x8, x9) >>> symbols('x5(:2)') (x50, x51) >>> symbols('x5:10,y:5') (x5, x6, x7, x8, x9, y0, y1, y2, y3, y4) >>> symbols(('x5:10', 'y:5')) ((x5, x6, x7, x8, x9), (y0, y1, y2, y3, y4)) If the character to the right of the colon is a letter, then the single letter to the left (or 'a' if there is none) is taken as the start and all characters in the lexicographic range *through* the letter to the right are used as the range:: >>> symbols('x:z') (x, y, z) >>> symbols('x:c') # null range () >>> symbols('x(:c)') (xa, xb, xc) >>> symbols(':c') (a, b, c) >>> symbols('a:d, x:z') (a, b, c, d, x, y, z) >>> symbols(('a:d', 'x:z')) ((a, b, c, d), (x, y, z)) Multiple ranges are supported; contiguous numerical ranges should be separated by parentheses to disambiguate the ending number of one range from the starting number of the next:: >>> symbols('x:2(1:3)') (x01, x02, x11, x12) >>> symbols(':3:2') # parsing is from left to right (00, 01, 10, 11, 20, 21) Only one pair of parentheses surrounding ranges are removed, so to include parentheses around ranges, double them. And to include spaces, commas, or colons, escape them with a backslash:: >>> symbols('x((a:b))') (x(a), x(b)) >>> symbols('x(:1\,:2)') # or 'x((:1)\,(:2))' (x(0,0), x(0,1)) All newly created symbols have assumptions set according to ``args``:: >>> a = symbols('a', integer=True) >>> a.is_integer True >>> x, y, z = symbols('x,y,z', real=True) >>> x.is_real and y.is_real and z.is_real True Despite its name, :func:`symbols` can create symbol-like objects like instances of Function or Wild classes. To achieve this, set ``cls`` keyword argument to the desired type:: >>> symbols('f,g,h', cls=Function) (f, g, h) >>> type(_[0]) <class 'sympy.core.function.UndefinedFunction'> """result=[]ifisinstance(names,string_types):marker=0literals=['\,','\:','\ ']foriinrange(len(literals)):lit=literals.pop(0)iflitinnames:whilechr(marker)innames:marker+=1lit_char=chr(marker)marker+=1names=names.replace(lit,lit_char)literals.append((lit_char,lit[1:]))defliteral(s):ifliterals:forc,linliterals:s=s.replace(c,l)returnsnames=names.strip()as_seq=names.endswith(',')ifas_seq:names=names[:-1].rstrip()ifnotnames:raiseValueError('no symbols given')# split on commasnames=[n.strip()forninnames.split(',')]ifnotall(nforninnames):raiseValueError('missing symbol between commas')# split on spacesforiinrange(len(names)-1,-1,-1):names[i:i+1]=names[i].split()cls=args.pop('cls',Symbol)seq=args.pop('seq',as_seq)fornameinnames:ifnotname:raiseValueError('missing symbol')if':'notinname:symbol=cls(literal(name),**args)result.append(symbol)continuesplit=_range.split(name)# remove 1 layer of bounding parentheses around rangesforiinrange(len(split)-1):ifiand':'insplit[i]andsplit[i]!=':'and \
split[i-1].endswith('(')and \
split[i+1].startswith(')'):split[i-1]=split[i-1][:-1]split[i+1]=split[i+1][1:]fori,sinenumerate(split):if':'ins:ifs[-1].endswith(':'):raiseValueError('missing end range')a,b=s.split(':')ifb[-1]instring.digits:a=0ifnotaelseint(a)b=int(b)split[i]=[str(c)forcinrange(a,b)]else:a=aor'a'split[i]=[string.ascii_letters[c]forcinrange(string.ascii_letters.index(a),string.ascii_letters.index(b)+1)]# inclusiveifnotsplit[i]:breakelse:split[i]=[s]else:seq=Trueiflen(split)==1:names=split[0]else:names=[''.join(s)forsincartes(*split)]ifliterals:result.extend([cls(literal(s),**args)forsinnames])else:result.extend([cls(s,**args)forsinnames])ifnotseqandlen(result)<=1:ifnotresult:return()returnresult[0]returntuple(result)else:fornameinnames:result.append(symbols(name,**args))returntype(names)(result)

[docs]defvar(names,**args):""" Create symbols and inject them into the global namespace. This calls :func:`symbols` with the same arguments and puts the results into the *global* namespace. It's recommended not to use :func:`var` in library code, where :func:`symbols` has to be used:: Examples ======== >>> from sympy import var >>> var('x') x >>> x x >>> var('a,ab,abc') (a, ab, abc) >>> abc abc >>> var('x,y', real=True) (x, y) >>> x.is_real and y.is_real True See :func:`symbol` documentation for more details on what kinds of arguments can be passed to :func:`var`. """deftraverse(symbols,frame):"""Recursively inject symbols to the global namespace. """forsymbolinsymbols:ifisinstance(symbol,Basic):frame.f_globals[symbol.name]=symbolelifisinstance(symbol,FunctionClass):frame.f_globals[symbol.__name__]=symbolelse:traverse(symbol,frame)frominspectimportcurrentframeframe=currentframe().f_backtry:syms=symbols(names,**args)ifsymsisnotNone:ifisinstance(syms,Basic):frame.f_globals[syms.name]=symselifisinstance(syms,FunctionClass):frame.f_globals[syms.__name__]=symselse:traverse(syms,frame)finally:delframe# break cyclic dependencies as stated in inspect docsreturnsyms