enumerate is very useful and now "progresserate"

B

Brian Kelley

It also inspired me to write "progresserate" which returns the percent
completed of the list and the current value.

class progresserate:
def __init__(self, sequence):
self.size = float(len(sequence))
self.iterator = iter(sequence)
self.i = 0
self.last = None

def __iter__(self):
return self

def next(self):
value = self.iterator.next()
self.i += 1
percent = int(self.i/self.size * 100)
return percent, value

for percent, value in progresserate([1,2,3]):
print "percent complete", percent, "value", value

output
percent complete 33 value 1
percent complete 66 value 2
percent complete 100 value 3

This is useful for updating progress bars and the like. I use it all
the time, it sure saves code duplication.

Is this idea something that is useful enough for inclusion in the
standard library? (Not this code as-is, I don't show error checking for
brevity's sake)

One stylistic question, I tend to use
def __iter__(self): return self

when writing these styles of iterators. It kind of bugs me, is there a
better alternative?

Brian
 
F

Francis Avila

Brian Kelley wrote in message
It also inspired me to write "progresserate" which returns the percent
completed of the list and the current value.

This is useful for updating progress bars and the like. I use it all
the time, it sure saves code duplication.

Is this idea something that is useful enough for inclusion in the
standard library? (Not this code as-is, I don't show error checking for
brevity's sake)


It's very neat (I always seem to want to turn every problem into a generator
problem :). But actually, in this case (unless that error checking code you
mention forbids it), you don't need a class. The only methods you define
are for the generator protocol, and none of them have arguments. So a
generator function is enough (and undoubtably faster):

def progresserate(seq):
size = float(len(seq))
iterator = iter(seq)
i = 0
#what did self.last do?
while True: #StopIteration from iterator will propagate.
value = iterator.next()
i += 1
percent = int(i/size * 100)
yield percent, value

One stylistic question, I tend to use
def __iter__(self): return self

when writing these styles of iterators. It kind of bugs me, is there a
better alternative?

Could you be more specific? What bugs you about it?

If it's the 'self' you mean, then know that that corresponds exactly to the
behavior of iterators currently: if you request an iterator from an
iterator, it returns itself (what else would it return?). If you want a
*copy* of an iterator, you have to wait until PEP 323.
 
B

Bengt Richter

Brian Kelley wrote in message



It's very neat (I always seem to want to turn every problem into a generator
problem :). But actually, in this case (unless that error checking code you
mention forbids it), you don't need a class. The only methods you define
are for the generator protocol, and none of them have arguments. So a
generator function is enough (and undoubtably faster):

If it's being used to e.g. update a display, you can help overall speed by
returning a change flag that is only on when a new percentage is returned,
so it's easy to skip the i/o. (Of course, this makes a difference when you have
size much greater than 100) e.g., (untested changes)
def progresserate(seq):
size = float(len(seq))
iterator = iter(seq)
i = 0 percent = -1
#what did self.last do?
while True: #StopIteration from iterator will propagate.
value = iterator.next()
i += 1
percent = int(i/size * 100)
lastpc, percent = percent, int(i/size * 100 +.5)
yield percent, value
yield percent!=lastpc, percent, value
Regards,
Bengt Richter
 
B

Brian Kelley

The generator solution is better.
If it's being used to e.g. update a display, you can help overall speed by
returning a change flag that is only on when a new percentage is returned,
so it's easy to skip the i/o. (Of course, this makes a difference when you have
size much greater than 100) e.g., (untested changes)

I let the GUI control this. I.e. don't update if the last percentage
the same as the current. I'm not sure if this functionality should be
in the generator or outside.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top