import sympy

def getAllTheLetters(begin='a', end='z'):
    'Generates all letters a-z as strings'
    beginNum = ord(begin)
    endNum = ord(end)
    for number in xrange(beginNum, endNum+1):
        yield chr(number)
        
def getAllTheLetterCombinations(N=0):
    if N>0:
        letters=getAllTheLetters()
        for letter in letters:
            if N==1:
                yield letter
            else:
                tails=getAllTheLetterCombinations(N-1)
                for tail in tails:
                    yield letter+tail
                    
def getNames_aa_ab_ac():
    'generates new strings'
    N=1
    while True:
        names=getAllTheLetterCombinations(N)
        for name in names:
            yield name
        N=N+1

def getNames_a_aa_aaa():
    'generates new strings'
    N=0
    while True:
        letters=getAllTheLetters()
        for letter in letters:
            name=letter
            for n in range(N):
                name=name+letter
            yield name
        N=N+1
  
def getNewSymbols(List=[], names=None, forbiddenNames=[], cls=sympy.Symbol):
    'generates new instances of cls with names from names and puts them in List'
    if names==None:
        names=getNames_a_aa_aaa()
    for name in names:
        if name in forbiddenNames:
            continue
        new=cls(name)
        List.append(new)
        yield new

def getNewDummys(*arg, **kw):
    'generates new sympy.Dummy'
    return getNewSymbols( cls=sympy.Dummy, *arg, **kw)



def getNext(List,getNew):
    '''
    getNew should be a generator and List should be a list of object allredy generated by that genarator 
    e.g. dummyList=[]; newDummy=getNewDummy(List=dummyList)
    everytime getNext(dummyList, newDummy) is called, this will create a generator that replicate the same list of dummys, and create new one when needed.
    '''
    for next in List:
        yield next
    for next in getNew:
        yield next

