def iter_rate(self):
        """
        pun not intended

        # TODO: record iteration times for analysis
        # TODO Incorporate this better
        # FIXME; pad_stdout into subfunctions

        import dis
        dis.dis(ut.ProgressIter.iter_rate)
        """
        #class IterState(object):
        #    def __init__(state):
        #        state.freq = 1
        #        state.freq = 1
        #        pass
        adjust = self.autoadjust
        self._cursor_at_newline = not self.backspace
        # SETUP VARIABLES
        # HACK: reaquire logging print funcs in case they have changed
        if self.stream is None:
            self.write = util_logging._utool_write()
            self.flush = util_logging._utool_flush()
        else:
            self.write = lambda msg: self.stream.write(msg)  # NOQA
            self.flush = lambda: self.stream.flush()  # NOQA

        length        = self.length * self.parent_length  # hack
        freq          = self.freq
        self.count    = 0
        between_count = 0
        last_count    = 0

        # how long iterations should be before a flush
        # (used for freq adjustment)
        time_thresh = (self._get_timethresh_heuristics()
                       if self.time_thresh is None else
                       self.time_thresh)
        time_thresh_growth = self.time_thresh_growth
        if time_thresh_growth > 1:
            # time_thresh_growth is specified for very long processes
            # print out the starting timestamp in that case
            timestamp = time.strftime('%Y-%m-%d %H:%M:%S') + ' ' + time.tzname[0]
            print('Start progress lbl= %s at %s' % (self.lbl, timestamp,))
        #time_thresh = 0.5
        max_between_time = -1.0
        max_between_count = -1.0  # why is this different? # because frequency varies

        # TODO: should be kept as a statistic that uses the max time from a
        # list of iterations divided by the size of that list that will account
        # for buffering issues
        iters_per_second = 0
        self.iters_per_second = float('nan')
        self.est_seconds_left = 0
        self.total_seconds = 0

        # Write initial message
        #force_newlines = not self.backspace
        start_msg_fmt = ''.join(self.build_msg_fmtstr_head_cols(length, self.lbl))
        self.msg_fmtstr = self.build_msg_fmtstr2(self.lbl, length,
                                                 self.invert_rate,
                                                 self.backspace)

        try:
            util_logging._utool_flush()()
        except IOError as ex:
            # There is some weird error when doing progress in IPython notebook
            if util_arg.VERBOSE:
                print('IOError flushing %s' % (ex,))
        if not self.prehack:
            if self.backspace:
                self.display_message()
            elif self.verbose:
                start_msg = start_msg_fmt.format(count=self.parent_offset)
                util_logging._utool_write()(start_msg + '\n')

            self._cursor_at_newline = not self.backspace

            try:
                util_logging._utool_flush()()
            except IOError as ex:
                # There is some weird error when doing progress in IPython notebook
                if util_arg.VERBOSE:
                    print('IOError flushing %s' % (ex,))
        else:
            self._cursor_at_newline = True

        if self.prog_hook is not None:
            self.prog_hook(self.count, length)

        # TODO: on windows is time.clock better?
        # http://exnumerus.blogspot.com/2011/02/how-to-quickly-plot-multiple-line.html
        start_time    = default_timer()
        last_time     = start_time

        start = 1 + self.parent_offset

        if self.freq_est_strat == 'between':
            FREQ_EST = 0
        elif self.freq_est_strat == 'absolute':
            FREQ_EST = 1
        else:
            FREQ_EST = 1

        USE_RECORD = True

        # use last 64 times to compute a more stable average rate
        measure_between_time = collections.deque([], maxlen=self.est_window)

        # Wrap the for loop with a generator
        for self.count, item in enumerate(self.iterable, start=start):
            if self.prehack:
                # hack to print before yeilding
                # so much for efficiency
                self.set_extra((self.lbl + '=' + self.prehack) % item)
                self.display_message()
                self.ensure_newline()

            # GENERATE
            yield item

            if self.prehack or (self.count) % freq == 0:
                now_time          = default_timer()
                between_time      = (now_time - last_time)
                between_count     = self.count - last_count
                total_seconds     = (now_time - start_time)
                self.total_seconds = total_seconds
                if FREQ_EST == 0:
                    if USE_RECORD:
                        measure_between_time.append(between_count / (float(between_time) + 1E-9))
                        iters_per_second = sum(measure_between_time) / len(measure_between_time)
                    else:
                        iters_per_second = between_count / (float(between_time) + 1E-9)
                elif FREQ_EST == 1:
                    iters_per_second = (now_time - start_time) / self.count

                self.iters_per_second = iters_per_second
                # If the future is known
                if length is None:
                    est_seconds_left = -1
                else:
                    iters_left = length - self.count
                    est_seconds_left = iters_left / (iters_per_second + 1E-9)
                self.est_seconds_left = est_seconds_left

                # /future
                last_count        = self.count
                last_time         = now_time
                # ADJUST FREQ IF NEEDED
                # Adjust frequency if printing too quickly
                # so progress doesnt slow down actual function
                # TODO: better adjust algorithm
                time_thresh *= time_thresh_growth
                if adjust and (between_time < time_thresh or between_time > time_thresh * 2.0):
                    max_between_time = max(max(max_between_time, between_time),
                                           1E-9)
                    max_between_count = max(max_between_count, between_count)
                    # If progress was uniform and all time estimates were
                    # perfect this would be the new freq to achieve time_thresh
                    new_freq = max(int(time_thresh * max_between_count /
                                       max_between_time), 1)
                    if DEBUG_FREQ_ADJUST:
                        print('\n+---')
                        print('[prog] between_count = %r' % between_count)
                        print('[prog] between_time = %.8r' % between_time)
                        print('[prog] time_thresh = %r' % time_thresh)
                        print('[prog] max_between_count = %r' % max_between_count)
                        print('[prog] max_between_time = %.8r' % max_between_time)
                        print('[prog] Adusting frequency from: %r' % freq)
                        print('[prog] Adusting frequency to: %r' % new_freq)
                        print('L___')
                    # But things are not perfect. So, don't make drastic changes
                    max_freq_change_up = max(256, freq * 2)
                    max_freq_change_down = freq // 2
                    if (new_freq - freq) > max_freq_change_up:
                        freq += max_freq_change_up
                    elif (freq - new_freq) > max_freq_change_down:
                        freq -= max_freq_change_down
                    else:
                        freq = new_freq

                if not self.prehack:
                    self.display_message()

                # DO PROGRESS INFO
                if self.prog_hook is not None:
                    # From the point of view of the progress iter, we are about
                    # to enter the body of a for loop. (But we may have
                    # executed the body implicitly in the yeild....  so it is
                    # ambiguous. In the second case 0 will be executed twice.
                    self.prog_hook(self.count, length)

        if self.prehack:
            self.set_extra('')

        # --- end of main loop
        # cleanup
        if (self.count) % freq != 0:
            # If the final line of progress was not written in the loop, write
            # it here
            self.est_seconds_left = 0
            self.total_seconds = (default_timer() - start_time)
            self.display_message()
            if self.prog_hook is not None:
                # From the point of view of the progress iter, we are about to
                # enter the body of a for loop. (But we may have executed the
                # body implicitly in the yeild....  so it is ambiguous. In the
                # second case 0 will be executed twice.
                self.prog_hook(self.count, length)

        self.ensure_newline()
def iter_rate ( self ) : adjust = self . autoadjust self . _cursor_at_newline = not self . backspace if self . stream is None : self . write = util_logging . _utool_write ( ) self . flush = util_logging . _utool_flush ( ) else : self . write = lambda msg : self . stream . write ( msg ) self . flush = lambda : self . stream . flush ( ) length = self . length * self . parent_length freq = self . freq self . count = 0 between_count = 0 last_count = 0 time_thresh = ( self . _get_timethresh_heuristics ( ) if self . time_thresh is None else self . time_thresh ) time_thresh_growth = self . time_thresh_growth if time_thresh_growth > 1 : timestamp = time . strftime ( '%Y-%m-%d %H:%M:%S' ) + ' ' + time . tzname [ 0 ] print ( 'Start progress lbl= %s at %s' % ( self . lbl , timestamp , ) ) max_between_time = - 1.0 max_between_count = - 1.0 iters_per_second = 0 self . iters_per_second = float ( 'nan' ) self . est_seconds_left = 0 self . total_seconds = 0 start_msg_fmt = '' . join ( self . build_msg_fmtstr_head_cols ( length , self . lbl ) ) self . msg_fmtstr = self . build_msg_fmtstr2 ( self . lbl , length , self . invert_rate , self . backspace ) try : util_logging . _utool_flush ( ) ( ) except IOError as ex : if util_arg . VERBOSE : print ( 'IOError flushing %s' % ( ex , ) ) if not self . prehack : if self . backspace : self . display_message ( ) elif self . verbose : start_msg = start_msg_fmt . format ( count = self . parent_offset ) util_logging . _utool_write ( ) ( start_msg + '\n' ) self . _cursor_at_newline = not self . backspace try : util_logging . _utool_flush ( ) ( ) except IOError as ex : if util_arg . VERBOSE : print ( 'IOError flushing %s' % ( ex , ) ) else : self . _cursor_at_newline = True if self . prog_hook is not None : self . prog_hook ( self . count , length ) start_time = default_timer ( ) last_time = start_time start = 1 + self . parent_offset if self . freq_est_strat == 'between' : FREQ_EST = 0 elif self . freq_est_strat == 'absolute' : FREQ_EST = 1 else : FREQ_EST = 1 USE_RECORD = True measure_between_time = collections . deque ( [ ] , maxlen = self . est_window ) for self . count , item in enumerate ( self . iterable , start = start ) : if self . prehack : self . set_extra ( ( self . lbl + '=' + self . prehack ) % item ) self . display_message ( ) self . ensure_newline ( ) yield item if self . prehack or ( self . count ) % freq == 0 : now_time = default_timer ( ) between_time = ( now_time - last_time ) between_count = self . count - last_count total_seconds = ( now_time - start_time ) self . total_seconds = total_seconds if FREQ_EST == 0 : if USE_RECORD : measure_between_time . append ( between_count / ( float ( between_time ) + 1E-9 ) ) iters_per_second = sum ( measure_between_time ) / len ( measure_between_time ) else : iters_per_second = between_count / ( float ( between_time ) + 1E-9 ) elif FREQ_EST == 1 : iters_per_second = ( now_time - start_time ) / self . count self . iters_per_second = iters_per_second if length is None : est_seconds_left = - 1 else : iters_left = length - self . count est_seconds_left = iters_left / ( iters_per_second + 1E-9 ) self . est_seconds_left = est_seconds_left last_count = self . count last_time = now_time time_thresh *= time_thresh_growth if adjust and ( between_time < time_thresh or between_time > time_thresh * 2.0 ) : max_between_time = max ( max ( max_between_time , between_time ) , 1E-9 ) max_between_count = max ( max_between_count , between_count ) new_freq = max ( int ( time_thresh * max_between_count / max_between_time ) , 1 ) if DEBUG_FREQ_ADJUST : print ( '\n+---' ) print ( '[prog] between_count = %r' % between_count ) print ( '[prog] between_time = %.8r' % between_time ) print ( '[prog] time_thresh = %r' % time_thresh ) print ( '[prog] max_between_count = %r' % max_between_count ) print ( '[prog] max_between_time = %.8r' % max_between_time ) print ( '[prog] Adusting frequency from: %r' % freq ) print ( '[prog] Adusting frequency to: %r' % new_freq ) print ( 'L___' ) max_freq_change_up = max ( 256 , freq * 2 ) max_freq_change_down = freq // 2 if ( new_freq - freq ) > max_freq_change_up : freq += max_freq_change_up elif ( freq - new_freq ) > max_freq_change_down : freq -= max_freq_change_down else : freq = new_freq if not self . prehack : self . display_message ( ) if self . prog_hook is not None : self . prog_hook ( self . count , length ) if self . prehack : self . set_extra ( '' ) if ( self . count ) % freq != 0 : self . est_seconds_left = 0 self . total_seconds = ( default_timer ( ) - start_time ) self . display_message ( ) if self . prog_hook is not None : self . prog_hook ( self . count , length ) self . ensure_newline ( )
pun not intended

        # TODO: record iteration times for analysis
        # TODO Incorporate this better
        # FIXME; pad_stdout into subfunctions

        import dis
        dis.dis(ut.ProgressIter.iter_rate)