Qu

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