adding content of list

classic Classic list List threaded Threaded
6 messages Options
dpa
Reply | Threaded
Open this post in threaded view
|

adding content of list

dpa
Hi,
I have 2 questions that are the same topic for me but they are different
I wanted to chain a list of objects transposing their size so it's a "chain of objects" but I don't know how to add the single objects to another (in an elegant way). I thought it would be easy but...

1.
I tried to sum the sizes into lsum:

// size of the objects
sz = [ 6.5, 8.5, 10, 11.5, 13 ];
// variable sum of lens
lsum = 0;

for (i=[0:len(sz)-1]) {
echo(lsum =  lsum);
translate([lsum,0,0])
cube(size=sz[i], center=false);
lsum = lsum +  sz[i];
}


but "lsum" echo is always from 0+actual size, I thought it would add up but it seems to stay at the "init state". But it does change in the for-loop, always starting from 0? Does the for-loop start the whole script from the first line? I don't get it.

2.
After I could not do that I tried to build an array via a recursive function that sums up the sizes so I could just use an array like "transpose([(sum_sz(i),0,0])" but I failed again.. too many dimensions for me. I came so far and OpenScad doesn't help anymore, it echos no error with "sum_sz=[undef]". 

// size of the objects
sz = [ 6.5, 8.5, 10, 11.5, 13 ];

function sumlist(x, i=0, s=0) = [(
i >= len(x)-1 ?
x[i] + s :
x[i] + sumlist(x, i+1, x[i]+s)
)];

sum_sz = sumlist(sz);
echo(sum_sz = sum_sz);


This is for sure not ready, I need to exclude the i=0 (what would wrongly call x[-1]) but it doesn't work starting with i=1 neither. Also I don't know how to separate elements via commas in this case, nor how to write separate parts in a row in a function (e.g. write something and call the same function again).. maybe not needed..?
I tried to find help in the great wikibooks help, but I could not find the reasons for my questions..

I would be very pleased about help and/or links
best regards!
Dietrich

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: adding content of list

JordanBrown
On 9/18/2020 10:17 AM, dpa wrote:
but "lsum" echo is always from 0+actual size, I thought it would add up but it seems to stay at the "init state". But it does change in the for-loop, always starting from 0? Does the for-loop start the whole script from the first line? I don't get it.

This is probably the #1 most frequently asked question.

The one-sentence summary is "OpenSCAD doesn't have variables; all it has are scoped constants."

Consider this program:
x = 0;
for (i = [1:10]) {
   x = x + i;
}

Roughly, what OpenSCAD does is:

In the "outer" scope, create a constant x with value 0.

In the "for" scope, create a constant i with value 1.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 1.  The result is 1.

In the "for" scope, create a constant x with that value 1.

We've reached the end of the "for" scope; discard its constants and their values.

In the "for" scope, create a constant i with value 2.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 2.  The result is 2.

... and so on.


One of the things that is confusing is that the "for" (as with all modules and module-like things) creates a new scope, and so you can create a new x.  In some ways it's more obvious if you try to unroll the loop:

x = 0;
x = x + 1;
x = x + 2;
...

which yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

Even simpler:

x = 0;
x = 1;

yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

I'll leave it to somebody else to help with the recursive functions that can help you achieve similar results.  Others have done that a lot more than I have and can just rattle off the appropriate patterns.



  


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: adding content of list

nophead
The simplest way is with a recursive module

/// size of the objects
sz = [ 6.5, 8.5, 10, 11.5, 13 ];

module object(i = 0, lsum = 0)
    if(i < len(sz)) {
        translate([lsum,0,0])
            cube(sz[i]);
   
        object(i + 1, lsum + sz[i]);
    }

object();



On Fri, 18 Sep 2020 at 18:39, Jordan Brown <[hidden email]> wrote:
On 9/18/2020 10:17 AM, dpa wrote:
but "lsum" echo is always from 0+actual size, I thought it would add up but it seems to stay at the "init state". But it does change in the for-loop, always starting from 0? Does the for-loop start the whole script from the first line? I don't get it.

This is probably the #1 most frequently asked question.

The one-sentence summary is "OpenSCAD doesn't have variables; all it has are scoped constants."

Consider this program:
x = 0;
for (i = [1:10]) {
   x = x + i;
}

Roughly, what OpenSCAD does is:

In the "outer" scope, create a constant x with value 0.

In the "for" scope, create a constant i with value 1.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 1.  The result is 1.

In the "for" scope, create a constant x with that value 1.

We've reached the end of the "for" scope; discard its constants and their values.

In the "for" scope, create a constant i with value 2.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 2.  The result is 2.

... and so on.


One of the things that is confusing is that the "for" (as with all modules and module-like things) creates a new scope, and so you can create a new x.  In some ways it's more obvious if you try to unroll the loop:

x = 0;
x = x + 1;
x = x + 2;
...

which yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

Even simpler:

x = 0;
x = 1;

yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

I'll leave it to somebody else to help with the recursive functions that can help you achieve similar results.  Others have done that a lot more than I have and can just rattle off the appropriate patterns.



  
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: adding content of list

Ronaldo
As it may have other uses, it is convenient to define, possibly in a library, a recursive function to compute the accumulate sum of a list of numbers and use it in the (non-recursive) object definition:

function accum_sum(list, _i=0, _sum=0) =
  _i >=len(list)
  ? _sum
  : accum_sum(list, _i+1, _sum+list[_i]);

// size of the objects
sz = [ 6.5, 8.5, 10, 11.5, 13 ];

module object(sz) {
  asum = accum_sum(sz);
  for( i=[0:len(sz)-1])
    size = asum[i]; 
    translate([size,0,0])
      cube(sz[i]);
}
obj(sz);

(I haven't run this code to check it)

Em sex., 18 de set. de 2020 às 18:58, nop head <[hidden email]> escreveu:
The simplest way is with a recursive module

/// size of the objects
sz = [ 6.5, 8.5, 10, 11.5, 13 ];

module object(i = 0, lsum = 0)
    if(i < len(sz)) {
        translate([lsum,0,0])
            cube(sz[i]);
   
        object(i + 1, lsum + sz[i]);
    }

object();



On Fri, 18 Sep 2020 at 18:39, Jordan Brown <[hidden email]> wrote:
On 9/18/2020 10:17 AM, dpa wrote:
but "lsum" echo is always from 0+actual size, I thought it would add up but it seems to stay at the "init state". But it does change in the for-loop, always starting from 0? Does the for-loop start the whole script from the first line? I don't get it.

This is probably the #1 most frequently asked question.

The one-sentence summary is "OpenSCAD doesn't have variables; all it has are scoped constants."

Consider this program:
x = 0;
for (i = [1:10]) {
   x = x + i;
}

Roughly, what OpenSCAD does is:

In the "outer" scope, create a constant x with value 0.

In the "for" scope, create a constant i with value 1.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 1.  The result is 1.

In the "for" scope, create a constant x with that value 1.

We've reached the end of the "for" scope; discard its constants and their values.

In the "for" scope, create a constant i with value 2.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 2.  The result is 2.

... and so on.


One of the things that is confusing is that the "for" (as with all modules and module-like things) creates a new scope, and so you can create a new x.  In some ways it's more obvious if you try to unroll the loop:

x = 0;
x = x + 1;
x = x + 2;
...

which yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

Even simpler:

x = 0;
x = 1;

yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

I'll leave it to somebody else to help with the recursive functions that can help you achieve similar results.  Others have done that a lot more than I have and can just rattle off the appropriate patterns.



  
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: adding content of list

rickan
This one works.
function sumlist(l, al=[0], i=0, t=0) = i>=len(l)-1 ? al : sumlist(l, concat(al, [t+l[i]]), i+1, t+l[i]);

sz = [6.5, 8.5, 10, 11.5, 13, 14.5];

module object(sz){
  sl = sumlist(sz);
  for(i=[0:len(sz)-1]){
    translate([sl[i], 0, 0])
    cube(sz[i]);
  }
}

object(sz);

I post this just as an example. I would use the recursive module.

Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
dpa
Reply | Threaded
Open this post in threaded view
|

Re: adding content of list

dpa
In reply to this post by nophead
Thank you all!
The Ronaldos accumulation list does not generate an array but a single sum value, therefore asum[i] does not work.
But Nop Head's suggestion works fine and is 'kind of' simple.. recursive modules... I didn't know about that until now... :)


Am Fr., 18. Sept. 2020 um 19:58 Uhr schrieb nop head <[hidden email]>:
The simplest way is with a recursive module

/// size of the objects
sz = [ 6.5, 8.5, 10, 11.5, 13 ];

module object(i = 0, lsum = 0)
    if(i < len(sz)) {
        translate([lsum,0,0])
            cube(sz[i]);
   
        object(i + 1, lsum + sz[i]);
    }

object();



On Fri, 18 Sep 2020 at 18:39, Jordan Brown <[hidden email]> wrote:
On 9/18/2020 10:17 AM, dpa wrote:
but "lsum" echo is always from 0+actual size, I thought it would add up but it seems to stay at the "init state". But it does change in the for-loop, always starting from 0? Does the for-loop start the whole script from the first line? I don't get it.

This is probably the #1 most frequently asked question.

The one-sentence summary is "OpenSCAD doesn't have variables; all it has are scoped constants."

Consider this program:
x = 0;
for (i = [1:10]) {
   x = x + i;
}

Roughly, what OpenSCAD does is:

In the "outer" scope, create a constant x with value 0.

In the "for" scope, create a constant i with value 1.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 1.  The result is 1.

In the "for" scope, create a constant x with that value 1.

We've reached the end of the "for" scope; discard its constants and their values.

In the "for" scope, create a constant i with value 2.

Evaluate the expression "x + i".  x comes from the "outer" scope, with value 0.  i comes from the "for" scope, with value 2.  The result is 2.

... and so on.


One of the things that is confusing is that the "for" (as with all modules and module-like things) creates a new scope, and so you can create a new x.  In some ways it's more obvious if you try to unroll the loop:

x = 0;
x = x + 1;
x = x + 2;
...

which yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

Even simpler:

x = 0;
x = 1;

yields:

WARNING: x was assigned on line 1 but was overwritten on line 2

I'll leave it to somebody else to help with the recursive functions that can help you achieve similar results.  Others have done that a lot more than I have and can just rattle off the appropriate patterns.



  
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org