How to find if item is contained in Dict in Julia - dictionary

I'm fairly new to Julia and am trying to figure out how to check if the given expression is contained in a Dict I've created.
function parse( expr::Array{Any} )
if expr[1] == #check here if "expr[1]" is in "owl"
return BinopNode(owl[expr[1]], parse( expr[2] ), parse( expr[3] ) )
end
end
owl = Dict(:+ => +, :- => -, :* => *, :/ => /)
I've looked at Julia's documentation and other resources, but can't find any answer to this.
"owl" is the name of my dictionary that I'm trying to check. I want to run the return statement should expr[1] be either "+,-,* or /".

A standard approach to check if some dictionary contains some key would be:
:+ in keys(owl)
or
haskey(owl, :+)
Your solution depends on the fact that you are sure that 0 is not one of the values in the dictionary, which might not be true in general. However, if you want to use such an approach (it is useful when you do not want to perform a lookup in the dictionary twice: once to check if it contains some key, and second time to get the value assigned to the key if it exists) then normally you would use nothing as a sentinel and then perform the check get_return_value !== nothing (note two = here - they are important for the compiler to generate an efficient code). So your code would look like this:
function myparse(expr::Array{Any}, owl) # better pass `owl` as a parameter to the function
v = get(expr[1], owl, nothing)
if v !== nothing
return BinopNode(v, myparse(expr[2]), myparse(expr[3]))
end
# and what do we do if v === nothing?
end
Note that I use myparse name, as parse is a function defined in Base, so we do not want to have a name clash. Finally your myparse is recursive so you should define a second method to this function handling the case when expr is not an Array{Any}.

I feel like an idiot for finding this so fast, but I came up with the following solution: (Willing to hear more efficient answers however)
yes = 1
yes = get(owl,expr[1],0)
if yes != 0
#do return statement here
"yes" should get set equal to 0 if the expression is not found in the dictionary "owl". So a simple != if statement to see if it's zero fixes my problem.

Related

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.

Julia: Append to an array

Someone please help me understand this. I have the following code below. I am trying to append index[i]-1 to an empty array. However I am getting this error: "BoundsError: attempt to access 0-element Array{Any,1} at index [1]" :
sample_size_array = [9,5,6,9,2,6,9]
n_minus_1 = []
array_length = length(sample_size_array)
for i in 1:array_length
n_minus_1[i].append(sample_size_array[i] -1)
end
println(n_minus_1)
If Julia does not understand array[0] then why is i starting at 0 and not at 1?
Your code has two problems:
in the first iteration you are trying to access n_minus_1 array at index 1 while this array is still empty (has 0 length) - this throws you an error;
in Julia you do not invoke methods using a . (this symbol is used for different purposes - in this case it is parsed as field access and also would throw an error later)
To solve both those problems use push! function which appends an element at the end of an array. The code could look like this:
sample_size_array = [9,5,6,9,2,6,9]
n_minus_1 = []
array_length = length(sample_size_array)
for i in 1:array_length
push!(n_minus_1, sample_size_array[i]-1)
end
println(n_minus_1)
However in this case the whole operation can be written even simpler as:
n_minus_1 = sample_size_array .- 1
and you do not need any loop (and here you see another use of . in Julia - in this case we use it to signal that we want to subtract 1 from every element of sample_size_array).

Compare two elements of the same document in MarkLogic

I have a MarkLogic 8 database in which there are documents which have two date time fields:
created-on
active-since
I am trying to write an Xquery to search all the documents for which the value of active-since is less than the value of created-on
Currently I am using the following FLWOR exression:
for $entity in fn:collection("entities")
let $id := fn:data($entity//id)
let $created-on := fn:data($entity//created-on)
let $active-since := fn:data($entity//active-since)
where $active-since < $created-on
return
(
$id,
$created-on,
$active-since
)
The above query takes too long to execute and with increase in the number of documents the execution time of this query will also increase.
Also, I have
element-range-index for both the above mentioned dateTime fields but they are not getting used here. The cts-element-query function only compares one element with a set of atomic values. In my case I am trying to compare two elements of the same document.
I think there should be a better and optimized solution for this problem.
Please let me know in case there is any search function or any other approach which will be suitable in this scenario.
This may be efficient enough for you.
Take one of the values and build a range query per value. This all uses the range indexes, so in that sense, it is efficient. However, at some point, there is a large query that us built. It reads similiar to a flword statement. If really wanted to be a bit more efficient, you could find out which if your elements had less unique values (size of the index) and use that for your iteration - thus building a smaller query. Also, you will note that on the element-values call, I also constrain it to your collection. This is just in case you happen to have that element in documents outside of your collection. This keeps the list to only those values you know are in your collection:
let $q := cts:or-query(
for $created-on in cts:element-values(xs:QName("created-on"), (), cts:collection-query("entities"))
return cts:element-value-range-query(xs:Qname("active-since"), "<" $created-on)
)
return
cts:search(
fn:collection("entities"),
$q
)
So, lets explain what is happening in a simple example:
Lets say I have elements A and B - each with a range index defined.
Lets pretend we have the combinations like this in 5 documents:
A,B
2,3
4,2
2,7
5,4
2,9
let $ := cts:or-query(
for $a in cts:element-values(xs:QName("A"))
return cts:element-value-range-query(xs:Qname("B"), "<" $a)
)
This would create the following query:
cts:or-query(
(
cts:element-value-range-query(xs:Qname("B"), "<" 2),
cts:element-value-range-query(xs:Qname("B"), "<" 4),
cts:element-value-range-query(xs:Qname("B"), "<" 5)
)
)
And in the example above, the only match would be the document with the combination: (5,4)
You might try using cts:tuple-values(). Pass in three references: active-since, created-on, and the URI reference. Then iterate the results looking for ones where active-since is less than created-on, and you'll have the URI of the doc.
It's not the prettiest code, but it will let all the data come from RAM, so it should scale nicely.
I am now using the following script to get the count of documents for which the value of active-since is less than the value of created-on:
fn:sum(
for $value-pairs in cts:value-tuples(
(
cts:element-reference(xs:QName("created-on")),
cts:element-reference(xs:QName("active-since"))
),
("fragment-frequency"),
cts:collection-query("entities")
)
let $created-on := json:array-values($value-pairs)[1]
let $active-since := json:array-values($value-pairs)[2]
return
if($active-since lt $created-on) then cts:frequency($value-pairs) else 0
)
Sorry for not having enough reputation, hence I need to comment here on your answer. Why do you think that ML will not return (2,3) and (4,2). I believe we are using an Or-query which will take any single query as true and return the document.

Oracle named parameters

How can I use keywords with Oracle named parameters syntax ? The following gives me 'ORA-00936: missing expression' because of the 'number'-argument:
select b.g3e_fid
, a.g3e_fid
, sdo_nn_distance( 1)
from acn a, b$gc_fitface_s b
where mdsys.sdo_nn ( geometry1 => a.g3e_geometry, geometry2 => b.g3e_geometry, param => 'sdo_num_res=1', number=>1) = 'TRUE' and b.g3e_fid = 57798799;
If I run it without named parameters it is fine.
thanks, Steef
Although you can get around the reserved word issue in your call by enclosing the name in double quotes as #AvrajitRoy suggested, i.e. ... "NUMBER"=>1) = 'TRUE'..., you aren't actually achieving much. Oracle is letting you refer to the parameters by name but it isn't doing anything with that information.
MDSYS.SDO_NN is a spatial operator, not a direct call to a function. There is a function backing it up - you can see from the schema scripts for MDSYS that it's actually calling prtv_idx.nn - but the names of the formal parameters of that function are not relevant. With some digging you can see those are actually called geom, geom2, mask etc., and there isn't one called number (and you can't have a formal parameter called number, even quoting it, as far as I can tell).
The formal parameters to the operator are not named, and are effectively passed through positionally. You can't skip an argument by naming the others, as you can with a function/procedure with arguments that have default values.
So that means you can call the parameters anything you want in your call; changing the names of the first three parameters in your call to something random won't stop it working.
It also means naming them in the call is a bit pointless, but if you're just trying to document the call then you can use some other meaningful name rather than 'number' if you don't want to quote it.
Hello as mentined in you question . There are two ways in which u can eliminate this RESERVED keyword ISSUE.
1) Use "" to use any RESERVED key word for calling. But remember this is not a good coding practice.
Eg >
SELECT b.g3e_fid ,
a.g3e_fid ,
sdo_nn_distance( 1)
FROM acn a,
b$gc_fitface_s b
WHERE mdsys.sdo_nn
( geometry1 => a.g3e_geometry,
geometry2 => b.g3e_geometry,
"param" => 'sdo_num_res=1',
"NUMBER"=>1) = 'TRUE'
AND b.g3e_fid = 57798799;
2) Secondly you can just call the function without using "=>" as shown below
Eg >
SELECT b.g3e_fid ,
a.g3e_fid ,
sdo_nn_distance( 1)
FROM acn a,
b$gc_fitface_s b
WHERE mdsys.sdo_nn
( a.g3e_geometry,
b.g3e_geometry,
'sdo_num_res=1',
1) = 'TRUE'
AND b.g3e_fid = 57798799;

idl: pass keyword dynamically to isa function to test structure read by read_csv

I am using IDL 8.4. I want to use isa() function to determine input type read by read_csv(). I want to use /number, /integer, /float and /string as some field I want to make sure float, other to be integer and other I don't care. I can do like this, but it is not very readable to human eye.
str = read_csv(filename, header=inheader)
; TODO check header
if not isa(str.(0), /integer) then stop
if not isa(str.(1), /number) then stop
if not isa(str.(2), /float) then stop
I am hoping I can do something like
expected_header = ['id', 'x', 'val']
expected_type = ['/integer', '/number', '/float']
str = read_csv(filename, header=inheader)
if not array_equal(strlowcase(inheader), expected_header) then stop
for i=0l,n_elements(expected_type) do
if not isa(str.(i), expected_type[i]) then stop
endfor
the above doesn't work, as '/integer' is taken literally and I guess isa() is looking for named structure. How can you do something similar?
Ideally I want to pick expected type based on header read from file, so that script still works as long as header specifies expected field.
EDIT:
my tentative solution is to write a wrapper for ISA(). Not very pretty, but does what I wanted... if there is cleaner solution , please let me know.
Also, read_csv is defined to return only one of long, long64, double and string, so I could write function to test with this limitation. but I just wanted to make it to work in general so that I can reuse them for other similar cases.
function isa_generic,var,typ
; calls isa() http://www.exelisvis.com/docs/ISA.html with keyword
; if 'n', test /number
; if 'i', test /integer
; if 'f', test /float
; if 's', test /string
if typ eq 'n' then return, isa(var, /number)
if typ eq 'i' then then return, isa(var, /integer)
if typ eq 'f' then then return, isa(var, /float)
if typ eq 's' then then return, isa(var, /string)
print, 'unexpected typename: ', typ
stop
end
IDL has some limited reflection abilities, which will do exactly what you want:
expected_types = ['integer', 'number', 'float']
expected_header = ['id', 'x', 'val']
str = read_csv(filename, header=inheader)
if ~array_equal(strlowcase(inheader), expected_header) then stop
foreach type, expected_types, index do begin
if ~isa(str.(index), _extra=create_struct(type, 1)) then stop
endforeach
It's debatable if this is really "easier to read" in your case, since there are only three cases to test. If there were 500 cases, it would be a lot cleaner than writing 500 slightly different lines.
This snipped used some rather esoteric IDL features, so let me explain what's happening a bit:
expected_types is just a list of (string) keyword names in the order they should be used.
The foreach part iterates over expected_types, putting the keyword string into the type variable and the iteration count into index.
This is equivalent to using for index = 0, n_elements(expected_types) - 1 do and then using expected_types[index] instead of type, but the foreach loop is easier to read IMHO. Reference here.
_extra is a special keyword that can pass a structure as if it were a set of keywords. Each of the structure's tags is interpreted as a keyword. Reference here.
The create_struct function takes one or more pairs of (string) tag names and (any type) values, then returns a structure with those tag names and values. Reference here.
Finally, I replaced not (bitwise not) with ~ (logical not). This step, like foreach vs for, is not necessary in this instance, but can avoid headache when debugging some types of code, where the distinction matters.
--
Reflective abilities like these can do an awful lot, and come in super handy. They're work-horses in other languages, but IDL programmers don't seem to use them as much. Here's a quick list of common reflective features I use in IDL, with links to the documentation for each:
create_struct - Create a structure from (string) tag names and values.
n_tags - Get the number of tags in a structure.
_extra, _strict_extra, and _ref_extra - Pass keywords by structure or reference.
call_function - Call a function by its (string) name.
call_procedure - Call a procedure by its (string) name.
call_method - Call a method (of an object) by its (string) name.
execute - Run complete IDL commands stored in a string.
Note: Be very careful using the execute function. It will blindly execute any IDL statement you (or a user, file, web form, etc.) feed it. Never ever feed untrusted or web user input to the IDL execute function.
You can't access the keywords quite like that, but there is a typename parameter to ISA that might be useful. This is untested, but should work:
expected_header = ['id', 'x', 'val']
expected_type = ['int', 'long', 'float']
str = read_cv(filename, header=inheader)
if not array_equal(strlowcase(inheader), expected_header) then stop
for i = 0L, n_elemented(expected_type) - 1L do begin
if not isa(str.(i), expected_type[i]) then stop
endfor

Resources