# Tuples.

> On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.

— Charles Babbage

Let’s not split hairs…​ According to Wikipedia, "In mathematics, a tuple is a finite ordered list (sequence) of elements." I can live with that. I’m just using it here because I like to reserve the word "Vector" for a tuple of no more than 3, sometimes homogenised to 4, elements, representing a point in 2D or 3D space.

Circular indexing

Circular indexing is when you consider the first element of an array to be the next of the last element. This makes `array[12]` valid even if the array only has 10 elements, and thus `array[9]` is the last, because you just keep numbering through, 10 becomes 0, 11 becomes 1 and thus `array[12]` is the same as `array[2]` (in this case). Now, even `array[-2]` has meaning; since `array[0]` is the first element and we consider it to be the next of the last element, `array[-1]` must be the last element, or `array[len(array)-1]`, i.e. 'the first from the end' and thus `array[-2]` is the same as `array[len(array)-2]` or the 'second from the end'. It’s jolly handy; when you want to address the previous vertex of a polygon boundary; simply look at `array[CurrentIndex-1]` and whatever 'CurrentIndex' is, even if it’s the first element of the array, you’re looking at the previous vertex in the polygon. It’s a beauty, and jolly useful for mesh-generation and such like.

| In The GHOUL, whenever a function takes index-parameters for an array or tuple (and even strings), the parameter will be mapped onto the valid range `[0:len(MyList)-1]` by `Map()` or, more likely, `Dex()` . Parameter names indicating this behaviour are: Index, Begin and End.

## The routines

### `CropTuple()`

`CropTuple(Tuple,Lenght=2)`

- Tuple, a vector of any length, usually a 3D vertex.

- Length, a scalar, determines the length of the returned tuple. Default=2.

Crop a tuple down to a length. `CropTuple()` returns a tuple containing the first Length items of Tuple.
Most commonly used to crop and 'demote' a 3D vector down to a 2D vector.

    NewVertex=CropTuple(Tuple=[0,1,2],Lenght=2);
    echo(NewVertex);

    ECHO: [0, 1]

### `FillTuple()`

`FillTuple(Lenght,Value)`

- Length, a scalar, determines the length of the returned Tuple. Default=undef.

- Value, a value to fill the tuple with. Default=undef.

Pre-populate a tuple for further processing. Not sure if I’ve used this one, ever…​

    NewTuple=FillTuple(Lenght=3,Value=0);
    echo(NewTuple);

    ECHO: [0, 0, 0]

### `Interval()`

`Interval(Start,Factor,End,Resolution=0)`

- Start, scalar, first value.

- Factor, scalar, step-size.

- End, scalar, last value.

- Resolution, scalar, minimum step at either end.

Generates a range from start to end, both inclusive, with all multiples of Factor that fall in between. If the distance to the closest iteration of Factor to either Start or End is less than Resolution, that iteration is skipped.

    Foo=Interval(1.2,3,12.9) // => [1.2, 3, 6, 9, 12, 12.9]

    Bar=Interval(1.8,2,6.6) // => [1.8, 2, 4, 6, 6.6]
    // but
    Baz=Interval(1.8,2,6.6,0.5) // => [1.8, 4, 6, 6.6]

### `IsInRange()`

`IsInRange(Value,Range)`

- Value, what we’re looking for.

- Range, a regular OpenSCAD range like [0:50] or [0:2:10].

Expands Range and checks if it contains Item.

    Boolean=IsInRange(6,[0:2:10]);
    echo(Boolean);

    ECHO: true

### `LeftTuple()`

`LeftTuple(Tuple,Index)`

- Tuple, a tuple of any length.

- Index, 0-based index of the last remaining item in Tuple. Default=undef.

Returns a tuple with the first elements of Tuple up to Index (inclusive). Index is 0-based.

    NewTuple=Left(Tuple=[0,1,2,3,4,5],Index=2);
    echo(NewTuple);

    ECHO: [0, 1, 2]

### `PadTuple()`

`PadTuple(Tuple=[],Lenght=3,Padding=0)`

- Tuple, a tuple of any length.

- Length, 0-based length of the returned tuple. Default=3.

- Padding, value to fill empty elements. Default=0.

Pad the right end of a tuple. Returns a tuple of length Length. Empty elements are filled with Padding. Length is 0-based.
Used mainly to 'promote' a 2D vertex to 3D for processing with 3D based routines.

    NewTuple=PadTuple(Tuple=[0,1],Lenght=3,Padding=0);
    echo(NewTuple);

    ECHO: [0, 1, 0]

### `RangeToTuple()`

`RangeToTuple(Range=[])`

- Range, a regular OpenSCAD 'for' type range expression, formatted like: [start:_step_:_end_], e.g. [0:1:9]

Expand a range into a tuple.
Useful for list generation.

    NewTuple=RangeToTuple(Range=[0:2:10]);
    echo(NewTuple);

    ECHO: [0, 2, 4, 6, 8, 10]

### `RemoveElement()`

`RemoveElement(Tuple, Index)`

- Tuple, tuple.

- Index, index, index of element to be removed.

Remove an element from a tuple, or an array…​ There is also `RemoveElements()` which accepts a list of indices of elements to be removed.

    echo(RemoveElement([4, 3, 2, 1], 1));
    echo(RemoveElements([4, 3, 2, 1], [1,3]));

    ECHO: [4, 2, 1]
    ECHO: [4, 2]

### `ReplaceUndef()`

`ReplaceUndef(StringsTuple,Replacement)`

- StringsTuple, description

- Replacement, description

Replaces every occurrence of undef in StringsTuple with Replacement. Can’t remember why I wrote this…​

### `ReverseTuple()`

`ReverseTuple(Tuple)`

- Tuple, tuple to be reversed.

Yep. It does. Reverse a tuple.

    NewTuple=ReverseTuple(Tuple=[0,1,2,3,4]);
    echo(NewTuple);

    ECHO: [4, 3, 2, 1, 0]

### `RightTuple()`

`RightTuple(Tuple,Begin)`

- Tuple, a tuple of any length.

- Begin, integer, 0-based ID of first item to be selected.

Begin is re-mapped by `Dex()`, so you can do `RightTuple(Tuple,-2)` for the last two items from Tuple.

    NewTuple=Right(Tuple=[0,1,2,3,4,5],Begin=2);
    echo(NewTuple);

    ECHO: [2, 3, 4, 5]

### `SetTupleElement()`

`SetTupleElement(Tuple,Index,Value)`

- Tuple, a tuple of any length.

- Index, index, index of the element that is being changed.

- Value, new value for Element.

Return a tuple with the value of Element replaced by Value.

    NewTuple=SetTupleElement_T([0,1,2,3,4], 2, 12);
    echo(NewTuple);

    ECHO: [0, 1, 12, 3, 4]

### `SubTuple()`

`SubTuple(Tuple,Begin=0,End=-1)`

- Tuple, a tuple of any length.

- Begin, 0-based index of the first element, inclusive.

- End, 0-based index of the last element, inclusive.

Begin and End are mapped onto `[0:Len(Tuple)]` by `Dex()` so negative indices are accepted, and -1 maps onto `Len(Tuple)`

Start and End are re-mapped by `Dex()`, like in the other routines here

    echo(SubTuple(Tuple=[0,1,2,3,4,5,6,7,8],Begin=3,End=7));

    ECHO: [3, 4, 5, 6, 7]

    echo(SubTuple(Tuple=[0,1,2,3,4,5,6,7,8],Begin=3,End=-2));

    ECHO: [3, 4, 5, 6, 7]