Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Real Time Progress Bar in console

by liverpole (Monsignor)
on Oct 09, 2010 at 17:29 UTC ( #864405=note: print w/ replies, xml ) Need Help??


in reply to Real Time Progress Bar in console

Corion hit the nail on the head.

The brief answer is -- make your standard output (STDOUT) flush immediately. To do so, add this line near the beginning of your script (before doing any print statments):

$| = 1;

The corresponding section from the article Corion linked to is the one entitled "Disabling Inappropriate Buffering", where it talks about making the "filehandle hot".

If you have use for a really fancy ascii-oriented progress bar, here is something I wrote that I've found useful in a lot of different applications:

# # progress_bar # # Input: $1 - A message to display with the progress bar. It can co +ntain # any of the following special 3-character strings, each + of which # will be converted to the following value: # # <b> - the progress bar itself # <c> - the current count # <p> - the percentage finished # <r> - estimated remaining time # <t> - the total count # # $2 - A total count # $3 - (optional) The 'done' symbol (default is '@') # $4 - (optional) The 'todo' symbol (default is '-') # # Output: A closure that takes a count, and updates the progress bar + based # on its value. When the progress bar is done, it should be + called # with no arguments, to show that the progress is complete - +and- to # print a final newline. ## sub progress_bar { my ($msg, $total, $done_sym, $todo_sym) = @_; ($total || 0) or fatal("total can NOT be zero/undefined!"); $done_sym ||= '@'; $todo_sym ||= '-'; $| = 1; my $start = time(); my $last = $start; my $remain = "???"; my $b_left = ($msg =~ /<r>/)? 1: 0; my $c_prog = sub { my ($count) = @_; my $b_done = defined($count)? 0: 1; $b_done and $count = $total; ($count > $total) and $count = $total; my $pcnt = sprintf "%6.2f", 100.0 * $count / $total; my $new_msg = $msg; # Calculate estimated remaining time my $time = time(); my $dtime = $time - $start; if ($b_done) { $remain = "Finished"; } elsif ($b_left and $count and $dtime and $time - $last > 3) +{ $last = $time; my $rate = ($count / $dtime); my $nsec = int(($total - $count) / $rate); my $hr = my $min = 0; if ($nsec > 3600) { $hr = int($nsec / 3600); $nsec -= 360 +0 * $hr } if ($nsec > 60) { $min = int($nsec / 60); $nsec -= 60 +* $min } if ($hr) { $remain = sprintf "%02d:%02d:%02d", $hr, $min, $nsec; } elsif ($min) { $remain = sprintf "%02d:%02d", $min, $nsec; } else { my $s = (1 == $nsec)? "": "s"; $remain = "$nsec second$s"; } } $new_msg =~ s/<c>/$count/g; $new_msg =~ s/<p>/$pcnt/g; $new_msg =~ s/<t>/$total/g; $new_msg =~ s/<r>/$remain/g; my $len = 79 + 3 - length($new_msg); my $ndone = int($len * $count / $total); my $ntodo = $len - $ndone; my $bar = ($done_sym x $ndone) . ($todo_sym x $ntodo); $new_msg =~ s/<b>/$bar/; print "$new_msg\r"; $b_done and print "\n"; }; return $c_prog; }

You can call it like this ... let's say you were processing a bunch of files, and wanted progress indication for each file processed:

use strict; use warnings; my @files = ( 'some', 'list', 'of', 'files' ); my $nfiles = @files; my $nhandled = 0; my $c_prog = progress_bar("File #<c> of <t> [<p>%] <b>", $nfiles); foreach my $file (@files) { do_something_with_this_file($file); $c_prog->(++$nhandled); } $c_prog->();

Note that you don't want to print anything while the progress bar is displaying, or it will disrupt the progress bar's output. :)

Subroutine do_something_with_this_file left as an exercise to the reader.


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/


Comment on Re: Real Time Progress Bar in console
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://864405]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2015-07-06 05:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (70 votes), past polls