Uncategorised
qu_progress_bar
a tqdm-style progress indicator for a long loop.
catalog/qu_progress_bar.qu
`progress(i, n)` -- called once per iteration, `i` 0-based and less than `n` -- draws a bar, percent, rate and ETA, and redraws in place (carriage return, not a new line each time). Deliberately a plain builtin next to `tic`/`toc`, not new loop syntax: `for i = 0 to n - 1` is the ordinary Qu idiom, and this is the ordinary way to watch it.
How it works
A loop with real (if artificial) work per iteration, so the bar has
something to measure. sleep() stands in for the actual computation -- swap it for whatever the loop is really doing.
n = 40
total = 0.0
for i = 0 to n - 1
total = total + sqrt(i + 1.0)
sleep(50) # milliseconds, not seconds -- sleep() takes ms
progress(i, n)
end for
print("done: sum of sqrt(1..{n}) = {total:.4f}")
Calling it from the wrong range is a common off-by-one -- shown here
as the error it actually produces, not silently accepted.
try
progress(n, n)
catch e
print("expected error calling progress(n, n) instead of progress(n - 1, n): {e.message}")
end
Results
printed
[#-----------------------------] 2% (1/40) 0.0/s eta 0.0s [##----------------------------] 8% (3/40) 29.9/s eta 1.2s [####--------------------------] 12% (5/40) 24.8/s eta 1.4s [#####-------------------------] 18% (7/40) 23.2/s eta 1.4s [#######-----------------------] 22% (9/40) 22.4/s eta 1.4s [########----------------------] 28% (11/40) 21.9/s eta 1.3s [##########--------------------] 32% (13/40) 21.6/s eta 1.3s [###########-------------------] 38% (15/40) 21.3/s eta 1.2s [#############-----------------] 42% (17/40) 21.1/s eta 1.1s [##############----------------] 48% (19/40) 21.0/s eta 1.0s [################--------------] 52% (21/40) 20.9/s eta 0.9s [#################-------------] 57% (23/40) 20.8/s eta 0.8s [###################-----------] 62% (25/40) 20.7/s eta 0.7s [####################----------] 68% (27/40) 20.7/s eta 0.6s [######################--------] 72% (29/40) 20.6/s eta 0.5s [#######################-------] 78% (31/40) 20.5/s eta 0.4s [#########################-----] 82% (33/40) 20.5/s eta 0.3s [##########################----] 88% (35/40) 20.5/s eta 0.2s [############################--] 92% (37/40) 20.4/s eta 0.1s [#############################-] 98% (39/40) 20.4/s eta 0.0s [##############################] 100% (40/40) 20.4/s eta 0.0s done: sum of sqrt(1..40) = 171.6158 expected error calling progress(n, n) instead of progress(n - 1, n): progress: i must be 0-based and less than n (0..39), got 40 -- `for i = 0 to n - 1 ... progress(i, n) ...` is the idiom, not `1 to n`
The whole program
Runnable as it stands: qu run catalog/qu_progress_bar.qu
# qu_progress_bar.qu -- a tqdm-style progress indicator for a long loop.
#
# `progress(i, n)` -- called once per iteration, `i` 0-based and less
# than `n` -- draws a bar, percent, rate and ETA, and redraws in place
# (carriage return, not a new line each time). Deliberately a plain
# builtin next to `tic`/`toc`, not new loop syntax: `for i = 0 to n - 1`
# is the ordinary Qu idiom, and this is the ordinary way to watch it.
backend auto
#%% A loop with real (if artificial) work per iteration, so the bar has
# something to measure. sleep() stands in for the actual computation --
# swap it for whatever the loop is really doing.
n = 40
total = 0.0
for i = 0 to n - 1
total = total + sqrt(i + 1.0)
sleep(50) # milliseconds, not seconds -- sleep() takes ms
progress(i, n)
end for
print("done: sum of sqrt(1..{n}) = {total:.4f}")
#%% Calling it from the wrong range is a common off-by-one -- shown here
# as the error it actually produces, not silently accepted.
try
progress(n, n)
catch e
print("expected error calling progress(n, n) instead of progress(n - 1, n): {e.message}")
end