velocity template loop through array to create string - velocity

I'm trying to use the velocity templating language in an AWS appsync resolver to create a string by looping through an array of characters.
Given the array listOfWords = ["好" "克力"] how would I achieve the string output of queryString = "+\"好\" +\"克力\""
So far I have managed something like this:
24: #set($listOfWords = ["好" "克力"])
25: #set($queryString = "")
26: #foreach($word in $listOfWords)
27: #if( $velocityCount == 1 )
28: #set($queryString = "+\"$word\"")
29: #else
30: #set($queryString = $queryString +"+\"$word\"")
31: #end
32: #end
This returns the error:
Encountered \"$word\" at velocity[line 28, column 37]\nWas expecting one of:\n <RPAREN> ...\n <WHITESPACE> ...\n \"-\" ...\n \"+\" ...\n \"*\" ...\n \"/\" ...\n \"%\" ...\n <LOGICAL_AND> ...\n <LOGICAL_OR> ...\n <LOGICAL_LT> ...\n <LOGICAL_LE> ...\n <LOGICAL_GT> ...\n <LOGICAL_GE> ...\n <LOGICAL_EQUALS> ...\n <LOGICAL_NOT_EQUALS> ...\n
I have also tried
#foreach( $word in $listOfWords )
#if( $velocityCount == 1 )
#set($queryString = "+" + "\\" + "\"" + $word + "\\" + "\"") line 27
#else
#set($queryString = $queryString + "+" + "\\" + "\"" + $word + "\\" + "\"")
#end
#end
)
But seem to be causing a lexical error:
"Lexical error, Encountered: \"\\\"\" (34), after : \"\\\\\\\\\" at *unset*[line 27, column 64]"

You can do that:
#set($listOfWords = ["好" "克力"])
#set($q = '"')
#set($queryString = "")
#foreach($word in $listOfWords)
#if( $velocityCount == 1 )
#set($queryString = "$q$word$q")
#else
#set($queryString = "$queryString+$q$word$q")
#end
#end

Rather than building up a VTL variable, you could just build up the string as the output directly. Kind of like this example from the VTL docs;
<ul>
#foreach( $product in $allProducts )
<li>$product</li>
#end
</ul>

Related

Awk script extra output: printing raw line (as read) as well as processed line

I have some CSV files where a certain column is actually supposed to be an array, but ALL fields are separated by commas. I need to convert the file to where every value is quoted, and the array column is a quoted, comma-delimited list. I do know the column index for each file.
I wrote the script below to handle this. However, I get each line printed as hoped for, but followed by the raw line.
desired output:
A,B,C,D
"1","","a,b,c","2"
"3","4","","5"
"","5","d,e","6"
"7","8","f","9"
(base) balter#winmac:~/winhome/CancerGraph$ cat testfile
A,B,C,D
1,,a,b,c,2
3,4,,5
,5,d,e,6
7,8,f,9
(base) balter#winmac:~/winhome/CancerGraph$ ./fix_array_cols.awk FS="," array_col=3 testfile
A,B,C,D
"1","","a,b,c","2"
1,,a,b,c,2
"3","4","","5"
3,4,,5
"","5","d,e","6"
,5,d,e,6
"7","8","f","9"
7,8,f,9
(base) balter#winmac:~/winhome/CancerGraph$ cat fix_array_cols.awk
#!/bin/awk -f
BEGIN {
getline;
print $0;
num_cols = NF;
#printf("num_cols: %s, array_col: %s\n\n", num_cols, array_col);
}
NR>1 {
total_fields = NF;
# fields_before_array = (array_col - 1)
# fields_before_array + array_length + fields_after_array = NF
# fields_before_array + fields_after_array + 1 = num_cols
# array_length - 1 = total_fields - num_cols
# array_length = total_fields - num_cols + 1
# fields_after_array = total_fields - array_length - fields_before_array
# = total_fields - (total_fields - num_cols + 1) - (array_col - 1)
# = num_cols - array_col
fields_before_array = (array_col - 1);
array_length = total_fields - num_cols + 1;
fields_after_array = num_cols - array_col;
first_array_position = array_col;
last_array_position = array_col + array_length-1;
#printf("array_col: %s, fields_before_array: %s, array_length: %s, fields_after_array: %s, total_fields: %s, num_cols: %s", array_col, fields_before_array, array_length, fields_after_array, total_fields, num_cols)
### loop through fields before array column
### remove whitespace, and print surround with ""
for (i=1; i<array_col; i++)
{
gsub(/ /,"",$i);
printf("\"%s\",", $i);
}
### Collect array surrounded by ""
array_data = "";
### Loop through array
for (i=array_col ; i<array_col+array_length-1 ; i++)
{
gsub(/ /, "", $i);
array_data = array_data $i ",";
}
### collect last array element with no trailing ,
array_data = array_data $i
### print array surrounded by quotes
printf("\"%s\",", array_data);
### loop through remaining fields, remove whitespace, surround with ""
for (i=last_array_position+1 ; i<total_fields ; i++)
{
gsub(/ /,"",$i);
printf("\"%s\",", $i);
}
### finish line with \n
printf("\"%s\"\n", $total_fields);
} FILENAME
Remove FILENAME from your script.

Why does indexing a string inside of a recursive call yield a different result?

In my naive implementation of edit-distance finder, I have to check whether the last characters of two strings match:
ulong editDistance(const string a, const string b) {
if (a.length == 0)
return b.length;
if (b.length == 0)
return a.length;
const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
import std.algorithm : min;
return min(
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + delt,
editDistance(a, b[0 .. $ - 1]) + 1,
editDistance(a[0 .. $ - 1], b) + 1
);
}
This yields the expected results but if I replace delt with its definition it always returns 1 on non-empty strings:
ulong editDistance(const string a, const string b) {
if (a.length == 0)
return b.length;
if (b.length == 0)
return a.length;
//const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
import std.algorithm : min;
return min(
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + a[$ - 1] == b[$ - 1] ? 0 : 1, //delt,
editDistance(a, b[0 .. $ - 1]) + 1,
editDistance(a[0 .. $ - 1], b) + 1
);
}
Why does this result change?
The operators have different precedence from what you expect. In const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1; there is no ambiguity, but in editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + a[$ - 1] == b[$ - 1] ? 0 : 1, there is (seemingly).
Simplifying:
auto tmp = editDistance2(a[0..$-1], b[0..$-1]);
return min(tmp + a[$-1] == b[$-1] ? 0 : 1),
//...
);
The interesting part here is parsed as (tmp + a[$-1]) == b[$-1] ? 0 : 1, and tmp + a[$-1] is not equal to b[$-1]. The solution is to wrap things in parentheses:
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + (a[$ - 1] == b[$ - 1] ? 0 : 1)

how to vectorize a[i] = a[i-1] +c with AVX2

I want to vectorize a[i] = a[i-1] +c by AVX2 instructions. It seems its un vectorizable because of the dependencies. I've vectorized and want to share the answer here to see if there is any better answer to this question or my solution is good.
I have implemented the following function for vectorizing this and it seems OK! The speedup is 2.5x over gcc -O3
Here is the solution:
// vectorized
inline void vec(int a[LEN], int b, int c)
{
// b=1 and c=2 in this case
int i = 0;
a[i++] = b;//0 --> a[0] = 1
//step 1:
//solving dependencies vectorization factor is 8
a[i++] = a[0] + 1*c; //1 --> a[1] = 1 + 2 = 3
a[i++] = a[0] + 2*c; //2 --> a[2] = 1 + 4 = 5
a[i++] = a[0] + 3*c; //3 --> a[3] = 1 + 6 = 7
a[i++] = a[0] + 4*c; //4 --> a[4] = 1 + 8 = 9
a[i++] = a[0] + 5*c; //5 --> a[5] = 1 + 10 = 11
a[i++] = a[0] + 6*c; //6 --> a[6] = 1 + 12 = 13
a[i++] = a[0] + 7*c; //7 --> a[7] = 1 + 14 = 15
// vectorization factor reached
// 8 *c will work for all
//loading the results to an vector
__m256i dep1, dep2; // dep = { 1, 3, 5, 7, 9, 11, 13, 15 }
__m256i coeff = _mm256_set1_epi32(8*c); //coeff = { 16, 16, 16, 16, 16, 16, 16, 16 }
for(; i<LEN-1; i+=16){
dep1 = _mm256_load_si256((__m256i *) &a[i-8]);
dep1 = _mm256_add_epi32(dep1, coeff);
_mm256_store_si256((__m256i *) &a[i], dep1);
dep2 = _mm256_load_si256((__m256i *) &a[i]);
dep2 = _mm256_add_epi32(dep2, coeff);
_mm256_store_si256((__m256i *) &a[i+8], dep2);
}
}

ABEL HDL Counter 4bit

I want to create counte 4bit generate this sequence : 1,3,5,7,9,8,6,4,2,0,1... in ABEL HDL. For odd number i make , but for even number fail. Can anyone exlpain me , where is my mistake.
I think to make like in vhdl.
contor=1;
if contor >9 contor = contor + 2; else contor = 8;
if contor >0 contor -2 ;
But i don't understand how to use #if .
This is the code which i made :
*<MODULE CounterV2
declarations
"pin declaration
X = .x.;
x = .X.;
"pin of clock , load "
clock pin 1;
ld pin 7;
i_d pin 8;
"output pin"
q3, q2, q1, q0 pin 19, 18, 17, 16 istype 'reg';
contor = [q3,q2,q1,q0];
MOD = [ld, i_d];
STOP =(MOD == [0, X]);
PAR =(MOD == [0, 1]);
IMPAR =(MOD == [0, 0]);
equations
[q3,q2,q1,q0].clk = clock;
"there is the core of code :D "
when IMPAR then contor :=1#(contor + 2);
when PAR then {
contor := 8;
when contor == 8 then contor :=contor -2;
}
" there a made test vector
test_vectors 'test'
([i_d,clock]->[q3,q2,q1,q0])
[0,.c.]->[x,x,x,x];
[0,.c.]->[x,x,x,x];
[0,.c.]->[x,x,x,x];
[0,.c.]->[x,x,x,x];
[0,.c.]->[x,x,x,x];
[1,.c.]->[x,x,x,x];
[1,.c.]->[x,x,x,x];
[1,.c.]->[x,x,x,x];
[1,.c.]->[x,x,x,x];
[1,.c.]->[x,x,x,x];
[1,.c.]->[x,x,x,x];
END
>*

Pass unsigned char * by reference

HI! I create a function to get a grayscale version of an image, but i have problem trying to pass by reference the destination of the bit(s) generated by this function:
void grayscale (const unsigned char *source, unsigned char **dest, int data_size) {
for (int i=0; i < data_size; i= i+4) {
int gray = (source[i] + source[i+1] + source[i+2]) / 3;
gray = 255 - (int)cos(source[i])*255;
*dest[i] = (char)gray;
*dest[i + 1] = (char)gray;
*dest[i + 2] = (char)gray; //HERE AN ERROR
*dest[i + 3] = (char)255;
}
}
I call this function with:
grayscale(source, &destination, width*height*4 );
Is there something wrong with pointers ?
(i'm working on objective C and i obtain a EXC_BAD_ACCESS).
Thank you
It's not clear why you're using an additional level of indirection for dest, since *dest is not being modified but most likely you need to do the following - change:
*dest[i] = (char)source[i];
*dest[i + 1] = (char)gray;
*dest[i + 2] = (char)gray;
*dest[i + 3] = (char)255;
to:
(*dest)[i] = (char)source[i];
(*dest)[i + 1] = (char)gray;
(*dest)[i + 2] = (char)gray;
(*dest)[i + 3] = (char)255;
The reason for this is operator precedence/associativity.
Also it's hard to tell without seeing the calling code, but I'm guessing you may need to change:
(*dest)[i] = (char)source[i];
to:
(*dest)[i] = (char)source[i / 4];
if you're trying to do something like convert a single plane image to RGBA.
Your call is fine, you have an illegal memory access. Debug your indices and check the size of the array your passing in, also check that it is still in scope. Most likely i+2 is out of bounds.