text.progress- Showing progress on text terminals
This module provides a utility to report a progress of processing on a text terminal, using characters to display bar chart. The generic format of a progress bar consists of a single line of text, which is splitted into several parts; a header, which displays the title; followed by a bar, a numeric part, and a time part, as shown in the followig example (only the line beginning with “foo” is actually displayed).
<-header-> <-------bar---------> <-num-><-time-> <---info----> foo |############# |123/211 01:21 ETA compiling... ^ separator
Various things like the character used in the bar chart or the format of the numeric progress can be configured.
Internally a progress bar maintains two numbers, the maximum (goal) value and the current value. The bar shows the proportion of the current value relative to the maximum value. The numeric progress shows the current value over the maximum value by default, but you can configure it to show only the current value or percentage, for example.
A progress bar also has two states, “in progress” and “finished”.
When it is in progress, every time the text is displayed it is
#\return, so that the next display overwrites
the bar, and the time part shows ETA (estimated time of arrival).
Once it becomes finished, the last line of text is displayed
#\newline, and the time part shows the actual time
it took to finish.
This module provides only one procedure,
which packages the progress bar feature in a closure and returns it.
Returns a procedure that packages operations on the progress bar. The procedure can be called with a symbol indicating an operation, and an optional numeric argument.
Redisplays the progress bar. All other operations implies redisplay, so you don’t need to use this unless you have a specific reason to redisplay the current state.
proc 'set value
Sets the current value to value, then redisplays the progress bar. If value exceeds the max value, it is clipped by the max value.
proc 'inc value
Increments the current value by value, then redisplays the progress bar. If the current value exceeds the max value, it is clipped by the max value.
Puts the progress bar to the “finished” state, then redisplays it.
The time part shows the total elapsed time, and the line is terminated
#\newline so that it won’t be clobbered. Once a progress
bar becomes “finished”, there’s no way to put it back “in progress”.
proc 'set-info text
Changes the text displayed in the “info” part. To use the info part,
you have to give a positive value to info-width keyword argument
proc 'set-header text
Changes the text displayed in the “header’ area.
The keyword arguments are used to customize the display:
The text to be displayed in the header part.
This can be changed later, by sending
to the created progress bar.
The width of the header part, in number of characters. The header text is displayed left-aligned in the part. If the header text is longer than the width, the excess characters are omitted. The default is 14.
A character used to draw a bar chart. The default is
The width of the bar chart part, in number of characters. The default is 40.
The width of the numeric part, in number of characters. The default is 9. Setting this to 0 hides the numeric part.
A procedure to format the numeric part. Two arguments are passed; the current value and the maximum value. It must return a string. The default is the following procedure.
(lambda (cur max) (format "~d/~d" cur max))
The width of the time part, in number of characters. The default is 7. Settings this to 0 hides the time part.
The text to be displayed in the info part. This text can be
changed later by sending
set-info message to the created
progress bar. Note that you have to give a positive number
to info-width keyword argument to enable the info part.
The width of the info part. The default value is zero, which means the info part is not displayed.
A character put around the bar part. Default is
You can pass
#f not to display the separators.
The maximum value of the progress bar. Default is 100.
An output port to which the progress bar is displayed. The default value
is the current output port when
make-text-progress-bar is called.
Here’s a simple example, using customized numeric part:
(use text.progress) (define (main args) (define (num-format cur max) (format "~d/~d(~3d%)" cur max (round->exact (/. (* cur 100) max)))) (let ((p (make-text-progress-bar :header "Example" :header-width 10 :bar-char #\o :num-format num-format :num-width 13 :max-value 256))) (do ((i 0 (+ i 1))) ((= i 256) (p 'finish)) (p 'inc 1) (sys-select #f #f #f 50000))))