# Incrementing a string -- puzzing "solution"...

Terry Reedy tjreedy at udel.edu
Fri Sep 17 03:13:50 CEST 2004

```"Pierre Fortin" <pfortin at pfortin.com> wrote in message
news:20040916004438.657b50a4 at gypsy.pfortin.com...
> On Wed, 15 Sep 2004 15:08:20 -0700 John wrote:
> Puzzling...  I hacked at this problem as a flexibility learning exercise
> and actually got this to work; but... does 'while True' in a generator
> have side-effects...??

No.  Note that the 'while True' and the rest of the body code end up in/as
the body of the .next method of the generator object produced by calling
the generator function.  You don't have to understand all this to use
generators in for statements, but you should when using them with while
loops.

>  Or generator recursion?

I has a main of sometimes simplifying variable depth recursion ;-)

> I don't see how the string actually _grows_ inside  the while....  :^?
> I was just expecting the prefix to be '', then 'a'...'z' giving a..z,
> aa..az, ba..bz, ... za..zz -- not continuing through aaa...azz and
> onwards... It's cool; but boggles my mind at the moment...  not that
> that's a stretch...  :^)

The following is an never-ending generator, with unbounded levels of
recursion.  The generator on each level of recursion is the same and
therefore generates the same sequence.  Each is 'behind' the level above it
and 'ahead' of the level beneath (counting the first as the top level) in
terms of where it is in the sequence.

Prefix grows from length 0 to 1 on the first call to the next method of the
level beneath it.  That same call causes the creation of another 'instance'
(still inactive) two levels down.  When a later g.next call causes the
prefix one level down to grow from 0 to 1, the prefix as the current level
grows from 1 to 2.  And so on.  At any time (except transitions), there is
a stack of n+1 identical instances of the generator (and its .next methods)
with prefixes ranging from length n-1 down to 0 with the bottom instance
having no prefix at all.

> def ascinc(start='a',end='z'):
>    g = ascinc(start,end)

This creates a new generator object but does NOT call its .next method.

>    prefix = ''
>    while True:
>        for i in range(ord(start[-1]),ord(end[-1])+1):
>            yield (prefix + chr(i))
>        prefix = g.next()

Increments in prefix length bubble up from the bott

> g = ascinc('a')

This 'kickstarts' the process by creating the top generator without calling
it.

> for i in range(100):
>    print g.next(),

while True: print g.next() # would theorectically continue indefinitely, as
would
for s in ascinc('a'): print s # both would croak on the recursion limit

In each case, the first call of .next() causes creation of a second
generator and a blank prefix.  I hope the mechanism is now clearer for you.

Terry J. Reedy

```