The function of validate input params - kdb

Definded the method to validate input params :
`validate_paramaters{[Date;Code;CodeType;Param]
if[ not (14h=abs[type[Date]]);
[
.log.info["\tError - Exiting function - Date is not of the correct type"];
: `$"Error - Date is not of the correct type"
]
];
if[ not (11h=abs[type[Code]]);
[
.log.info["\tError - Exiting function - Code is not of the correct type"];
: `$"Error - Code is not of the correct type"
]
];
if[ not (-11h=type[CodeType]);
[
.log.info["\tError - Exiting function - CodeType is not of the correct type"];
: $"Error - CodeType is not of the correct type"
]
];
:`validated
}`
But now The CodeType`s type add more addition :
-11h=type[CodeType] `also can be` 99h=type[CodeType]
Please give me a guidance how can i validate the CodeType now

Replace your not (-11h=type[CodeType]) with not any -11 99h in type CodeType
The keyword in allows you to compare the type of CodeType with a list of numeric types. This returns a boolean list. For example:
q)CodeType:`sample`dictionary!`a`b
q)-11 99h in type CodeType
01b
The any prepended to that returns a 1b if ANY members of the list are True.
q)any -11 99h in type CodeType
1b
Finally, you seem to be throwing errors if the CodeType is NOT one of the aforementioned types, so we'll prepend this all with a not.

Alternatively to Jemma's response, you could also try a more concise method:
validate:{[d;names;types]
if[count fails:key[d] where not any each types=type each d[names];
:"error - exiting - ",("," sv string fails)," are not of correct type"];
};
This first parameter of this function is a dictionary (d) where the key is the names of the arguments and the values are their corresponding values. This argument can be passed along with the names of the variables you are querying and the types they should be. Nested lists should be used if you're looking for multiple types to conform against.
For example, here is a dictionary with valid entries.
q)d:`date`code`codetype!(.z.d;`some`code`to`test;`thetypeofmycode)
q)validate[d;`date`code`codetype;(-14;11;(-11 99h))]
q)
However, you can see this returns an error if the dictionary is updated with an invalid datatype.
q)d[`code]:"wrongtype"
q)d[`date]:.z.p
q)validate[d;`date`code`codetype;(-14;11;(-11 99h))]
"error - exiting - date,code are not of correct type"
Just note that the list of types has to be in the same order as the dictionary
To incorporate your .log.info you can adapt the above function as so:
validate:{[d;names;types]if[count fails:key[d] where not any each types=type each d key d;
.lg.info"error - exiting - ",("," sv string[fails])," are not of correct type";
:"error: ",("," sv string[fails])," - type incorrect"]}
Referring to the example above, this would return the same result but this time logging the error using .log.info also.

Related

Invalid Data Type Specified

'
Hello, I am trying to write a for loop that will search through my one-column array for the symbol "[]" or an empty numeric array. However, I keep getting this error when I search for [] : "Abnormal exit: Invalid data type specified. Data type can be Advisor.Element objects or character vector." I really have no idea why this is happening. When I search for a value like "1" or "2", it seems to work.
for x = 1:1:n
if(names_en{1,x} == "[]")
display(new_block_name_enable{x,1}); % finds [] and displays location
end
end

Pound symbol in object type, in F# [duplicate]

What does # mean in type signatures like seq<#seq<'a>> compared to just seq<seq<'a>> ?
This is called flexible type. The short summary is that #type means any type that is inherited from type. So, in your concrete example seq<#seq<'a>> will be a sequence of any collections containing 'a values.
When calling a function, F# automatically casts concrete types to interfaces - so for example, you can call a function taking seq<'a> with array 'a[] as an argument. However, this does not work when you have array of arrays - because 'a[][] only implements seq<'a[]> but not seq<seq<'a>>.
For example, the following two functions return list of lengths of nested sequences:
let f1 (s:seq<seq<'T>>) = [ for i in s -> Seq.length i ]
let f2 (s:seq<#seq<'T>>) = [ for i in s -> Seq.length i ]
But only the second one can be called on lists of lists:
[ [1]; [2;3] ] |> f1
// error FS0001: The type 'int list list' is not
// compatible with the type 'seq<seq<'a>>'
[ [1]; [2;3] ] |> f2
// val it : int list = [1; 2]

kdb+/q: Check if argument has been supplied to the function call

Say we have function fun with two arguments, second one is optional.
How to check within the function whether the second, optional argument has been supplied and act accordingly?
fun: {[x;optarg] $["optarg was supplied" like "optarg was supplied";"behavior 1"; "behavior 2"] }
fun[1;2] / behavior 1
fun[1] / behavior 2
```
I don't think this is possible. Supplying less than the specified number of arguments result in a projection.
A good alternative is to have your function accept one argument - a list. And then you can check for the existence of each element of the list.
f:{[l] $[1=count[l];
/ do something with first arg only;
/ do something with both args ]
}
Or you could have the function accept a dictionary (this allows you to set default values in the function).
q)f:{[dict] def:`a`b`c!10 20 30;
def:def upsert dict;
:def[`a] + def[`b] + def[`c] }
q)f[`a`b!5 10]
45
q)f[`a`c!5 10]
35
You can't check for number of arguments, kdb+ will report rank error when number of arguments is more than expected. But there is a workaround which will result in function which will accept any number of arguments:
q)func:('[{$[1=count x;"one";"more"]};enlist])
q)func[1]
"one"
q)func[1;2]
"more"
q)func[1;2;3]
"more"
Here is an example:
q)func:('[{$[1=count x;x[0];sum x]};enlist])
q)func[1]
1
q)func[1;2]
3
q)func[1;2;4]
7
q)func[1;2;4;7]
14
func:('[{
inputs:(`a_Required`b_Required`c_Optional`d_Optional);
optionalDefaults:`c_Optional`d_Optional!(0b;1b);
if[(count inputs)<count x;-1"Too Many input arguments";:()];
data:inputs xcols optionalDefaults, (!) . (numInputs:count x)#'(inputs;x);
show data;
data
};enlist]
)

unknown data type return from KDB+ -79

i am facing a very strange problem in KDB+. where data type returned from kdb+ server is -79. that i can't find out.
does any body know that type is it. ?
79h is type for mapped list of lists of GUID data type.
Reference: http://code.kx.com/q/ref/datatypes/
Section: Nested Type.
From page:
Nested Type:
These types are used for mapped lists of lists of the same type. The numbering is 77 + primitive type.
Guid type is 2 which gives it's nested type value=79
ex:
q)`:t1.dat set 2 2#0x0 sv 16?0xff
q) a:get `:t1.dat
q) type a
q) 79h

Undefined function 'lt' for input arguments of type 'cell'

I store a list of 30k date information in variable 'enDate' of size/type <30000x1 cell> , each cell contains 11 chars string like this '01-Jan-2004'(eg.).
I want to filter out a list of true/false into trainInd, where the date is less than (before) '2007-01-01'. I try this way but matlab prompted error 'Undefined function 'lt' for input arguments of type 'cell'.' .
trainInd = enDate < datenum('2007-01-01');
What is the right way to (a) compare date, and (b) filter the array offset in 1 line of code with the above structure?
arh OK. I tried this way and it works
trainInd = datenum(enDate) < datenum('2007-01-01');