One-liner challenge

Agree that narg() self-documents well.

But subtle are the differences betwixt $# and narg($*). These differences stem from G’MIC setting up $# directly, conveying the command line item count datum straight from the underlying environment, while narg($*) performs computation on a vector. It is this vector computation from which differences arise, particularly the role that commas play in vector string representations: commas are the item separators of vectors.

Consider this custom command defined in foobar.gmic:

foobar :
   e {narg($*)}
   e {$#}

Doris Diligence runs this to test a typical argument list for a G’MIC command she is (diligently) developing:

$ gmic foobar.gmic foobar 1,3,2.718,"Oh, yes, We have no bananas."
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Input custom command file 'foobar.gmic' (1 new, total: 4422).
[gmic]-0./foobar/ 6
[gmic]-0./foobar/ 6
[gmic]-0./ End G'MIC interpreter.

The two command line counters are in agreement, but Doris is unsettled. She has been thinking that her argument list has four elements: “1”, “3”, “2.718” and “Oh, yes, We have no bananas.”

Being a diligent cheat sheet reader, she has read Cheat #4: You’ve Moved Fast and Broken Things. Now What?. So Doris runs the script under -debug to understand how G’MIC sees the command line, which may differ from her view. Here is the -debug excerpt of G’MIC’s pipeline decomposition for entry into the foobar/ scope:

<gmic>-0./ Command 'foobar': arguments = '1,3,2.718,Oh, yes, We have no bananas.'.
<gmic>-0./ Found 6 given arguments for command 'foobar':
<gmic>-0./   $1 = '1'
<gmic>-0./   $2 = '3'
<gmic>-0./   $3 = '2.718'
<gmic>-0./   $4 = 'Oh'
<gmic>-0./   $5 = ' yes'
<gmic>-0./   $6 = ' We have no bananas.'

“Oh — foo!!!” cries Doris “I must bar the parsing of my last string argument into separate items! Of course! I have forgotten to escape the double quotes!”

So Doris — in a rare lapse of diligence — fails to consider the significance of initial spaces in arguments $5 and $6; she just escapes the double quotes and runs the command again.

G’MIC’s pipeline decomposition for entry into the foobar/ scope appears to have changed for the better:

<gmic>-0./ Command 'foobar': arguments = '1,3,2.718,Oh\, yes\, We have no bananas.'.
<gmic>-0./ Found 4 given arguments for command 'foobar':
<gmic>-0./   $1 = '1'
<gmic>-0./   $2 = '3'
<gmic>-0./   $3 = '2.718'
<gmic>-0./   $4 = 'Oh\, yes\, We have no bananas.'

“Success!” cries Doris. “Escaping the quotes did the trick. Now my string argument comes across intact!”

Whistling a merry tune, Doris scrolls further down to examine the substitutions going on within the foobar/ scope.

<gmic>-0./foobar/ Enter scope 'foobar/'.
<gmic>-0./foobar/#2 Item 'e', selection [].
<gmic>-0./foobar/#2 Command 'echo': arguments = '{narg(1,3,2.718,Oh, yes, We have no bananas.)}' -> '6'.
[gmic]-0./foobar/ 6
<gmic>-0./foobar/#3 Item 'e', selection [].
<gmic>-0./foobar/#3 Command 'echo': arguments = '{4}' -> '4'.
[gmic]-0./foobar/ 4
<gmic>-0./foobar/#3 Exit scope 'foobar/'.

“Oh! Triple foo with cherries on top — and whipped cream!!! I have six arguments and four arguments. Now — bar it all! — what am I to believe?”

This:

  1. narg() is a math function that counts elements of string-represented vectors. Commas separate elements in these representations, so the five commas in “1,3,2.718,Oh, yes, We have no bananas.” begat six elements: ["1", "3", "2.718", "Oh", " yes", " We have no bananas."]. Observe that the penultimate and last vector elements have leading spaces; these follow the commas upon which elements were split. Had Doris noticed these leading spaces earlier on, she would have been cued to the fact as to how her argument list was going off the rails.
  2. $# is a substitution G’MIC maintains for custom commands, relaying how many items it discovered when blocking out the pipeline, a part of scope-entry setup. When G’MIC reports "Found 4 given arguments for command 'foobar':", then $# relays the number following “Found”: the item count of the blocked-out, incoming pipeline, less the custom command name itself.

The construct:

$=citems_

induces G’MIC to provide the items themselves, exactly as to how G’MIC blocked them out. G’MIC expands this pseudo assignment into a series of actual assignments, one for each item of the blocked-out incoming pipeline plus the command name itself.

foobar modified:

foobar :
   $=citems_
   e "Narg sez: "{narg($*)}
   e "Dollar Hash sez: "{$#}
   e ${citems_0}"'s arguments are:"
   repeat $#,k
      e "Argument "{$k+1}" is: "${citems_{$k+1}}"." 
   done

Running it yields:

$ gmic foobar.gmic foobar 1,3,2.718,\"Oh, yes, We have no bananas.\"
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Input custom command file 'foobar.gmic' (1 new, total: 4422).
[gmic]-0./foobar/ Narg sez: 6
[gmic]-0./foobar/ Dollar Hash sez: 4
[gmic]-0./foobar/ foobar's arguments are:
[gmic]-0./foobar/*repeat/ Argument 1 is: 1.
[gmic]-0./foobar/*repeat/ Argument 2 is: 3.
[gmic]-0./foobar/*repeat/ Argument 3 is: 2.718.
[gmic]-0./foobar/*repeat/ Argument 4 is: Oh, yes, We have no bananas..
[gmic]-0./ End G'MIC interpreter.

The offsetting of local variable $k by one accommodates the fact that the first element of the blocked out pipeline contains the command name, useful should one be contemplating conditional command name processing.

The takeaway here is not that narg() is bad and $# is good; they are different tools that serve closely-related, but different purposes, and their operating mechanisms are different. That they almost always report the same results could lull us into thinking they are the same tools just spelled differently. They’re not. Corner cases exist and need to be understood — and navigated.

2 Likes

gmic sp lion f "<begin(P=whd);P--;Q=round(P/2);swap(I[Q],I)"
lion

3 Likes

This is really not interesting.

rep_concat: 64,64,1,1,"begin(concat(a,b)=b+a*10^(ceil(log10(b+1))+ceil(abs(b-.5))-b););px=abs(x-32);py=abs(y-32);q=int(norm(px,py));p=max(px,py);concat(p,q)%128;"

image

This basically utilize concatenate two integer number.

I got this idea from a blog that I can’t seem to find anymore which utilize concatenation, but the person didn’t made this sort of result with it, but something else.

EDIT:

With 31, it’d look like this:

image

And can also do this with concat(a,b):

image

Edit: I found the blog - Concatenations — Kerry Mitchell

That is where I got this idea. I don’t understand it though.

1 Like

gmic sp inside g xy,-1 sign g.. x,1 g. y,1 add ilaplacian ,

The kilometrage varies with ilaplacian. Not sure what to do with it…

Seen a Twitter post about this today (but cannot find the link anymore). It creates an image that exhibits a strong 3D effet (at least for me, particularly when I move my head) :

$ gmic 800,800,1,3 s0,s1,s2,s3,s4=\"255,0,0\",0,\"0,0,255\",0,\"255,0,0\" repeat 5 circle 50%,50%,'{arg0($>,35,25,22,13,10)}'%,1,'${s$>}' done f 'u<0.1?0:i' erode_circ. 3 r2dx 50%

weird3d

2 Likes

Ah yes, that’s called “Colour Pseudo-Stereopsis”, caused by chromatic aberration of the eye, and pupils not being central. Interestingly the effect can be reversed depending on the observer!

2 Likes

lovely example here https://twitter.com/DrNabinPaudel/status/1065340318126612480/photo/1

more recent tweet https://twitter.com/AkiyoshiKitaoka/status/1481642855840231425

2 Likes

I have been wondering if it was possible to generate random numbers via new seed, it appears it is possible! If you change 45 to something else, note the other numbers doesn’t change.

$ gmic echo {expr('>begin(test=[2,6];seed_collect=[23,45,60];k=0;test_seed=1;);if(x==test[k]&&k<2,++k;test_seed=1;);if(test_seed,srand(seed_collect[k]);test_seed=0;);int(u(0,11));',12)}

This would be perfect for finishing up new version of Stitch filter.

This is the expanded expr code.

expr('

 >begin(
  test=[2,6];
  seed_collect=[23,45,60];
  k=0;
  test_seed=1;
 );

 if(x==test[k]&&k<2,
  ++k;
  test_seed=1;
 );
 if(test_seed,
  srand(seed_collect[k]);
  test_seed=0;
 );
 int(u(0,11));'

, 12 )

A random generator is implemented as a sequence like:
x_{n+1} = \mod{(a\;x_n + b,c)},
with a,b and c, prescribed values (usually very large numbers)

When you set a random “seed” with srand(), you actually just set a new value for x_n, so you’ll always get the same sequence x_{n+1} , x_{n+2}, ... after that.

I like to revive this at a certain time of year :slight_smile:
Maybe others have some weird things saved up?

gmic sp bottles dilate 11 laplacian f "(x-y)%2?i:-i" +b 10% - sign
bottles

2 Likes

Been mostly refactoring and improving code in syntax, speed, ans readability. Still a few months away from done. So, not much from me.

Hmm ok, in that case I’ll do another on your behalf :smiley:

gmic sp wall s y foreach { sub {ia} cumulate x sub {ia} } a y
wall

1 Like

Found this one this morning, I like it :slight_smile:

300,300x5 foreach { noise_poissondisk 40 +distance 1 label_fg.. 0 mul. -1 watershed.. . rm. g xy,1 a c } norm neq 0 distance 1 apply_gamma 1.5 n 0,255 morph 20,0.1 map copper +rv[^0] animate 20

@paperdigits , do you know if it is possible to enable auto-loop mode for the video?

2 Likes

I don’t think it can be done in markdown. If you edited the markdown to the html5 video element, then yes: <video>: The Video Embed element - HTML: HyperText Markup Language | MDN

1 Like

Hello,
found a few weird stuff tonight (don’t forget the “w” !)

Shredder? :
gmic -v -1 sp repeat "{0,w*4}" rotate 15,0,0,"{$>}","{$>}" rotate -15,0,0,"{$>}","{$>}" rr2d 500,500,0,0 w done

The Eye:
gmic sp lena repeat 2000 rotate {v*1.8},0,3,53%,53% w done d

One day (don’t move the window ):
gmic -v -1 sp earth repeat 99 adjust_colors ,,,"{$>}" w done repeat 1500 rotate {v*5},0,2,50%,50% rotate "0.05,0,0,{50-$>/10}%,10%" adjust_colors ,,,{u*5} w done repeat 500 rotate {v*5},0,2,50%,50% rotate "0.05,0,0,{50-$>/10}%,10%" adjust_colors ,,,{u*5} w "{$<}","{$<}",0,0,50%,50% done

All these are (sort of) animated, so i don’t have screenshots (no spoilers heh)

EDIT: for some reason the last 2 don’t work on my other computer… bad substition for {v*5} ? (gmic 3.1.6)

EDIT : Worked fine on a 3rd computer (Manjaro on Mac M1 with UTM, gmic 3.2), and worked fine after update on 2nd computer.

Good night!

2 Likes

Nice ones !
Artifacts generated by iterated discrete rotations always give a nice fractal-looking aspect to the images. I’ve used this kind of trick also in x_whirls.

Yes, the variable v has been introduced in 3.2.0, so 3.1.6 won’t recognize it.

@David_Tschumperle Thanks!

It was indeed fun to do, even thought I don’t know my maths and it’s more random experiments for me. Still, good exercise to learn the predefined variables.

The rotation command can give good effects too. I have a little line that gives almost a watercolor-like effect, which is just what I’m looking for.

3D Menger Sponge

3,3,3,1,norm([x,y,z]-1)>1 (200) repeat 4 { r. {3*[w,h,d]},1,0,2 +ri[0] . *[-2,-1] } to_rgb. dv3d.

Haven’t found a smaller version, though it is probably possible with some XOR spells !

4 Likes

A few things found while following the bounding balls tutorial

gmic 255,255,127,3,"[ xor(x,y)%(z+1) ]"


gmic input 255,255,1,3,"xor(x,y)%16<(x+y)/30?[ 255,0,0 ]:[ 255,255,255 ]"
image

4 Likes