9
$\begingroup$

Is there any way to get a textual progress bar (e.g. like the progressbar module in a python repl) when working in console mode?

Anything would be better than this:

enter image description here

$\endgroup$
5
  • 1
    $\begingroup$ Monitor doesn't seem to be supported either and PrintTemporary isn't exactly the answer. Just a comment. $\endgroup$
    – Kuba
    Mar 21, 2017 at 23:02
  • 1
    $\begingroup$ If I remember correctly, this was discussed on a Wolfram livestream recently, so there might be some progress (sorry) on this functionality in upcoming versions. $\endgroup$
    – Carl Lange
    Jan 31, 2020 at 17:51
  • 2
    $\begingroup$ Related answer mathematica.stackexchange.com/questions/213537/… $\endgroup$
    – Fortsaint
    Feb 3, 2020 at 14:14
  • $\begingroup$ Just use python, mma doesn’t support the command line in any modern way $\endgroup$
    – M.R.
    Feb 4, 2020 at 16:54
  • $\begingroup$ how do you use python to run mma in the terminal? $\endgroup$
    – QuantumDot
    Feb 6, 2020 at 4:35

1 Answer 1

6
+25
$\begingroup$

Here is a crude progress bar demo script that has been tested in a Gnome terminal under Linux and a Powershell command prompt under Windows 10. Don't expect much because it's only a loop with a print statement:

progbar[width_, title_] := Function[{ndx},
    Print[ "  " <> title<>"\n  [" <>
            StringJoin@ConstantArray["*", ndx] <>
            StringJoin@ConstantArray[" ", width-ndx] <>
            "]" <> ToString[Round[100*ndx/width,1]] <>
            "%   \n\033[3A" ]
]

nsteps = 30;
pb = progbar[nsteps, "Crude Progress Bar"]

Table[ (*  put the function steps here *)
    Pause[1];

    (* follow the function steps with this one-line progress bar printer *)
    pb[ndx],
    {ndx, nsteps}
]

Print["\n\n"]

Crude Progress Bar
[******************************]100%

So what's going on? The progbar[ ] function returns a function that prints the progress bar. It takes 2 arguments. width is total number of steps, which should be an integer between, say, 10 and 100. title is the message to printed above the progress bar.

The pb = progbar[ ... ] statement means pb will be called with the actual progress, probably a step number, between zero and width. The variable name width makes sense in progbar, but the user might think of it as nsteps.

To monitor the training or testing of a machine learning algorithm, say, divide the training (or testing) task into chunks. The number of chunks will be width, or nsteps in the above demo. Perform the task in a loop and call pb with the loop index after each training with each chunk of data. The above demo uses Pause[1] to represent the training (or testing) task.

What's the trick? The only trick is to use an ANSI escape code to Print on the same line every time. The ANSI code "ESC[ 3 A" moves the cursor up 3 lines. There are many ANSI escape codes. This one is an example of a Terminal Output Sequence.

The Print["\n\n"] command is used to get the cursor back down below the progress bar after the task loop completes.

This has not been thoroughly tested, but one bug is known. If we run the demo script like this clear ; wolframscript -f progbardemo.wls, it will be too close to the top edge of the terminal. So, clear the terminal and then enter the wolframscript -f progbardemo.wls.

EDIT 1:

The appearance of the progress bar could be improved if escape codes that turn the screen cursor on and off could be found. The appearance could also be improved by judicious use of the well-known escape codes for color.

The progress bar does no error checking, so the user must ensure the argument of pb is an integer in the range of zero to width. Here is an example of a random walk that uses the progress bar as an indicator widget. Sometimes the walker wanders too far, and sometimes it comes back within range. Error checking is done by "normalizing" the progress before.

nsteps = 50;
pb = progbar[nsteps, "Random Walker"]
progress = nsteps/2;
Do[
    progress += RandomChoice[{-1,1}/100];
    normal = Max[Min[Round[progress], nsteps], 0];
    pb[normal],

    {10000000}
]

Print["\n\n"]

EDIT 2: Improving the Appearance

The progress bar's appearance will be improved under some circumstances by hiding the screen cursor. Use Print["\033[?25l"] before the loop to conceal the cursor and use Print["\033[?25h"] after the loop to reveal the cursor. If the loop should fail for some reason, the code that reveals the cursor may not be evaluated. If the WL script quits without revealing the cursor, the user will see the normal command line prompt, but without a cursor. It may be possible to execute python -c "print('\033[?25h')" at the command prompt to reveal the cursor. In Linux there is also a tset command that will reveal the screen cursor.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.