Append variable to list in Zscript - zscript

In Zscript I can create an list of 8 items
[VarDef, myArr(8)]
How do I add (push) a variable to that list?
[VarDef, temp, 14]
[myArr.push(temp)] // ??? there is no push command

I eventually figured it out. Not to my future self, you need to set a new variable for the array length.
(I don't think there is the Zscript equivalent of array.length.
Here's an example of creating a blank array and then filling it over a loop
[IButton, "Append", "stuff!",
// create array with 5 elements
[VarDef, myArr(5)]
// [Note,myArr(1),,1] // can't do! Variable has not been assigned a value
// create variable equal to array length
[VarDef, len, 5]
// create string to hold results
[VarDef, s, ""]
// loop over array
[VarSet,i,0]
[Loop,len,
[VarSet,myArr(i), i * 2]
[VarSet,s, [StrMerge, s, i, " "]]
// [Note,i,,0.5] // show counter
// [Note,s,,0.5] // show string value
[VarInc,i] // increase loop counter by 1
]
// show results!
[Note,myArr(1),,1]
]

Related

C++ , Finding the lowest value, Function Error: Loop will run at most one (Loop increment never executed)

So I'm trying to create a function to read 5 doubles ( which will be input by a user through the main function) and return the minimum value.
I was considering creating an array and assigning these 5 numbers to it. Then looping through the array and comparing new values with the first item in that array.
I receive the following error though: Loop will run at most one (Loop increment never executed).
Please check the code below. Any advice where it went wrong?
double findLowest(double a, double b, double c, double e, double f)
{
// creating an array numberRange[] to read the 5 input double values
double numberRange[] = {a,b,c,e,f};
// creating a variable minimum and assigning it the value of the
// first item in the numberRange[] array
double minimum = numberRange[0];
// looping through the numberRange array
for(int counter = 1; counter < sizeof(numberRange) ; counter++ )
{
// checking if the numberRange value at the counter is less than
// the minimum value. If true, the minimum value is replaced with
// a new value.
if ( numberRange[counter] < minimum )
{
minimum = numberRange[counter];
}
return minimum;
}
}
The reason for that warning is because you have return minimum inside the loop. So you will immediately leave the function during the first iteration of the loop. That statement should be after the loop is done.
Also, your counter test is incorrect. sizeof(numberRange) is the number of bytes in the array. But each number is more than one byte; if a double is 8 bytes, sizeof(numberRange) will be 5 * 8 = 40, and you'll try to read past the end of the array. To get the number of elements in an array, you have to divide the size of the array by the size of each element, so it should be
counter < sizeof(numberRange)/sizeof(*numberRange)
sizeof(numberRange) = 40
Would you like to loop 40 times? Each double take 8 bytes in your memory. So sizeof() tell you the space not the lenght of your array ...

Iteratively removing elements from ArrayFire array

I am trying to remove elements from an ArrayFire array (af::array) iteratively in a loop. Say I have:
af::array arr = af::range(af::dim4(4), -1, u32) + 1);
// arr = [1 2 3 4] (it's a column vector, though shown as a row vector here)
At each iteration of the loop, I have to remove a value from the array. The value to be removed depends on a computation, the result of which is not always the same. So in 4 iterations of the loop, the process can look like:
// Iter 1: arr = [1 3 4] (removed 2)
// Iter 2: arr = [1 4] (removed 3)
// Iter 3: arr = [4] (removed 1)
// Iter 4: arr = empty (removed 4)
I was wondering if someone had a suggestion on how best to accomplish this. I have a technique working that requires a conversion of arr to a C-array, removing an element, and re-conversion back to a device af::array. Is there a more idiomatic/efficient way to accomplish this?
Assuming the code in your example using columns, I would do the following since there doesn't appear to be any kind of row / column delete function.
i is set to the row we wish to delete, numbering starts at 0:
int i=2;
arr = af::join(0,arr.rows(0,i-1), arr.rows(i+1,end));
af::af_print(arr);
prints:
arr [3 1 1 1]
1
2
4
If you wish to have your data in a column vector, change the 'rows' function to the 'cols' function.

Copying part of an array stored in a memory mapped file

I have an array of doubles stored in a memory mapped file, and I want to read the last 3 entries of the array (or some arbitrary entry for that matter).
It is possible to copy the entire array stored in the MMF to an auxiliary array:
void ReadDataArrayToMMF(double* dataArray, int arrayLength, LPCTSTR* pBufPTR)
{
CopyMemory(dataArray, (PVOID)*pBufPTR, sizeof(double)*arrayLength);
}
and use the needed entries, but that would mean copying the entire array for just a few values actually needed.
I can shrink arrayLength to some number n in order to get the first n entries, but I'm having problems with copying a part of the array that doesn't start from the first entry. I tried playing with pBufPTR pointer but could only get runtime errors.
Any ideas on how to access/copy memory from the middle of the array without needing to copy the entire array?
To find start offset for nth-element:
const double *offset = reinterpret_cast<const double*>( *pBufPTR ) + n;
To copy last 3 elements:
CopyMemory( dataArray, reinterpret_cast<const double*>( *pBufPTR ) + arrayLength - 3, 3 * sizeof(double) );
You can just add the (0 based) index of the first array element you want to copy to the dataArray pointer value that you pass in... the pointer will be increased by the index times sizeof(double). Makes sure you pass in an arrayLength value reflecting the number of elements to operate on, and not the original array length.
For example, to copy the last 10 elements (assuming you've already checked there are at least 10 elements)...
ReadDataArrayToMMF(dataArray + arrayLength - 10, 10, &myBufPTR);
Similarly (albeit illustrating a different notation to get the address), to get elements 20..24:
ReadDataArrayToMMF(&dataArray[20], 5, &myBufPTR);

Insert a new value to element of array and move the rest of elements

I am making a program that it will be able to add any numbers on an array and then it will be able to modify them (insert,delete).What I want to know is how to create a new value in an array without modifying anything.Just create the value and push all the rest to the next one.Example: insert 1 8 //insert is just the command,1 is the place where you want to create the new value and 8 is the value itself so list[1] = 8 but I want the rest values that already exist to go 1 forward(if they are in the place I want to create the new value or higher than it(talking about place in the list))
Full example:
List:
5
6
7
8
9
Command: insert 3 10
New list:
5
6
7
10 //the one that changed,the rest from this point went 1 forward
8
9
What you want is to use a std::vector<int> something like this:
std::vector<int> v = {5, 6, 7, 8, 9};
v.insert(v.begin() + 1, 8); // v[1] now equals 8, everything after push up one
v.erase(v.begin() + 1); // v is now as it was before above insert
v.insert(v.begin() + 3, 10); // v[3] is now 10
One way would be to use std::vector and insert().
http://www.cplusplus.com/reference/vector/vector/
http://www.cplusplus.com/reference/vector/vector/insert/
Edit: unless you can't use STL containers and there's a requirement to use c-style arrays, in which case it won't be as straightforward, as you won't be able to directly grow them.
Let a be the array, position be the index in array where the value has to be inserted, and value be the value itself.
Then try:
int i;
for(i=CURRENT_SIZE_OF_ARRAY-1; i>=positon; --i)
{
a[i+1] = a[i];
}
a[i]=value;
This way, you shift the array values from the end in order to make space for the new element, and then finally insert that element in the desired location.

Why am i getting this kind of output since i know that the default values of non-initialized integer elements of an array is 0?

#include <iostream>
using namespace std;
void RemoveZeroElements(int arr1[],int arr2[],int &i){
int n=0;
int m=0;
while(n<14) {
switch(arr1[n]) {
case 0:
n+=1;
break;
default:
arr2[m]=arr1[n];
m+=1;
n+=1;
i+=1;
break;
}
}
}
int main()
{
int ar1[14]={2,4,5,0,7,-9,0,0,11,23,44,0,13,999};
int ar2[14];
int efsize=0;
RemoveZeroElements(ar1,ar2,efsize);
cout<<"the new array without the zeros has an effective size of "<< efsize << endl;
for (int i=0;i<14;i++) {
if(ar2[i]!=0) {
cout << "the new array has its " << (i+1)<< "th element set to " <<
ar2[i]<< endl;
}
}
}
The output i get is the following:
the new array without the zeros has an effective size of 10
the new array has its 1th element set to 2
the new array has its 2th element set to 4
the new array has its 3th element set to 5
the new array has its 4th element set to 7
the new array has its 5th element set to -9
the new array has its 6th element set to 11
the new array has its 7th element set to 23
the new array has its 8th element set to 44
the new array has its 9th element set to 13
the new array has its 10th element set to 999
the new array has its 11th element set to 1
the new array has its 12th element set to 65535
the new array has its 13th element set to 4308980
the new array has its 14th element set to -1079890440
The problem as you see is in the 12th,13th and 14th elements
What you know is wrong. The initial values of array elements of POD type (such as int or void * or struct some_standard_c_structure) with function scope is undefined. ar2 is full of garbage.
The initial values of array elements with static or global scope is 0 (not taking into account multithreading issues.)
You must make sure to clear the contents of ar2 before you use it. The simplest way to do so is with std::fill():
std::fill(ar2, ar2 + (sizeof(ar2) / sizeof(int)), 0);
In C, the equivalent is memset():
memset(ar2, 0, sizeof(ar2));
Because you are wrong. Those are uninitialized values, could be anything.
If they were static storage duration objects, instead of auto storage duration objects, they would be initialized to zero. It's best not to think about it and always initialize your variables.
What you're doing here is setting the first ten elements of ar2 to the numbers in ar1 that aren't zero. Your problem elements aren't just the 12th, 13th, and 14th, it also includes the 11th as well. You'll notice that the number 1 is nowhere in your original array also.
The last four elements aren't zero, they're completely undeclared, because of what he said ^^ up there. If you want the ar2 to be ar1 without the zeros, just do a count in a for loop that counts how many elements are NOT zero, and initialize ar2 to that number.