[Tutor] Generator function question?

John Clark clajo04 at mac.com
Sun May 8 02:32:54 CEST 2005


Okay, 

I guess I was not being clear, or my example was not communicating the
situation of my code.

In function Test2, I am iterating through database tables (this is simulated
by the for loop across the range(1, 10), printing out a message that states
that I am operating on that particular table, and then calls another
function for each table (Test1) - in Test1, I retrieve each row of the table
(as simulated by the for loop on the range(1, 100) and operate on that row
(simulated by the loop on range(1, 10000) that effectively does nothing... -
to show progress as I do that, I want to show the "spinning wheel" so for
each row I print a backspace and then I wanted to call my function
neverEndingStatus() and get back the next character in the "cycle" of
"|\-/".  

I realize I can write a generator function and then use a for loop to cycle
through it forever, but I have the iterator on the rows of the table driving
the loop of the Test1 function, and would rather have that drive the
operation of the function than turning the loop inside out to have the
status cycle driving the loop.

My second take on the code is much closer to what I wanted - a function that
returned the next character in the cycle of |\-/ based on what the last
results were.  This code looked like:

import sys

def neverEndingStatus():
     def statusGen():
          index = 0
          statusChars = ['|', '\\', '-', '/']
          while True:
               yield statusChars[index]
               index = (index + 1) % 4
     try: 
          neverEndingStatus.x
     except AttributeError:
          neverEndingStatus.x = statusGen()
     
     return neverEndingStatus.x.next()
     

def Test1():
    for w in range(1, 100):
        sys.stderr.write('\b'+neverEndingStatus())
        for z in range(1, 10000):
            z = z + 1

def Test2():
    for y in range(1, 10):
        sys.stderr.write('\b \nTesting'+str(y)+'\t')
        Test1()
    
Test2()

However, at this point I have begun wondering why I need a generator at all
- it seems like I can do the same thing with something with something like:

def neverEndingStatus():
     try: 
          neverEndingStatus.index = (neverEndingStatus.index + 1) % 4
     except AttributeError:
          neverEndingStatus.index = 0
          neverEndingStatus.chars = r'|\-/'
     
     return neverEndingStatus.chars[neverEndingStatus.index]


Or I can borrow a generator from itertools (as per suggestion from Karl)
perhaps a bit more cleanly (although I haven't yet looked at the overhead):

import itertools

def neverEndingStatus():
     try: 
          neverEndingStatus.cycle
     except AttributeError:
          neverEndingStatus.cycle = itertools.cycle(r'|\-/')
     return neverEndingStatus.cycle.next()

So I started out saying that I wasn't quite happy with the way that a
generator function was making me code my application, and I am pretty sure
I've come to the conclusion that I didn't really want to expose a generator
function at all.  Which maybe a victory for the TOOWTDI concept...

Anyway, if anyone sees something to be concerned about in either of these
last approaches, I would appreciate hearing about it, I thank Max and Karl
for their guidance...

-jdc


On 5/7/05 10:06 AM, "Max Noel" <maxnoel_fr at yahoo.fr> wrote:

> 
> On May 7, 2005, at 13:22, John Clark wrote:
> 
>> (Either that, or I am not following what you mean when you say:
>> 
>> 
>>>      As for how to access it, use a for loop (for i in
>>> neverEndingStatus()). xrange, for example, is a generator function.
>>> 
>> 
>> Can you please provide an example of how my Test1() function
>> changes based
>> on your suggestion?  (sorry to be dense)
>> 
> 
>      Try the following code:
> 
> 
> 
> for i in neverEndingTest():
>      print i
> 
> 
>      breaking out of the infinite loop is left to the reader as an
> exercise ;)
> 
> -- Max
> maxnoel_fr at yahoo dot fr -- ICQ #85274019
> "Look at you hacker... A pathetic creature of meat and bone, panting
> and sweating as you run through my corridors... How can you challenge
> a perfect, immortal machine?"
> 





More information about the Tutor mailing list