How to suppress function return - julia

Suppose I have a function that has multiple returned values (shown below). However, this output is not informative as users do not know what each value stands for unless they look up the function definition. So I would like to use println() to print the results with appropriate names to the screen, while suppressing the the actual returned values from being printed on the screen. In R, the function invisible() does that, but how do you do the same thing in Julia?
function trimci(x::Array; tr=0.2, alpha=0.05, nullvalue=0)
se=sqrt(winvar(x,tr=tr))./((1-2.*tr)*sqrt(length(x)))
ci=cell(2)
df=length(x)-2.*floor(tr.*length(x))-1
ci=[tmean(x, tr=tr)-qt(1-alpha./2, df).*se, tmean(x, tr=tr)+qt(1-alpha./2, df).*se]
test=(tmean(x,tr=tr)-nullvalue)./se
sig=2.*(1-pt(abs(test),df))
return ci, tmean(x, tr=tr), test, se, sig
end

In addition to what Harlan and Stefan said, let me share an example from the ODBC.jl package (source here).
One of my favorite features of Julia over other languages is how dead simple it is to create custom types (and without performance issues either!). Here's a custom type, Metadata, that simply holds several fields of data that describe an executed query. This doesn't necessarily need its own type, but it makes it more convenient passing all this data between functions as well as allowing custom formatting of its output by overloading the Base.show() function.
type Metadata
querystring::String
cols::Int
rows::Int
colnames::Array{ASCIIString}
coltypes::Array{(String,Int16)}
colsizes::Array{Int}
coldigits::Array{Int16}
colnulls::Array{Int16}
end
function show(io::IO,meta::Metadata)
if meta == null_meta
print(io,"No metadata")
else
println(io,"Resultset metadata for executed query")
println(io,"------------------------------------")
println(io,"Columns: $(meta.cols)")
println(io,"Rows: $(meta.rows)")
println(io,"Column Names: $(meta.colnames)")
println(io,"Column Types: $(meta.coltypes)")
println(io,"Column Sizes: $(meta.colsizes)")
println(io,"Column Digits: $(meta.coldigits)")
println(io,"Column Nullable: $(meta.colnulls)")
print(io,"Query: $(meta.querystring)")
end
end
Again, nothing fancy, but illustrates how easy it really is to define a custom type and produce custom output along with it.
Cheers.

One thing you could do would be to define a new type for the return value for this function, call it TrimCIResult or something. Then you could define appropriate methods to show that object in the REPL. Or you may be able to generalize that solution with a type hierarchy that could be used for storing the results from and displaying any statistical test.

The value nothing is how you return a value that won't print: the repl specifically checks for the value nothing and prints nothing if that's the value returned by an expression. What you're looking to do is to return a bunch of values and not print them, which strikes me as rather odd. If a function returns some stuff, I want to know about it – having the repl lie to users seems like a bad idea. Harlan's suggesting would work though: define a type for this value with the values you don't want to expose to the user as fields and customize its printing so that the fields you don't want to show people aren't printed.

Related

KEYWORD_SET in IDL

I am new to IDL and find the KEYWORD_SET difficult to grasp. I understand that it is a go no go switch. I think its the knocking on and off part that I am having difficulty with. I have written a small program to master this as such
Pro get_this_done, keyword1 = keyword1
WW=[3,6,8]
PRINT,'WW'
print,WW
y= WW*3
IF KEYWORD_Set(keyword1) Then BEGIN
print,'y'
print,y
ENDIF
Return
END
WW prints but print, y is restricted by the keyword. How do I knock off the keyword to allow y to print.
Silly little question, but if somebody can indulge me, it would be great.
After compiling the routine, type something like
get_this_done,KEYWORD1=1b
where the b after the one sets the numeric value to a BYTE type integer (also equivalent to TRUE). That should cause the y-variable to be printed to the screen.
The KEYWORD_SET function will return a TRUE for lots of different types of inputs that are basically either defined or not zero. The IF loop executes when the argument is TRUE.
Keywords are simply passed as arguments to the function:
get_this_done, KEYWORD1='whatever'
or also
get_this_done, /KEYWORD1
which will give KEYWORD1 the INT value of 1 inside the function. Inside the function KEYWORD_SET will return 1 (TRUE) when the keyword was passed any kind of value - no matter whether it makes sense or not.
Thus as a side note to the question: It often is advisable to NOT use KEYWORD_SET, but instead resort to a type query:
IF SIZE(variable, /TNAME) EQ 'UNDEFINED' THEN $
variable = 'default value'
It has the advantage that you can actually check for the correct type of the keyword and handle unexpected or even different variable types:
IF SIZE(variable, /TNAME) NE 'LONG' THEN BEGIN
IF SIZE(variable, /TNAME) EQ 'STRING' THEN $
PRINT, "We need a number here... sure that the cast to LONG works?"
variable = LONG(variable)
ENDIF

i don't think i understand function enclosures

I'm trying to package some code I use for data analysis so that other workers can use it. Currently, I'm stuck trying to write a simple function that imports data from a specific file type generated by a datalogger and trims it for use by other functions. Here's the code:
import<-function(filename,type="campbell",nprobes){
if (filename==TRUE){
if (type=="campbell"){
message("File import type is from Campbell CR1000")
flux.data<<-read.table(filename,sep=",",header=T,skip=1)
flux.data<<-flux.data[,-c(1,2)];flux.data<<-flux.data[-c(1,2),]
if (nprobes=="missing"){
nprobes<-32
}
flux.data<<-flux.data[,c(1:nprobes)]
flux.data.names<<-colnames(flux.data) #Saves column names
}
}
}
Ideally, the result would be a dataframe/matrix flux.data and a concomittant vector/list of the preserved column headers flux.data.names. The code runs and the function executes without errors, but the outputs aren't preserved. I usually use <<- to get around the function enclosure but its not working in this case - any suggestions?
I think the real problem is that I don't quite understand how enclosures work, despite a lot of reading... should I be using environment to assign environments within the function?
User joran answered my question in the comments above:
The critical issue was just in how the function was written: the conditional at the start (if filename==TRUE) was intended to see if filename was specified, and instead was checking to see if it literally equaled TRUE. The result was the conditional never being met, and no function output. Here's what fixed it:
import<-function(filename,type="campbell",nprobes){
if (exists(filename){
if (type=="campbell"){
#etc....
Another cool thing he pointed out was that I didn't need the <<- operator to utilize the function output and instead could write return(flux.data). This is a much more flexible approach, and helped me understand function enclosures a lot better.

Function signature not found despite showing with methods(...)

I am new to Julia, so this might be trivial.
I have a function definition within a module that looks like (using URIParser):
function add!(graph::Graph,
subject::URI,
predicate::URI,
object::URI)
...
end
Outside of the module, I call:
add!(g, URIParser.URI("http://test.org/1"), URIParser.URI("http://test.org/2"), URIParser.URI("http://test.org/1"))
Which gives me this error:
ERROR: no method add!(Graph,URI,URI,URI)
in include at boot.jl:238
in include_from_node1 at loading.jl:114
at /Users/jbaran/src/RDF/src/RDF.jl:79
Weird. Because when I can see a matching signature:
julia> methods(RDF.add!)
# 4 methods for generic function "add!":
add!(graph::Graph,subject::URI,predicate::URI,object::Number) at /Users/jbaran/src/RDF/src/RDF.jl:29
add!(graph::Graph,subject::URI,predicate::URI,object::String) at /Users/jbaran/src/RDF/src/RDF.jl:36
add!(graph::Graph,subject::URI,predicate::URI,object::URI) at /Users/jbaran/src/RDF/src/RDF.jl:43
add!(graph::Graph,statement::Statement) at /Users/jbaran/src/RDF/src/RDF.jl:68
At first I thought it was my use of object::Union(...), but even when I define three functions with Number, String, and URI, I get this error.
Is there something obvious that I am missing? I am using Julia 0.2.1 x86_64-apple-darwin12.5.0, by the way.
Thanks,
Kim
This looks like you may be getting bit by the very slight difference between method extension and function shadowing.
Here's the short of it. When you write function add!(::Graph, ...); …; end;, Julia looks at just your local scope and sees if add! is defined. If it is, then it will extend that function with this new method signature. But if it's not already defined locally, then Julia creates a new local variable add! for that function.
As JMW's comment suggests, I bet that you have two independent add! functions. Base.add! and RDF.add!. In your RDF module, you're shadowing the definition of Base.add!. This is similar to how you can name a local variable pi = 3 without affecting the real Base.pi in other scopes. But in this case, you want to merge your methods with the Base.add! function and let multiple dispatch take care of the resolution.
There are two ways to get the method extension behavior:
Within your module RDF scope, say import Base: add!. This explicitly brings Base.add! into your local scope as add!, allowing method extension.
Explicitly define your methods as function Base.add!(graph::Graph, …). I like this form as it more explicitly documents your intentions to extend the Base function at the definition site.
This could definitely be better documented. There's a short reference to this in the Modules section, and there's currently a pull request that should be merged soon that will help.

How to create a collection in Julia?

This seems like a really basic question, but can't find the answer. How do I create a collection in Julia? For example, I want to open a text file and parse each line to create an (iterable or otherwise) collection. Obviously I don't know how many elements there are in advance.
I can iterate through the lines like this
I = each_line(open(fileName,"r"))
state = start(I)
while !done(I, state)
(i, state) = next(I, state)
println(i)
end
But I don't know how to put each i into an array or other collection. I tried
map( i -> println(i), each_line(open(fileName,"r") ) )
But got the error
no method map(Function,EachLine)
You could do this:
lines = String[]
for line in each_line(open(fileName))
push!(lines, line)
end
And then lines contains the list of lines. You need the String in the first line to make the array extensible.
Standard collections and supported operations are mainly covered in the standard library documentation.
Specifically, the Deques section covers all of the operations supported by the 1d Array type (vector), including push! and pop! as well as insertion, resizing, etc.
Omar's answer is correct, and I will just add a small qualification: String[] creates a 1d array of Strings. The same constructor syntax may be used for example to create Int[], Float[], or even Any[] vectors. The latter type may hold objects of any type.
Depending on your Julia version, you may also be able to write collect(eachline(open("LICENSE.md"))) or [eachline(open("LICENSE.md"))...]. I think these won't work in 0.1.x versions but will working in newer 0.2 development versions (which are recommended at this point – 0.2 is on its way soon).

How to stop evaluating if the first condion has been passed

I try to evaluate a field in my report but it fails every time :
= IIf(Fields!lectcrs_hrs.IsMissing,
Round(Fields!lectcrs_fee.Value * "1.00", 2),
Round(Fields!lectcrs_fee.Value * Fields!lectcrs_hrs.Value, 2))
in the case of Fields!lectcrs_hrs.IsMissing = true my field is empty and i find that the reason that the second case Round(Fields!lectcrs_fee.Value * Fields!lectcrs_hrs.Value, 2) contains a missing field Fields!lectcrs_hrs .why it checks the second case if it passes the first one !
How to fix this problem ?
The behavior you are looking for is called "short-circuiting" and, unfortunately, the IIf function in Visual Basic does not offer that. The reason being is that IIf() is a ternary function and, as such, all arguments passed into it are evaluated before the function call occurs. A ternary operator (If() in VB 9+), on the other hand, does support conditional evaluation. However, I do not believe that the If() operator can be used as a part of an expression in SSRS.
Given the fact that you are trying to use a field which may or may not exist at run time, I suggest that you create a custom function in your report to handle the proper checking and return values. For reference, take a look at this blog post, which covers the same scenario.

Resources