If you look at Jeremy's file progress.m
you linked to, you'll see that he defined functions like ProgressTable
that are able to understand the iterator specifications. This is a decent approach, and I'm now going to do something similar in writing a ShowProgress
function that understands basic Table
iterators and has a generic fallback.
(* ShowProgress needs to hold it's arguments, otherwise it
tries to show progress for something that's already
completely done.*)
SetAttributes[ShowProgress, HoldAll];
(* Basic table syntaxes. Excludes {i, {i1, i2, ...}} and multi-iterator forms *)
ShowProgress[Table[e_, {i_, max_}]] :=
ShowProgress[Table[e, {i, 1, max, 1}]]
ShowProgress[Table[e_, {i_, min_, max_}]] :=
ShowProgress[Table[e, {i, min, max, 1}]]
ShowProgress[Table[e_, {i_, min_, max_, step_}]] :=
Monitor[
Table[e, {i, min, max, step}],
Row[{ProgressIndicator[i, {min, max}], i}, " "]
]
(* Fall-back: shows an indeterminate progress bar and elapsed time,
updating a few times per second *)
ShowProgress[a_] :=
With[{progressStartTime = AbsoluteTime[]},
Monitor[
a,
Dynamic[Refresh[
Row[{
ProgressIndicator[Dynamic[Clock[]], Indeterminate],
AbsoluteTime[] - progressStartTime
}, " "],
UpdateInterval -> 0.25]]
]]
Here are some examples of ShowProgress
in use:
I like this approach instead of the use of Progress...
functions like in Jeremy's package because you don't need to change much of your code. You could hook ShowProgress
in via $Pre
to get automatically applied to everything. If you're willing to change code and use a special function when needed, then the Progress...
functions are fine, although not too much different from ShowProgres[...]
.
The indeterminate progress bar with elapsed time is hopefully a little bit useful in the generic case where it can be difficult to know ahead of time how long a calculation will take. (Technically, there are times when it's unknown ahead of time whether something will finish at all.)