How to correctly use jq's in() function - jq

I'm trying to understand in() function of jq.
https://jqplay.org/s/BR1KbCjP8u
filter:
map( in(["ms", "is", "bad"]) )
input:
["apple","is","bad"]
I expected the output [false,true,true] because for each element of the input array:
"apple" is not in ["ms", "is", "bad"] so false
"is" is in ["ms", "is", "bad"] so true
"bad" is in ["ms", "is", "bad"] so true
Obviously this is wrong because I get error:
jq: error (at <stdin>:0): Cannot check whether array has a string key
exit status 5
What is wrong with this and how to correctly use the in() function when passing ["ms","is","bad"] in the filter? I want to check if each element in the input array is found in this list.

Maybe you were looking for the IN (not in) function. Also, it takes a stream of elements, not an array.
map(IN("ms", "is", "bad"))
[false,true,true]
Demo
From the manual:
in
The builtin function in returns whether or not the input key is in the given object, or the input index corresponds to an element in the given array. It is, essentially, an inversed version of has.
IN
This builtin outputs true if . appears in the given stream, otherwise it outputs false.

I was using in() incorrectly.
https://jqplay.org/s/FJcNTgplG6
filter:
map(in(["apple","is","bad"]))
input:
[3, 2, 1, 0]
output:
[
false,
true,
true,
true
]
It's testing if the indexes of the filter array are found in the input array.

Related

is.null on lists vs. other objects

Consider the following scenario:
demo <- list()
is.null(demo$first)
is.null(undefined_object)
The first scenario returns TRUE as it's a NULL element of the list. Why doesn't undefined_object return NULL as it's not an object in the global environment?
If we need a similar TRUE option, one option is to reference that object with .GlobalEnv and check if it is NULL
is.null(.GlobalEnv$undefined_object)
#[1] TRUE
with OP's example, we are checking whether the 'first' is NULL in the environment of 'demo' object which is already created, but the undefined_object is not created and thus we can check it in context with the global environment
is.null(demo$first)
#[1] TRUE
is.null(.GlobalEnv$demo$first)
#[1] TRUE
demo$first calls the function $, and that function returns NULL if the right hand argument is not found.
undefined_object is not a function call, it's just the name of an object, but that object doesn't exist.
If you just print the two expressions, you'll see that they are different:
> demo$first
NULL
> undefined_object
Error: object 'undefined_object' not found
So when you put them in the is.null() call, you get different results, as you saw.

How to pass FsCheck Test Correctly

let list p = if List.contains " " p || List.contains null p then false else true
I have such a function to check if the list is well formatted or not. The list shouldn't have an empty string and nulls. I don't get what I am missing since Check.Verbose list returns falsifiable output.
How should I approach the problem?
I think you don't quite understand FsCheck yet. When you do Check.Verbose someFunction, FsCheck generates a bunch of random input for your function, and fails if the function ever returns false. The idea is that the function you pass to Check.Verbose should be a property that will always be true no matter what the input is. For example, if you reverse a list twice then it should return the original list no matter what the original list was. This property is usually expressed as follows:
let revTwiceIsSameList (lst : int list) =
List.rev (List.rev lst) = lst
Check.Verbose revTwiceIsSameList // This will pass
Your function, on the other hand, is a good, useful function that checks whether a list is well-formed in your data model... but it's not a property in the sense that FsCheck uses the term (that is, a function that should always return true no matter what the input is). To make an FsCheck-style property, you want to write a function that looks generally like:
let verifyMyFunc (input : string list) =
if (input is well-formed) then // TODO: Figure out how to check that
myFunc input = true
else
myFunc input = false
Check.Verbose verifyMyFunc
(Note that I've named your function myFunc instead of list, because as a general rule, you should never name a function list. The name list is a data type (e.g., string list or int list), and if you name a function list, you'll just confuse yourself later on when the same name has two different meanings.)
Now, the problem here is: how do you write the "input is well-formed" part of my verifyMyFunc example? You can't just use your function to check it, because that would be testing your function against itself, which is not a useful test. (The test would essentially become "myFunc input = myFunc input", which would always return true even if your function had a bug in it — unless your function returned random input, of course). So you'd have to write another function to check if the input is well-formed, and here the problem is that the function you've written is the best, most correct way to check for well-formed input. If you wrote another function to check, it would boil down to not (List.contains "" || List.contains null) in the end, and again, you'd be essentially checking your function against itself.
In this specific case, I don't think FsCheck is the right tool for the job, because your function is so simple. Is this a homework assignment, where your instructor is requiring you to use FsCheck? Or are you trying to learn FsCheck on your own, and using this exercise to teach yourself FsCheck? If it's the former, then I'd suggest pointing your instructor to this question and see what he says about my answer. If it's the latter, then I'd suggest finding some slightly more complicated function to use to learn FsCheck. A useful function here would be one where you can find some property that should always be true, like in the List.rev example (reversing a list twice should restore the original list, so that's a useful property to test with). Or if you're having trouble finding an always-true property, at least find a function that you can implement in at least two different ways, so that you can use FsCheck to check that both implementations return the same result for any given input.
Adding to #rmunn's excellent answer:
if you wanted to test myFunc (yes I also renamed your list function) you could do it by creating some fixed cases that you already know the answer to, like:
let myFunc p = if List.contains " " p || List.contains null p then false else true
let tests =
testList "myFunc" [
testCase "empty list" <| fun()-> "empty" |> Expect.isTrue (myFunc [ ])
testCase "nonempty list" <| fun()-> "hi" |> Expect.isTrue (myFunc [ "hi" ])
testCase "null case" <| fun()-> "null" |> Expect.isFalse (myFunc [ null ])
testCase "empty string" <| fun()-> "\"\"" |> Expect.isFalse (myFunc [ "" ])
]
Tests.runTests config tests
Here I am using a testing library called Expecto.
If you run this you would see one of the tests fails:
Failed! myFunc/empty string:
"". Actual value was true but had expected it to be false.
because your original function has a bug; it checks for space " " instead of empty string "".
After you fix it all tests pass:
4 tests run in 00:00:00.0105346 for myFunc – 4 passed, 0 ignored, 0
failed, 0 errored. Success!
At this point you checked only 4 simple and obvious cases with zero or one element each. Many times functions fail when fed more complex data. The problem is how many more test cases can you add? The possibilities are literally infinite!
FsCheck
This is where FsCheck can help you. With FsCheck you can check for properties (or rules) that should always be true. It takes a little bit of creativity to think of good ones to test for and granted, sometimes it is not easy.
In your case we can test for concatenation. The rule would be like this:
If two lists are concatenated the result of MyFunc applied to the concatenation should be true if both lists are well formed and false if any of them is malformed.
You can express that as a function this way:
let myFuncConcatenation l1 l2 = myFunc (l1 # l2) = (myFunc l1 && myFunc l2)
l1 # l2 is the concatenation of both lists.
Now if you call FsCheck:
FsCheck.Verbose myFuncConcatenation
It tries a 100 different combinations trying to make it fail but in the end it gives you the Ok:
0:
["X"]
["^"; ""]
1:
["C"; ""; "M"]
[]
2:
[""; ""; ""]
[""; null; ""; ""]
3:
...
Ok, passed 100 tests.
This does not necessarily mean your function is correct, there still could be a failing combination that FsCheck did not try or it could be wrong in a different way. But it is a pretty good indication that it is correct in terms of the concatenation property.
Testing for the concatenation property with FsCheck actually allowed us to call myFunc 300 times with different values and prove that it did not crash or returned an unexpected value.
FsCheck does not replace case by case testing, it complements it:
Notice that if you had run FsCheck.Verbose myFuncConcatenation over the original function, which had a bug, it would still pass. The reason is the bug was independent of the concatenation property. This means that you should always have the case by case testing where you check the most important cases and you can complement that with FsCheck to test other situations.
Here are other properties you can check, these test the two false conditions independently:
let myFuncHasNulls l = if List.contains null l then myFunc l = false else true
let myFuncHasEmpty l = if List.contains "" l then myFunc l = false else true
Check.Quick myFuncHasNulls
Check.Quick myFuncHasEmpty
// Ok, passed 100 tests.
// Ok, passed 100 tests.

returning result from binary search tree

I'm trying to determine if a value is found in the binary search tree.
If it's found, the value is printed. If not, a message is printed saying it wasn't found.
My problem is that even when the value is found, the message is printed saying that it wasn't found.
My result seems to reset even after returning True, and I am confused as to why this is happening... I think it's because I'm calling the function recursively, but I don't know how to fix this problem. Any help would be appreciated, thank you.
def lookUpVal(bst,val,result):
if bst == None:#base case, if the tree is 0, return none
return
elif bst['data'] == val:
print ("value found")
result = True
return result
lookUpVal(bst['left'],val,result)
lookUpVal(bst['right'],val,result)
def main(bst):
print ("Enter the value you want to find")
val = int(input())
result = 0
lookUpVal(bst,stud,result)
if result != True:
print ("Value not found")
The problem is with your result variable, you probably think you are passing by reference, what is actually happening is close to pass-by-value.
Here is an example:
def voo(x):
print('x:',id(x))
x = True
print('x:',id(x))
p = False
print('p:',id(p))
voo(p)
print('value of p:',p)
print('p:',id(p))
'id' returns a unique id for any object, including of course boolean ones.
Here's the output: (numbers will vary in your pc)
p: 1613433952
x: 1613433952
x: 1613433936
value of p: False
p: 1613433952
First note, False in output, p's value has not changed. But to see why that's happening, closely examine the id values, specially how x's id changed after assignment in function; which means python allocated a new object. And old one is still referenced by 'p', as evident in it's output, which has not changed.

What is the '<>' asp operator?

Simple question. I tried searching, by googling for less than and greater than signs doesn't return great results.
My guess is that <> is basically equivalent to not equals. So, the below expression would be false if x is null or an empty string, and true otherwise?
if x <> ""
This would also return True if a value is contained in the entity listed. This is commonly used to look for quesrystring or form elements that may or may not have been supplied:
If Request("someFieldName") <> "" Then
' Field was provided and has a value, so use the field value
Else
' Field was either empty or not provided, in which case use something else
End If
Hope this helps.
So, the below expression would be false if x is null or an empty string, and true otherwise?
Not exactly. There are few function to verify value:
IsNull(expression)
IsNull returns True if expression is Null, that is, it contains no
valid data; otherwise, IsNull returns False. If expression consists of
more than one variable, Null in any constituent variable causes True
to be returned for the entire expression.
The Null value indicates that the variable contains no valid data.
Null is not the same as Empty, which indicates that a variable has not
yet been initialized. It is also not the same as a zero-length string
(""), which is sometimes referred to as a null string.
IsEmpty(expression)
The expression argument can be any expression. However, because
IsEmpty is used to determine if individual variables are initialized,
the expression argument is most often a single variable name.
IsEmpty returns True if the variable is uninitialized, or is
explicitly set to Empty; otherwise, it returns False. False is always
returned if expression contains more than one variable.
Other good function
VarType(varname)
Returns a value indicating the subtype of a variable.
Use Windows Script 5.6 Documentation from http://www.microsoft.com/en-us/download/details.aspx?id=2764

Pass returned list Erlang

I want to pass my returned list into case but I'm getting the
"->" Error
Here is my code:
parse ( Element, [] ) -> false;
parse(Element,N) -> re:split(N,"([*+])",[{return,list}]),
parse ( Element, [ Item | ListTail ] ) ->
case ( Item == Element ) of
true -> true;
false -> listFind(Element, ListTail)
end.
I don't know how to pass the returned list into the case, Can anyone help?
If you want to test the result of re:split/3 in a case, you need to get rid of the extraneous function head stuck inside the second clause of parse/2. You also don't need the first clause of parse/2, as it's unnecessary and not used. Just look through the result of re:split/3 for Element, like this:
parse(Element, N) ->
Elements = re:split(N,"([*+])",[{return,list}]),
lists:member(Element, Elements).
If for example the argument N has the value "a*b+c*d+e", the re:split/3 call returns ["a","*","b","+","c","*","d","+","e"] (and let's assume that's really what you want). The call to lists:member/2 then searches that result for the value of Element, returning true if found or false if not found.

Resources