Progress bars and other dynamic reports
Archive - Originally posted on "The Horse's Mouth" - 2006-03-09 05:54:25 - Graham EllisIf you've got a program that runs for a long time, your users will wish to be kept informed of progress and how much longer there is to go. Now that's not always easy to predict (and I'm sure that most of you have made fun of such forecasts in the past) but its's much much much better than sitting staring at a blank screen.
There are a couple of "gotcha"s the first time you try to write a neat status line that overwrites itself repeatedly during the running of your program - it's not JUST a case of switching a \n (new line) to a \r (return) character. Three things that can be gotchas are:
1. Buffering. When your program outputs, you see the results on the screen but NOT right away - all programming languages buffer their output and write it out in a fewer, larger blocks or "buffers", typically writing the buffer out when a new line is thrown. It makes sense really - you wouldn't dream of having the rubbish man come around to collect the wrapper every time you finished a packet of crisps as that would be inefficient. Better to wait for his visit each Tuesday. In coding terms, though, if you don't *have* a \n character going out, you have to tell your program to flush the buffers under a different regime.
2. Output channel. If you output to the screen, that's great. Except that if you output to the screen in the same way that you output your results, they can appear mixed up and if the program's user runs via a redirect or pipe, the progress report AND real results both get written to the file. Result? No progress bar seen on the screen and, frankly, a mess in the file. Better to output to STDERR which is usually available to you and was originally intended for error message output.
3. Droppings. If you're overwriting each report line with another, then you have to be careful that report lines don't get shorter; if they were indeed to get shorter, then spurious characters can get left at the right from older lines and give the user a confusing report. A report line that concludes with directorys remaining - xxx where xxx is 110, then 105, then 92, then 84 ... will confusedly report 110, 105, 925, 845 .... Better to use a specific with format such as with Tcl's format command, printf in Perl, or the % operator in Python.
I've put together a source code example in Perl showing these three issues resolved in a simple program and there's a much fuller example that adds a real time completion estimate and an interrupt and intermediate report capability too.
A quick aside of forecasting time-to-go. You may have to start off with a very rough guess as forecasting a long event based on a very short-to-date run is notoriously hard, so do come back during your run from time to time and re-evaluate your total time estimate!