enumerate is very useful and now "progresserate"

Discussion in 'Python' started by Brian Kelley, Nov 19, 2003.

  1. Brian Kelley

    Brian Kelley Guest

    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
     
    Brian Kelley, Nov 19, 2003
    #1
    1. Advertisements

  2. 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):

    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

    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.
     
    Francis Avila, Nov 19, 2003
    #2
    1. Advertisements

  3. 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)
    lastpc, percent = percent, int(i/size * 100 +.5)
    yield percent!=lastpc, percent, value
    Regards,
    Bengt Richter
     
    Bengt Richter, Nov 20, 2003
    #3
  4. Brian Kelley

    Brian Kelley Guest

    The generator solution is better.
    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.
     
    Brian Kelley, Nov 20, 2003
    #4
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.