This seem like something that would help me share a more readable code to other generative art folks that use other language. Also great for newcomers.
It’s implemented and I must say it looks quite good so far.
I’m preparing new binaries for tonight, with this addition.
Well I’m ready to try it - already gone through 4k lines of local gmic file to use foreach
. No problems with that so far!
I am on board with the braces {...}
. Would be easier to tidy the code with them around.
I’ve just fixed a bug with foreach
by the way, happening when an iteration produces multiple images. I’m currently building binary updates for Win and impish.
The few changes I’ve made in the stdlib code confirms this.
For instance:
select_color : skip ${1=0}
e[^-1] "Select color (${2--1}) in image$?, with tolerance $1."
foreach { +fc ${2--1} - norm <= $1 }
That is really cool ans shorten the code a lot.
Note that these new starting/closing braces can be used only for the blocks with the following type:
local { ... }
for (cond) { ... }
foreach[selection] { ... }
repeat $N { ... }
Cannot be used for if... elif... else... fi
, and do...while
.
I did a test. It doesn’t work. Wrong version?
C:\Windows\System32>gmic sp cat,dog foreach[0,1] { erode 2 }
[gmic]-0./ Start G'MIC interpreter.
[gmic]-1./ Input sample image 'cat' (1 image 600x550x1x3).
[gmic]-2./ Input sample image 'dog' (1 image 1024x685x1x3).
[gmic]-1./*foreach/ Input file '{' at position 1
[gmic]-1./*foreach/ *** Error *** Unknown command or filename '{'; did you mean '%'?
C:\Windows\System32>gmic version
gmic: GREYC's Magic for Image Computing: command-line interface
Version 3.1.0 (pre-release #220304)
(https://gmic.eu)
Copyright (c) Since 2008, David Tschumperlé / GREYC / CNRS.
(https://www.greyc.fr)
I think maybe the windows build is not ready - works fine for me on the ubuntu build with timestamp 3 hours later.
Edit: I find it helps readability even on terminal, because the scope is clearly visible. Nice!
New:
gmic repeat 10 { sp } foreach { +mirror y add }
Old (ignoring having to escape shell things too):
gmic repeat 10 sp done repeat $! l[$>] +mirror y add endl done
Found one problem with to_rgb
- it no longer retains the input image name (output is just “unnamed”)
Edit: it gets even stranger with the display
gmic sp dog
= image called “unnamed”
gmic sp dog sp dog
= both called “dog”
No problem. I dislike if
statements with braces because there can be more than a pair.
I don’t like it either. I think other commands do that too, e.g., med
. I forget the rest. I just rename them back, but I should be reporting them.
Now, the windows version works after the update in pre-release collection. Thanks. This’ll make coding a bit more fun now.
I’m a bit more or less neutral on this. The ‘{}’ seem to be slower, however, I find it easier to work with in KDE Kate as I would only need to click next to the bracket to see where it start or end. So, after using ‘{}’, I simple replace it with done.
If you are commenting on the quoted text, you probably mean fi
.
How much slower is it? That is a good strategy. Use {...}
for faster scripting. Then delete {
and replace }
with done
for faster run times.
Actually, it’s faster. I just had a test where it seem slower at the time.
C:\Windows\System32>gmic sp cat,dog,lena tic foreach blur 1 done toc rm
[gmic]-0./ Start G'MIC interpreter.
[gmic]-1./ Input sample image 'cat' (1 image 600x550x1x3).
[gmic]-2./ Input sample image 'dog' (1 image 1024x685x1x3).
[gmic]-3./ Input sample image 'lena' (1 image 512x512x1x3).
[gmic]-3./ Initialize timer.
[gmic]-1./*foreach/ Blur image [0] with standard deviation 1, neumann boundary conditions and gaussian kernel.
[gmic]-1./*foreach/ Blur image [0] with standard deviation 1, neumann boundary conditions and gaussian kernel.
[gmic]-1./*foreach/ Blur image [0] with standard deviation 1, neumann boundary conditions and gaussian kernel.
[gmic]-3./ Elapsed time: 0.025 s.
[gmic]-3./ Remove images [0,1,2] (0 images left).
[gmic]-0./ End G'MIC interpreter.
C:\Windows\System32>gmic sp cat,dog,lena tic foreach { blur 1 } toc rm
[gmic]-0./ Start G'MIC interpreter.
[gmic]-1./ Input sample image 'cat' (1 image 600x550x1x3).
[gmic]-2./ Input sample image 'dog' (1 image 1024x685x1x3).
[gmic]-3./ Input sample image 'lena' (1 image 512x512x1x3).
[gmic]-3./ Initialize timer.
[gmic]-1./*foreach/ Blur image [0] with standard deviation 1, neumann boundary conditions and gaussian kernel.
[gmic]-1./*foreach/ Blur image [0] with standard deviation 1, neumann boundary conditions and gaussian kernel.
[gmic]-1./*foreach/ Blur image [0] with standard deviation 1, neumann boundary conditions and gaussian kernel.
[gmic]-3./ Elapsed time: 0.023 s.
[gmic]-3./ Remove images [0,1,2] (0 images left).
[gmic]-0./ End G'MIC interpreter.
Barely makes a difference, but to a guy like me that tries to do micro-optimization, that’s something.
Fixed with:
https://github.com/dtschump/gmic/commit/d4692422c95de4c86db2df8671b1babe81b0657a
New binary packages on the way!
One more thing - there’s no help for the foreach
command yet either (I guess you’re waiting for it to become stable first?)
Indeed. And I just didn’t think about writing it yet to be honest.
BTW, any help is welcome, I’m not that good at writing reference documentation
The one-liner description could be something like:
"Iterate over all images in the selection, with a separate local environment for each one"
What matters to me most in the cli help is a precise technical description, in as few words as possible. I find what you do already is certainly good enough in general
So I propose this:
#@cli foreach : (+)
#@cli : Start a 'foreach...[onfail]...done' block, that iterates over all images in the selection, \
# with a separate local environment for each one.
#@cli : $ sample colorful,earth,duck,dog foreach[^2] +blur 10 sub normalize 0,255 done
which renders like this:
I’ll probably be switching to braces syntax most of the time now, it’s just plain better. Text editors handle it nicely by highlighting them and code folding works. No problems yet with the latest version
I’m currently converting the code in stdlib
and my strategy is to use the braces as much as I can, except when the code inside the loop becomes too long and I can’t see the opening brace, in which case I prefer to stick with the done
command.
That’s my personal flavor though