<h3 dir="auto">Describe the workflow you want to enable</h3>
<p dir="auto">I believe it would be beneficial to integrate tqdm into GridSearchCV for more detailed and user-friendly progress tracking. While the verbose parameter provides some information, a progress bar could give users a better sense of how long the process will take. This could be particularly useful for large parameter grids that take a long time to process.</p>
<h3 dir="auto">Describe your proposed solution</h3>
<p dir="auto">One potential way to implement this would be to wrap the parameter grid in a tqdm object in the _run_search method. However, this would introduce a new dependency on tqdm, and it might not be consistent with the rest of the library's interface. I'm interested to hear the thoughts of the maintainers and other users on this idea.</p>
<h3 dir="auto">Describe alternatives you've considered, if relevant</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">Additional context</h3>
<p dir="auto"><em>No response</em></p>
<p dir="auto">I'm currently working with a fork of sklearn where I include progress bars in long running Estimators (particularly MiniBatchKmeans). It takes up to 9 hours to run some of the algorithms and having an estimated time remaining has been quite helpful to see when I should come back and look at the results.</p>
<p dir="auto">I was wondering if it would be worthwhile to compile some of these into a pull requests and add this functionality to the library. If so there are few logistics:</p>
<p dir="auto">Which progress implementation should I use? I see three options here.</p>
<ol dir="auto">
<li>I could add a dependency on the external click library and use its ProgressBar class.</li>
<li>I could port my a simplified version of my own ProgIter class into sklearn utils.</li>
<li>I could port a simplified version of click's ProgressBar class</li>
</ol>
<p dir="auto">All options essentially wrap an iterator and dump some info to stdout about how far through the iterator they are.</p>
<p dir="auto">These options are ordered from the least work to the most work. The first option is the least work, but it adds a dependency. I have experience with the second option, but it is not as widely used as click (although my port would use a more click-like signature). The third option requires me to delve into the click library, which I haven't had any experience with yet. However, judging from my initial look at its implementation it looks my implementation may be more efficient. The click implementation seems to compute and display progress information on every iteration, whereas my implementation tries to minimally impact the wrapped loop by adjusting its report frequency.</p>
<p dir="auto">Here is some example code. Previously a code block looked like this:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="        if self.verbose:
            print('Computing label assignment and total inertia')
        x_squared_norms = row_norms(X, squared=True)
        slices = gen_batches(X.shape[0], self.batch_size)
        results = [_labels_inertia(X[s], x_squared_norms[s],
                                   self.cluster_centers_) for s in slices]
        labels, inertia = zip(*results)
        return np.hstack(labels), np.sum(inertia)"><pre class="notranslate">        <span class="pl-k">if</span> <span class="pl-s1">self</span>.<span class="pl-s1">verbose</span>:
            <span class="pl-en">print</span>(<span class="pl-s">'Computing label assignment and total inertia'</span>)
        <span class="pl-s1">x_squared_norms</span> <span class="pl-c1">=</span> <span class="pl-en">row_norms</span>(<span class="pl-v">X</span>, <span class="pl-s1">squared</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
        <span class="pl-s1">slices</span> <span class="pl-c1">=</span> <span class="pl-en">gen_batches</span>(<span class="pl-v">X</span>.<span class="pl-s1">shape</span>[<span class="pl-c1">0</span>], <span class="pl-s1">self</span>.<span class="pl-s1">batch_size</span>)
        <span class="pl-s1">results</span> <span class="pl-c1">=</span> [<span class="pl-en">_labels_inertia</span>(<span class="pl-v">X</span>[<span class="pl-s1">s</span>], <span class="pl-s1">x_squared_norms</span>[<span class="pl-s1">s</span>],
                                   <span class="pl-s1">self</span>.<span class="pl-s1">cluster_centers_</span>) <span class="pl-k">for</span> <span class="pl-s1">s</span> <span class="pl-c1">in</span> <span class="pl-s1">slices</span>]
        <span class="pl-s1">labels</span>, <span class="pl-s1">inertia</span> <span class="pl-c1">=</span> <span class="pl-en">zip</span>(<span class="pl-c1">*</span><span class="pl-s1">results</span>)
        <span class="pl-k">return</span> <span class="pl-s1">np</span>.<span class="pl-en">hstack</span>(<span class="pl-s1">labels</span>), <span class="pl-s1">np</span>.<span class="pl-en">sum</span>(<span class="pl-s1">inertia</span>)</pre></div>
<p dir="auto">If I port a refactored / paired down version of my progress iterator to sklearn, then it will look something like this:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="        if self.verbose:
            print('Computing label assignment and total inertia')
        x_squared_norms = row_norms(X, squared=True)
        n_samples = X.shape[0]
        total_batches = int(n_samples // self.batch_size)
        slices = gen_batches(n_samples, self.batch_size)
        slices = ProgIter(slices, label='computing labels and inertia',
                          length=total_batches, enabled=self.verbose)
        results = [_labels_inertia(X[s], x_squared_norms[s],
                                   self.cluster_centers_) for s in slices]
        labels, inertia = zip(*results)
        return np.hstack(labels), np.sum(inertia)"><pre class="notranslate">        <span class="pl-k">if</span> <span class="pl-s1">self</span>.<span class="pl-s1">verbose</span>:
            <span class="pl-en">print</span>(<span class="pl-s">'Computing label assignment and total inertia'</span>)
        <span class="pl-s1">x_squared_norms</span> <span class="pl-c1">=</span> <span class="pl-en">row_norms</span>(<span class="pl-v">X</span>, <span class="pl-s1">squared</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
        <span class="pl-s1">n_samples</span> <span class="pl-c1">=</span> <span class="pl-v">X</span>.<span class="pl-s1">shape</span>[<span class="pl-c1">0</span>]
        <span class="pl-s1">total_batches</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-s1">n_samples</span> <span class="pl-c1">//</span> <span class="pl-s1">self</span>.<span class="pl-s1">batch_size</span>)
        <span class="pl-s1">slices</span> <span class="pl-c1">=</span> <span class="pl-en">gen_batches</span>(<span class="pl-s1">n_samples</span>, <span class="pl-s1">self</span>.<span class="pl-s1">batch_size</span>)
        <span class="pl-s1">slices</span> <span class="pl-c1">=</span> <span class="pl-v">ProgIter</span>(<span class="pl-s1">slices</span>, <span class="pl-s1">label</span><span class="pl-c1">=</span><span class="pl-s">'computing labels and inertia'</span>,
                          <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-s1">total_batches</span>, <span class="pl-s1">enabled</span><span class="pl-c1">=</span><span class="pl-s1">self</span>.<span class="pl-s1">verbose</span>)
        <span class="pl-s1">results</span> <span class="pl-c1">=</span> [<span class="pl-en">_labels_inertia</span>(<span class="pl-v">X</span>[<span class="pl-s1">s</span>], <span class="pl-s1">x_squared_norms</span>[<span class="pl-s1">s</span>],
                                   <span class="pl-s1">self</span>.<span class="pl-s1">cluster_centers_</span>) <span class="pl-k">for</span> <span class="pl-s1">s</span> <span class="pl-c1">in</span> <span class="pl-s1">slices</span>]
        <span class="pl-s1">labels</span>, <span class="pl-s1">inertia</span> <span class="pl-c1">=</span> <span class="pl-en">zip</span>(<span class="pl-c1">*</span><span class="pl-s1">results</span>)
        <span class="pl-k">return</span> <span class="pl-s1">np</span>.<span class="pl-en">hstack</span>(<span class="pl-s1">labels</span>), <span class="pl-s1">np</span>.<span class="pl-en">sum</span>(<span class="pl-s1">inertia</span>)</pre></div>
<p dir="auto">Here is a mockup of the simplified ProgIter object. I paired it down rather quickly, so there may be some small issue in this version.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from __future__ import absolute_import, division, print_function, unicode_literals
import sys
import time
import datetime
import collections
import six

WIN32 = sys.platform.startswith('win32')

if WIN32:
    # Use time.clock in win32
    default_timer = time.clock
    BEFORE_BAR = '\r'
    AFTER_BAR = '\n'
else:
    default_timer = time.time
    BEFORE_BAR = '\r\033[?25l'
    AFTER_BAR = '\033[?25h\n'

text_type = six.text_type

class ProgIter(object):
    def __init__(self, iterable=None, label=None, length=None, enabled=True,
                 freq=1, adjust=True, eta_window=64):
        if length is None:
            try:
                length = len(iterable)
            except Exception:
                pass
        if label is None:
            label = ''
        self.iterable = iterable
        self.label = label
        self.length = length
        self.freq = freq
        self.enabled = enabled
        self.adjust = adjust
        self.count = 0
        # Window size for estimated time remaining
        self.eta_window = eta_window

    def __call__(self, iterable):
        self.iterable = iterable
        return self

    def __iter__(self):
        if not self.enabled:
            return iter(self.iterable)
        else:
            return self.iter_rate()

    def build_msg_fmtstr(self):
        with_wall = True
        tzname = time.tzname[0]
        length_ = '?' if self.length == 0 else text_type(self.length)
        msg_head = ['', self.label, ' {count:4d}/', length_ , '...  ']
        msg_tail = [
            ('rate={rate:4.2f} Hz,'),
            ('' if self.length == 0 else ' eta={eta},'),
            ' ellapsed={ellapsed},',
            (' wall={wall} ' + tzname if with_wall else ''),
        ]
        msg_fmtstr_time = ''.join(([BEFORE_BAR] + msg_head + msg_tail))
        return msg_fmtstr_time

    def tryflush(self):
        try:
            # flush sometimes causes issues in IPython notebooks
            sys.stdout.flush()
        except IOError:
            pass

    def write(self, msg):
        sys.stdout.write(msg)

    def iter_rate(self):
        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 = 2.0

        max_between_time = -1.0
        max_between_count = -1.0

        iters_per_second = -1

        # Prepare for iteration
        msg_fmtstr = self.build_msg_fmtstr()

        self.tryflush()

        msg = msg_fmtstr.format(
            count=self.count, rate=0.0,
            eta=text_type('0:00:00'),
            ellapsed=text_type('0:00:00'),
            wall=time.strftime('%H:%M'),
        )
        self.write(msg)

        self.tryflush()

        start_time = default_timer()
        last_time  = start_time

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

        # Wrap the for loop with a generator
        for self.count, item in enumerate(self.iterable, start=1):
            yield item

            if (self.count) % freq == 0:
                # update progress information every so often
                now_time          = default_timer()
                between_time      = (now_time - last_time)
                between_count     = self.count - last_count
                total_seconds     = (now_time - start_time)

                measure_between_time.append(between_count / (float(between_time) + 1E-9))
                iters_per_second = sum(measure_between_time) / len(measure_between_time)

                if self.length is None:
                    est_seconds_left = -1
                else:
                    iters_left = self.length - self.count
                    est_eta = iters_left / (iters_per_second + 1E-9)

                    measure_est_seconds.append(est_eta)
                    est_seconds_left = sum(measure_est_seconds) / len(measure_est_seconds)

                last_count = self.count
                last_time  = now_time
                # Adjust frequency if printing too quickly
                # so progress doesnt slow down actual function
                if self.adjust and (between_time &lt; time_thresh or
                                    between_time &gt; time_thresh * 2.0):
                    max_between_time = max(max_between_time, between_time)
                    max_between_time = max(max_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 = int(time_thresh * max_between_count / max_between_time)
                    new_freq = max(new_freq, 1)
                    # 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) &gt; max_freq_change_up:
                        freq += max_freq_change_up
                    elif (freq - new_freq) &gt; max_freq_change_down:
                        freq -= max_freq_change_down
                    else:
                        freq = new_freq
                msg = msg_fmtstr.format(
                    count=self.count,
                    rate=iters_per_second,
                    eta=text_type(datetime.timedelta(seconds=int(est_seconds_left))),
                    ellapsed=text_type(datetime.timedelta(seconds=int(total_seconds))),
                    wall=time.strftime('%H:%M'),
                )
                self.write(msg)
                self.tryflush()

        if (self.count) % freq != 0:
            # Write the final progress line if it was not written in the loop
            est_seconds_left = 0
            now_time = default_timer()
            total_seconds = (now_time - start_time)
            msg = msg_fmtstr.format(
                count=self.count,
                rate=iters_per_second,
                eta=text_type(datetime.timedelta(seconds=int(est_seconds_left))),
                ellapsed=text_type(datetime.timedelta(seconds=int(total_seconds))),
                wall=time.strftime('%H:%M'),
            )
            self.write(msg)
            self.tryflush()
        self.write(AFTER_BAR)"><pre class="notranslate"><span class="pl-k">from</span> __future__ <span class="pl-k">import</span> <span class="pl-s1">absolute_import</span>, <span class="pl-s1">division</span>, <span class="pl-s1">print_function</span>, <span class="pl-s1">unicode_literals</span>
<span class="pl-k">import</span> <span class="pl-s1">sys</span>
<span class="pl-k">import</span> <span class="pl-s1">time</span>
<span class="pl-k">import</span> <span class="pl-s1">datetime</span>
<span class="pl-k">import</span> <span class="pl-s1">collections</span>
<span class="pl-k">import</span> <span class="pl-s1">six</span>

<span class="pl-v">WIN32</span> <span class="pl-c1">=</span> <span class="pl-s1">sys</span>.<span class="pl-s1">platform</span>.<span class="pl-en">startswith</span>(<span class="pl-s">'win32'</span>)

<span class="pl-k">if</span> <span class="pl-v">WIN32</span>:
    <span class="pl-c"># Use time.clock in win32</span>
    <span class="pl-s1">default_timer</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-s1">clock</span>
    <span class="pl-v">BEFORE_BAR</span> <span class="pl-c1">=</span> <span class="pl-s">'<span class="pl-cce">\r</span>'</span>
    <span class="pl-v">AFTER_BAR</span> <span class="pl-c1">=</span> <span class="pl-s">'<span class="pl-cce">\n</span>'</span>
<span class="pl-k">else</span>:
    <span class="pl-s1">default_timer</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-s1">time</span>
    <span class="pl-v">BEFORE_BAR</span> <span class="pl-c1">=</span> <span class="pl-s">'<span class="pl-cce">\r</span><span class="pl-cce">\033</span>[?25l'</span>
    <span class="pl-v">AFTER_BAR</span> <span class="pl-c1">=</span> <span class="pl-s">'<span class="pl-cce">\033</span>[?25h<span class="pl-cce">\n</span>'</span>

<span class="pl-s1">text_type</span> <span class="pl-c1">=</span> <span class="pl-s1">six</span>.<span class="pl-s1">text_type</span>

<span class="pl-k">class</span> <span class="pl-v">ProgIter</span>(<span class="pl-s1">object</span>):
    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">iterable</span><span class="pl-c1">=</span><span class="pl-c1">None</span>, <span class="pl-s1">label</span><span class="pl-c1">=</span><span class="pl-c1">None</span>, <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-c1">None</span>, <span class="pl-s1">enabled</span><span class="pl-c1">=</span><span class="pl-c1">True</span>,
                 <span class="pl-s1">freq</span><span class="pl-c1">=</span><span class="pl-c1">1</span>, <span class="pl-s1">adjust</span><span class="pl-c1">=</span><span class="pl-c1">True</span>, <span class="pl-s1">eta_window</span><span class="pl-c1">=</span><span class="pl-c1">64</span>):
        <span class="pl-k">if</span> <span class="pl-s1">length</span> <span class="pl-c1">is</span> <span class="pl-c1">None</span>:
            <span class="pl-k">try</span>:
                <span class="pl-s1">length</span> <span class="pl-c1">=</span> <span class="pl-en">len</span>(<span class="pl-s1">iterable</span>)
            <span class="pl-k">except</span> <span class="pl-v">Exception</span>:
                <span class="pl-k">pass</span>
        <span class="pl-k">if</span> <span class="pl-s1">label</span> <span class="pl-c1">is</span> <span class="pl-c1">None</span>:
            <span class="pl-s1">label</span> <span class="pl-c1">=</span> <span class="pl-s">''</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">iterable</span> <span class="pl-c1">=</span> <span class="pl-s1">iterable</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">label</span> <span class="pl-c1">=</span> <span class="pl-s1">label</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">length</span> <span class="pl-c1">=</span> <span class="pl-s1">length</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">freq</span> <span class="pl-c1">=</span> <span class="pl-s1">freq</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">enabled</span> <span class="pl-c1">=</span> <span class="pl-s1">enabled</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">adjust</span> <span class="pl-c1">=</span> <span class="pl-s1">adjust</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">count</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>
        <span class="pl-c"># Window size for estimated time remaining</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">eta_window</span> <span class="pl-c1">=</span> <span class="pl-s1">eta_window</span>

    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">iterable</span>):
        <span class="pl-s1">self</span>.<span class="pl-s1">iterable</span> <span class="pl-c1">=</span> <span class="pl-s1">iterable</span>
        <span class="pl-k">return</span> <span class="pl-s1">self</span>

    <span class="pl-k">def</span> <span class="pl-en">__iter__</span>(<span class="pl-s1">self</span>):
        <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-s1">self</span>.<span class="pl-s1">enabled</span>:
            <span class="pl-k">return</span> <span class="pl-en">iter</span>(<span class="pl-s1">self</span>.<span class="pl-s1">iterable</span>)
        <span class="pl-k">else</span>:
            <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">iter_rate</span>()

    <span class="pl-k">def</span> <span class="pl-en">build_msg_fmtstr</span>(<span class="pl-s1">self</span>):
        <span class="pl-s1">with_wall</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>
        <span class="pl-s1">tzname</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-s1">tzname</span>[<span class="pl-c1">0</span>]
        <span class="pl-s1">length_</span> <span class="pl-c1">=</span> <span class="pl-s">'?'</span> <span class="pl-k">if</span> <span class="pl-s1">self</span>.<span class="pl-s1">length</span> <span class="pl-c1">==</span> <span class="pl-c1">0</span> <span class="pl-k">else</span> <span class="pl-en">text_type</span>(<span class="pl-s1">self</span>.<span class="pl-s1">length</span>)
        <span class="pl-s1">msg_head</span> <span class="pl-c1">=</span> [<span class="pl-s">''</span>, <span class="pl-s1">self</span>.<span class="pl-s1">label</span>, <span class="pl-s">' {count:4d}/'</span>, <span class="pl-s1">length_</span> , <span class="pl-s">'...  '</span>]
        <span class="pl-s1">msg_tail</span> <span class="pl-c1">=</span> [
            (<span class="pl-s">'rate={rate:4.2f} Hz,'</span>),
            (<span class="pl-s">''</span> <span class="pl-k">if</span> <span class="pl-s1">self</span>.<span class="pl-s1">length</span> <span class="pl-c1">==</span> <span class="pl-c1">0</span> <span class="pl-k">else</span> <span class="pl-s">' eta={eta},'</span>),
            <span class="pl-s">' ellapsed={ellapsed},'</span>,
            (<span class="pl-s">' wall={wall} '</span> <span class="pl-c1">+</span> <span class="pl-s1">tzname</span> <span class="pl-k">if</span> <span class="pl-s1">with_wall</span> <span class="pl-k">else</span> <span class="pl-s">''</span>),
        ]
        <span class="pl-s1">msg_fmtstr_time</span> <span class="pl-c1">=</span> <span class="pl-s">''</span>.<span class="pl-en">join</span>(([<span class="pl-v">BEFORE_BAR</span>] <span class="pl-c1">+</span> <span class="pl-s1">msg_head</span> <span class="pl-c1">+</span> <span class="pl-s1">msg_tail</span>))
        <span class="pl-k">return</span> <span class="pl-s1">msg_fmtstr_time</span>

    <span class="pl-k">def</span> <span class="pl-en">tryflush</span>(<span class="pl-s1">self</span>):
        <span class="pl-k">try</span>:
            <span class="pl-c"># flush sometimes causes issues in IPython notebooks</span>
            <span class="pl-s1">sys</span>.<span class="pl-s1">stdout</span>.<span class="pl-en">flush</span>()
        <span class="pl-k">except</span> <span class="pl-v">IOError</span>:
            <span class="pl-k">pass</span>

    <span class="pl-k">def</span> <span class="pl-en">write</span>(<span class="pl-s1">self</span>, <span class="pl-s1">msg</span>):
        <span class="pl-s1">sys</span>.<span class="pl-s1">stdout</span>.<span class="pl-en">write</span>(<span class="pl-s1">msg</span>)

    <span class="pl-k">def</span> <span class="pl-en">iter_rate</span>(<span class="pl-s1">self</span>):
        <span class="pl-s1">freq</span>          <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-s1">freq</span>
        <span class="pl-s1">self</span>.<span class="pl-s1">count</span>    <span class="pl-c1">=</span> <span class="pl-c1">0</span>
        <span class="pl-s1">between_count</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>
        <span class="pl-s1">last_count</span>    <span class="pl-c1">=</span> <span class="pl-c1">0</span>

        <span class="pl-c"># how long iterations should be before a flush</span>
        <span class="pl-c"># (used for freq adjustment)</span>
        <span class="pl-s1">time_thresh</span> <span class="pl-c1">=</span> <span class="pl-c1">2.0</span>

        <span class="pl-s1">max_between_time</span> <span class="pl-c1">=</span> <span class="pl-c1">-</span><span class="pl-c1">1.0</span>
        <span class="pl-s1">max_between_count</span> <span class="pl-c1">=</span> <span class="pl-c1">-</span><span class="pl-c1">1.0</span>

        <span class="pl-s1">iters_per_second</span> <span class="pl-c1">=</span> <span class="pl-c1">-</span><span class="pl-c1">1</span>

        <span class="pl-c"># Prepare for iteration</span>
        <span class="pl-s1">msg_fmtstr</span> <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-en">build_msg_fmtstr</span>()

        <span class="pl-s1">self</span>.<span class="pl-en">tryflush</span>()

        <span class="pl-s1">msg</span> <span class="pl-c1">=</span> <span class="pl-s1">msg_fmtstr</span>.<span class="pl-en">format</span>(
            <span class="pl-s1">count</span><span class="pl-c1">=</span><span class="pl-s1">self</span>.<span class="pl-s1">count</span>, <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-c1">0.0</span>,
            <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-en">text_type</span>(<span class="pl-s">'0:00:00'</span>),
            <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-en">text_type</span>(<span class="pl-s">'0:00:00'</span>),
            <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-s1">time</span>.<span class="pl-en">strftime</span>(<span class="pl-s">'%H:%M'</span>),
        )
        <span class="pl-s1">self</span>.<span class="pl-en">write</span>(<span class="pl-s1">msg</span>)

        <span class="pl-s1">self</span>.<span class="pl-en">tryflush</span>()

        <span class="pl-s1">start_time</span> <span class="pl-c1">=</span> <span class="pl-en">default_timer</span>()
        <span class="pl-s1">last_time</span>  <span class="pl-c1">=</span> <span class="pl-s1">start_time</span>

        <span class="pl-c"># use last few (64) times to compute a more stable average rate</span>
        <span class="pl-s1">measure_between_time</span> <span class="pl-c1">=</span> <span class="pl-s1">collections</span>.<span class="pl-en">deque</span>([], <span class="pl-s1">maxlen</span><span class="pl-c1">=</span><span class="pl-s1">self</span>.<span class="pl-s1">eta_window</span>)
        <span class="pl-s1">measure_est_seconds</span> <span class="pl-c1">=</span> <span class="pl-s1">collections</span>.<span class="pl-en">deque</span>([], <span class="pl-s1">maxlen</span><span class="pl-c1">=</span><span class="pl-s1">self</span>.<span class="pl-s1">eta_window</span>)

        <span class="pl-c"># Wrap the for loop with a generator</span>
        <span class="pl-k">for</span> <span class="pl-s1">self</span>.<span class="pl-s1">count</span>, <span class="pl-s1">item</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">self</span>.<span class="pl-s1">iterable</span>, <span class="pl-s1">start</span><span class="pl-c1">=</span><span class="pl-c1">1</span>):
            <span class="pl-k">yield</span> <span class="pl-s1">item</span>

            <span class="pl-k">if</span> (<span class="pl-s1">self</span>.<span class="pl-s1">count</span>) <span class="pl-c1">%</span> <span class="pl-s1">freq</span> <span class="pl-c1">==</span> <span class="pl-c1">0</span>:
                <span class="pl-c"># update progress information every so often</span>
                <span class="pl-s1">now_time</span>          <span class="pl-c1">=</span> <span class="pl-en">default_timer</span>()
                <span class="pl-s1">between_time</span>      <span class="pl-c1">=</span> (<span class="pl-s1">now_time</span> <span class="pl-c1">-</span> <span class="pl-s1">last_time</span>)
                <span class="pl-s1">between_count</span>     <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-s1">count</span> <span class="pl-c1">-</span> <span class="pl-s1">last_count</span>
                <span class="pl-s1">total_seconds</span>     <span class="pl-c1">=</span> (<span class="pl-s1">now_time</span> <span class="pl-c1">-</span> <span class="pl-s1">start_time</span>)

                <span class="pl-s1">measure_between_time</span>.<span class="pl-en">append</span>(<span class="pl-s1">between_count</span> <span class="pl-c1">/</span> (<span class="pl-en">float</span>(<span class="pl-s1">between_time</span>) <span class="pl-c1">+</span> <span class="pl-c1">1E-9</span>))
                <span class="pl-s1">iters_per_second</span> <span class="pl-c1">=</span> <span class="pl-en">sum</span>(<span class="pl-s1">measure_between_time</span>) <span class="pl-c1">/</span> <span class="pl-en">len</span>(<span class="pl-s1">measure_between_time</span>)

                <span class="pl-k">if</span> <span class="pl-s1">self</span>.<span class="pl-s1">length</span> <span class="pl-c1">is</span> <span class="pl-c1">None</span>:
                    <span class="pl-s1">est_seconds_left</span> <span class="pl-c1">=</span> <span class="pl-c1">-</span><span class="pl-c1">1</span>
                <span class="pl-k">else</span>:
                    <span class="pl-s1">iters_left</span> <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-s1">length</span> <span class="pl-c1">-</span> <span class="pl-s1">self</span>.<span class="pl-s1">count</span>
                    <span class="pl-s1">est_eta</span> <span class="pl-c1">=</span> <span class="pl-s1">iters_left</span> <span class="pl-c1">/</span> (<span class="pl-s1">iters_per_second</span> <span class="pl-c1">+</span> <span class="pl-c1">1E-9</span>)

                    <span class="pl-s1">measure_est_seconds</span>.<span class="pl-en">append</span>(<span class="pl-s1">est_eta</span>)
                    <span class="pl-s1">est_seconds_left</span> <span class="pl-c1">=</span> <span class="pl-en">sum</span>(<span class="pl-s1">measure_est_seconds</span>) <span class="pl-c1">/</span> <span class="pl-en">len</span>(<span class="pl-s1">measure_est_seconds</span>)

                <span class="pl-s1">last_count</span> <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-s1">count</span>
                <span class="pl-s1">last_time</span>  <span class="pl-c1">=</span> <span class="pl-s1">now_time</span>
                <span class="pl-c"># Adjust frequency if printing too quickly</span>
                <span class="pl-c"># so progress doesnt slow down actual function</span>
                <span class="pl-k">if</span> <span class="pl-s1">self</span>.<span class="pl-s1">adjust</span> <span class="pl-c1">and</span> (<span class="pl-s1">between_time</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">time_thresh</span> <span class="pl-c1">or</span>
                                    <span class="pl-s1">between_time</span> <span class="pl-c1">&gt;</span> <span class="pl-s1">time_thresh</span> <span class="pl-c1">*</span> <span class="pl-c1">2.0</span>):
                    <span class="pl-s1">max_between_time</span> <span class="pl-c1">=</span> <span class="pl-en">max</span>(<span class="pl-s1">max_between_time</span>, <span class="pl-s1">between_time</span>)
                    <span class="pl-s1">max_between_time</span> <span class="pl-c1">=</span> <span class="pl-en">max</span>(<span class="pl-s1">max_between_time</span>, <span class="pl-c1">1E-9</span>)
                    <span class="pl-s1">max_between_count</span> <span class="pl-c1">=</span> <span class="pl-en">max</span>(<span class="pl-s1">max_between_count</span>, <span class="pl-s1">between_count</span>)
                    <span class="pl-c"># If progress was uniform and all time estimates were</span>
                    <span class="pl-c"># perfect this would be the new freq to achieve time_thresh</span>
                    <span class="pl-s1">new_freq</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-s1">time_thresh</span> <span class="pl-c1">*</span> <span class="pl-s1">max_between_count</span> <span class="pl-c1">/</span> <span class="pl-s1">max_between_time</span>)
                    <span class="pl-s1">new_freq</span> <span class="pl-c1">=</span> <span class="pl-en">max</span>(<span class="pl-s1">new_freq</span>, <span class="pl-c1">1</span>)
                    <span class="pl-c"># But things are not perfect. So, don't make drastic changes</span>
                    <span class="pl-s1">max_freq_change_up</span> <span class="pl-c1">=</span> <span class="pl-en">max</span>(<span class="pl-c1">256</span>, <span class="pl-s1">freq</span> <span class="pl-c1">*</span> <span class="pl-c1">2</span>)
                    <span class="pl-s1">max_freq_change_down</span> <span class="pl-c1">=</span> <span class="pl-s1">freq</span> <span class="pl-c1">//</span> <span class="pl-c1">2</span>
                    <span class="pl-k">if</span> (<span class="pl-s1">new_freq</span> <span class="pl-c1">-</span> <span class="pl-s1">freq</span>) <span class="pl-c1">&gt;</span> <span class="pl-s1">max_freq_change_up</span>:
                        <span class="pl-s1">freq</span> <span class="pl-c1">+=</span> <span class="pl-s1">max_freq_change_up</span>
                    <span class="pl-k">elif</span> (<span class="pl-s1">freq</span> <span class="pl-c1">-</span> <span class="pl-s1">new_freq</span>) <span class="pl-c1">&gt;</span> <span class="pl-s1">max_freq_change_down</span>:
                        <span class="pl-s1">freq</span> <span class="pl-c1">-=</span> <span class="pl-s1">max_freq_change_down</span>
                    <span class="pl-k">else</span>:
                        <span class="pl-s1">freq</span> <span class="pl-c1">=</span> <span class="pl-s1">new_freq</span>
                <span class="pl-s1">msg</span> <span class="pl-c1">=</span> <span class="pl-s1">msg_fmtstr</span>.<span class="pl-en">format</span>(
                    <span class="pl-s1">count</span><span class="pl-c1">=</span><span class="pl-s1">self</span>.<span class="pl-s1">count</span>,
                    <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-s1">iters_per_second</span>,
                    <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-en">text_type</span>(<span class="pl-s1">datetime</span>.<span class="pl-en">timedelta</span>(<span class="pl-s1">seconds</span><span class="pl-c1">=</span><span class="pl-en">int</span>(<span class="pl-s1">est_seconds_left</span>))),
                    <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-en">text_type</span>(<span class="pl-s1">datetime</span>.<span class="pl-en">timedelta</span>(<span class="pl-s1">seconds</span><span class="pl-c1">=</span><span class="pl-en">int</span>(<span class="pl-s1">total_seconds</span>))),
                    <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-s1">time</span>.<span class="pl-en">strftime</span>(<span class="pl-s">'%H:%M'</span>),
                )
                <span class="pl-s1">self</span>.<span class="pl-en">write</span>(<span class="pl-s1">msg</span>)
                <span class="pl-s1">self</span>.<span class="pl-en">tryflush</span>()

        <span class="pl-k">if</span> (<span class="pl-s1">self</span>.<span class="pl-s1">count</span>) <span class="pl-c1">%</span> <span class="pl-s1">freq</span> <span class="pl-c1">!=</span> <span class="pl-c1">0</span>:
            <span class="pl-c"># Write the final progress line if it was not written in the loop</span>
            <span class="pl-s1">est_seconds_left</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>
            <span class="pl-s1">now_time</span> <span class="pl-c1">=</span> <span class="pl-en">default_timer</span>()
            <span class="pl-s1">total_seconds</span> <span class="pl-c1">=</span> (<span class="pl-s1">now_time</span> <span class="pl-c1">-</span> <span class="pl-s1">start_time</span>)
            <span class="pl-s1">msg</span> <span class="pl-c1">=</span> <span class="pl-s1">msg_fmtstr</span>.<span class="pl-en">format</span>(
                <span class="pl-s1">count</span><span class="pl-c1">=</span><span class="pl-s1">self</span>.<span class="pl-s1">count</span>,
                <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-s1">iters_per_second</span>,
                <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-en">text_type</span>(<span class="pl-s1">datetime</span>.<span class="pl-en">timedelta</span>(<span class="pl-s1">seconds</span><span class="pl-c1">=</span><span class="pl-en">int</span>(<span class="pl-s1">est_seconds_left</span>))),
                <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-en">text_type</span>(<span class="pl-s1">datetime</span>.<span class="pl-en">timedelta</span>(<span class="pl-s1">seconds</span><span class="pl-c1">=</span><span class="pl-en">int</span>(<span class="pl-s1">total_seconds</span>))),
                <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-s1">time</span>.<span class="pl-en">strftime</span>(<span class="pl-s">'%H:%M'</span>),
            )
            <span class="pl-s1">self</span>.<span class="pl-en">write</span>(<span class="pl-s1">msg</span>)
            <span class="pl-s1">self</span>.<span class="pl-en">tryflush</span>()
        <span class="pl-s1">self</span>.<span class="pl-en">write</span>(<span class="pl-v">AFTER_BAR</span>)</pre></div>
<p dir="auto">Here is an example showing what this does:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Define a function that takes some time
def is_prime(n):
    return n &gt;= 2 and not any(n % i == 0 for i in range(2, n))
N = 50000

# Default behavior adjusts frequency of progress reporting so
# the performance of the loop is minimally impacted
iterable = (is_prime(n) for n in range(N))
piterable = ProgIter(iterable, length=N)
_ = list(piterable)
 50000/50000...  rate=25097.04 Hz, eta=0:00:00, ellapsed=0:00:22, wall=11:22 EST

# Adjustments can be turned off to give constant feedback
iterable = (is_prime(n) for n in range(N))
piterable = ProgIter(iterable, length=N, adjust=False, freq=100)
_ = list(piterable)
  2200/50000...  rate=32500.44 Hz, eta=0:00:01, ellapsed=0:00:00, wall=11:23 EST
43300/50000...    rate=1398.73 Hz, eta=0:00:06, ellapsed=0:00:18, wall=11:23 EST
50000/50000...  rate=1129.99 Hz, eta=0:00:02, ellapsed=0:00:25, wall=11:25 EST

# only one line of the above output is shown at a time, I copied different points from a few runs 
# to illustrate the output. "><pre class="notranslate"><span class="pl-c"># Define a function that takes some time</span>
<span class="pl-k">def</span> <span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>):
    <span class="pl-k">return</span> <span class="pl-s1">n</span> <span class="pl-c1">&gt;=</span> <span class="pl-c1">2</span> <span class="pl-c1">and</span> <span class="pl-c1">not</span> <span class="pl-en">any</span>(<span class="pl-s1">n</span> <span class="pl-c1">%</span> <span class="pl-s1">i</span> <span class="pl-c1">==</span> <span class="pl-c1">0</span> <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">2</span>, <span class="pl-s1">n</span>))
<span class="pl-v">N</span> <span class="pl-c1">=</span> <span class="pl-c1">50000</span>

<span class="pl-c"># Default behavior adjusts frequency of progress reporting so</span>
<span class="pl-c"># the performance of the loop is minimally impacted</span>
<span class="pl-s1">iterable</span> <span class="pl-c1">=</span> (<span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>) <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-v">N</span>))
<span class="pl-s1">piterable</span> <span class="pl-c1">=</span> <span class="pl-v">ProgIter</span>(<span class="pl-s1">iterable</span>, <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-v">N</span>)
<span class="pl-s1">_</span> <span class="pl-c1">=</span> <span class="pl-en">list</span>(<span class="pl-s1">piterable</span>)
 <span class="pl-c1">50000</span><span class="pl-c1">/</span><span class="pl-c1">50000.</span>..  <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-c1">25097.04</span> <span class="pl-v">Hz</span>, <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">00</span>, <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">22</span>, <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-c1">11</span>:<span class="pl-c1">22</span> <span class="pl-v">EST</span>

<span class="pl-c"># Adjustments can be turned off to give constant feedback</span>
<span class="pl-s1">iterable</span> <span class="pl-c1">=</span> (<span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>) <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-v">N</span>))
<span class="pl-s1">piterable</span> <span class="pl-c1">=</span> <span class="pl-v">ProgIter</span>(<span class="pl-s1">iterable</span>, <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-v">N</span>, <span class="pl-s1">adjust</span><span class="pl-c1">=</span><span class="pl-c1">False</span>, <span class="pl-s1">freq</span><span class="pl-c1">=</span><span class="pl-c1">100</span>)
<span class="pl-s1">_</span> <span class="pl-c1">=</span> <span class="pl-en">list</span>(<span class="pl-s1">piterable</span>)
  <span class="pl-c1">2200</span><span class="pl-c1">/</span><span class="pl-c1">50000.</span>..  <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-c1">32500.44</span> <span class="pl-v">Hz</span>, <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">01</span>, <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">00</span>, <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-c1">11</span>:<span class="pl-c1">23</span> <span class="pl-v">EST</span>
<span class="pl-c1">43300</span><span class="pl-c1">/</span><span class="pl-c1">50000.</span>..    <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-c1">1398.73</span> <span class="pl-v">Hz</span>, <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">06</span>, <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">18</span>, <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-c1">11</span>:<span class="pl-c1">23</span> <span class="pl-v">EST</span>
<span class="pl-c1">50000</span><span class="pl-c1">/</span><span class="pl-c1">50000.</span>..  <span class="pl-s1">rate</span><span class="pl-c1">=</span><span class="pl-c1">1129.99</span> <span class="pl-v">Hz</span>, <span class="pl-s1">eta</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">02</span>, <span class="pl-s1">ellapsed</span><span class="pl-c1">=</span><span class="pl-c1">0</span>:<span class="pl-c1">00</span>:<span class="pl-c1">25</span>, <span class="pl-s1">wall</span><span class="pl-c1">=</span><span class="pl-c1">11</span>:<span class="pl-c1">25</span> <span class="pl-v">EST</span>

<span class="pl-c"># only one line of the above output is shown at a time, I copied different points from a few runs </span>
<span class="pl-c"># to illustrate the output. </span></pre></div>
<p dir="auto">Lastly here is some timeit information that shows how frequency adjusting causes minimal overhead</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="def is_prime(n):
    return n &gt;= 2 and not any(n % i == 0 for i in range(2, n))

N = 1000

# Test time of raw loop without any fanciness 
%timeit list((is_prime(n) for n in range(N)))
100 loops, best of 3: 10 ms per loop

# Test time of raw loop when printing on every iteration
%timeit list(ProgIter((is_prime(n) for n in range(N)), length=N, freq=1, adjust=False))
10 loops, best of 3: 159 ms per loop

# Test time of raw loop when printing based on an adjusted schedule 
%timeit list(ProgIter((is_prime(n) for n in range(N)), length=N, freq=1, adjust=True))
100 loops, best of 3: 11 ms per loop

"><pre class="notranslate"><span class="pl-k">def</span> <span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>):
    <span class="pl-k">return</span> <span class="pl-s1">n</span> <span class="pl-c1">&gt;=</span> <span class="pl-c1">2</span> <span class="pl-c1">and</span> <span class="pl-c1">not</span> <span class="pl-en">any</span>(<span class="pl-s1">n</span> <span class="pl-c1">%</span> <span class="pl-s1">i</span> <span class="pl-c1">==</span> <span class="pl-c1">0</span> <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">2</span>, <span class="pl-s1">n</span>))

<span class="pl-v">N</span> <span class="pl-c1">=</span> <span class="pl-c1">1000</span>

<span class="pl-c"># Test time of raw loop without any fanciness </span>
<span class="pl-c1">%</span><span class="pl-s1">timeit</span> <span class="pl-en">list</span>((<span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>) <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-v">N</span>)))
<span class="pl-c1">100</span> <span class="pl-s1">loops</span>, <span class="pl-s1">best</span> <span class="pl-s1">of</span> <span class="pl-c1">3</span>: <span class="pl-c1">10</span> <span class="pl-s1">ms</span> <span class="pl-s1">per</span> <span class="pl-s1">loop</span>

<span class="pl-c"># Test time of raw loop when printing on every iteration</span>
<span class="pl-c1">%</span><span class="pl-s1">timeit</span> <span class="pl-en">list</span>(<span class="pl-v">ProgIter</span>((<span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>) <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-v">N</span>)), <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-v">N</span>, <span class="pl-s1">freq</span><span class="pl-c1">=</span><span class="pl-c1">1</span>, <span class="pl-s1">adjust</span><span class="pl-c1">=</span><span class="pl-c1">False</span>))
<span class="pl-c1">10</span> <span class="pl-s1">loops</span>, <span class="pl-s1">best</span> <span class="pl-s1">of</span> <span class="pl-c1">3</span>: <span class="pl-c1">159</span> <span class="pl-s1">ms</span> <span class="pl-s1">per</span> <span class="pl-s1">loop</span>

<span class="pl-c"># Test time of raw loop when printing based on an adjusted schedule </span>
<span class="pl-c1">%</span><span class="pl-s1">timeit</span> <span class="pl-en">list</span>(<span class="pl-v">ProgIter</span>((<span class="pl-en">is_prime</span>(<span class="pl-s1">n</span>) <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-v">N</span>)), <span class="pl-s1">length</span><span class="pl-c1">=</span><span class="pl-v">N</span>, <span class="pl-s1">freq</span><span class="pl-c1">=</span><span class="pl-c1">1</span>, <span class="pl-s1">adjust</span><span class="pl-c1">=</span><span class="pl-c1">True</span>))
<span class="pl-c1">100</span> <span class="pl-s1">loops</span>, <span class="pl-s1">best</span> <span class="pl-s1">of</span> <span class="pl-c1">3</span>: <span class="pl-c1">11</span> <span class="pl-s1">ms</span> <span class="pl-s1">per</span> <span class="pl-s1">loop</span>
</pre></div>