- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Optional arguments in functions
HI folks,
I just started using JMP after spending almost 10 years using IDL,
therefore transistioning from expert to beginner.
I am mostly in the process of learning the scripting language right now.
Hopefully you'll pardon me for the occasional silly question
So I'll start with a simple question:
What is the best way to use optional arguments in functions?
When I run scripts they do complain if I use less then the number
of arguments specified in the argument list of the function.
One could conceivably use associative arrays as input instead,
and have optional keys in there, but that requires the user to
create one every time the function is called, which seems a bit
cumbersome....
Thanks!
Paolo Grigis
ABB Switzerland
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Optional arguments in functions
Paulo
If you create a user-defined function then you have the option of specifying default values for arguments. If defaults are specified then the arguments become optional.
So in the example below the 3rd argument is optional and defaults to missing (indicated by a dot in JSL)
My Function = Function( {a,b,c=.}, {Default Local},
show(IsMissing(c));
show(a,b,c)
);
My Function( 1, 2 )
Regards,
Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Optional arguments in functions
Hi Paolo
You will probably get some more helpful responses if you can give some examples of the type of functions that you are using.
Typically functions have required arguments that need to be parsed in a specific order, but there are additional optional arguments, often specified by keywords, that can be specified in any position and omitted if not required.
As far as I am aware it is not possible to parse the arguments as a list, they have to be specified indivdually, except of course where the argument item is itself a list. However, there is a JSL function called FUNCTION that allows you to create user-defined functions. I often use this capability to "wrap" an existing JSL function so that I have more control of the input arguments.
Regards,
Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Optional arguments in functions
Hi Dave,
thanks for your answer.
That's exactly what I am looking for - optional keywords - only
I am not sure how to implement them in my functions.
For instance, if I am creating a user-defined function called myplot
to do a plot, and I would like to be able to call it using
myplot(x,y)
or
myplot(x,y,xRange,yRange)
(or whatever is the required syntax is to specify xRange and yRange
as keywords).
If xRange and yRange are specified, I will use them, if not
I will compute some default values for them.
My question was how to implement that in my user defined function.
If I use
function({x,y,xRange,yRange},
my commands...
);
it will complain if I call it with only two arguments as in
dummy=myplot(x,y)
and throw an error message about insufficent arguments.
I hope this make it a bit more clear. Maybe I am missing
something obvious but I find the reference for the commands
at the end of the scripting guide somewhat less detailed then
what I am used to.
Paolo Grigis
ABB Switzerland
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Optional arguments in functions
Paulo
If you create a user-defined function then you have the option of specifying default values for arguments. If defaults are specified then the arguments become optional.
So in the example below the 3rd argument is optional and defaults to missing (indicated by a dot in JSL)
My Function = Function( {a,b,c=.}, {Default Local},
show(IsMissing(c));
show(a,b,c)
);
My Function( 1, 2 )
Regards,
Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Optional arguments in functions
Ah yes, that's what I was looking for thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Optional arguments in functions
well, on second thought, what if I have a function with multiple optional
arguments, say,
PGtest=function({a,b,c=1,d=2,e=3},{Default Local},
Show(a,b,c,d,e);
);
I want to specify arguments a,b and e but not c and d
(in this call, maybe in future calls i will specify a,b and d
instead...).
Do I have to use
PGTest(a,b, , , e=11)
? That becomes unwieldy with more than a few arguments to skip...
Is there a way to do this without having to specify the middle
arguments?
Thanks,
Paolo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Optional arguments in functions
Taking up Dave's earlier point about lists, something I often do myself is to supply my user-defined functions with a single list containing as many arguments as I want to supply, as opposed to simply a set of them. I can then perform tests on the list within the function to see what's there and what isn't. For example, the following function tests first of all to see if what I've supplied it with actually is a list, and then if it is, either raises the first number in the list to the power of the second if a second number is supplied, or square-roots it otherwise. If the argument isn't a list but is simply a number, that number is square-rooted anyway. That provides me with quite a bit of flexibility in terms of how I can use the function:
RootFn = function({Params},
show(Params);
if(is list(Params),
if(nItems(Params) < 2, Result = Params[1]^0.5, Result = Params[1]^Params[2])
,
Result = Params^0.5
);
Result
);
MyParams = {6, 3}; show(RootFn(MyParams));
MyParams = {6, 2}; show(RootFn(MyParams));
MyParams = {6, 0.5}; show(RootFn(MyParams));
MyParams = {6}; show(RootFn(MyParams));
MyParams = 6; show(RootFn(MyParams));
You could try something like this, inserting a call to your myplot function into the user-defined function wherever appropriate.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Optional arguments in functions
If you don't want to parse all th arguments then you could use a list a David suggested above. You would still need to insert the values in the correct position in the list. Alternatively use an associative array which gives you key-value pairs, so you could use the key as the label for the parameter e.g. myArray["c"] = 10.
If you are familiar with object-oriented programming then you can implement the equivalent of a protected class. You can then have a function that acts as a method call (i.e. do something ) which uses properties set using functions that act as accessors (i.e. set value / get value). These properties can be stored in a namespace (and if you want to can put all these definitions into a separate file and use the Include function to reference them).
Below is some example code that illustrates this principle. There is a function (method call) called Standard Capability Analysis that takes 2 arguments - a reference to the data table column, and the type of distribution to use for the calculation. The method call also requires specification values, but these are set using accessor methods Set LSL / Get LSL etc. The values associated with these properties are stored in a namespace.
capdat = New Namespace( "MyCapabilityAnalysis" );
capdat:lsl = List();
capdat:target = List();
capdat:usl = List();
Get LSL = Function({colIndex},{Default Local},
retVal = .;
If (!IsMissing(capdat:lsl[colIndex]),
retVal = capdat:lsl[colIndex]
,
Get Specs(colIndex);
retVal = capdat:lsl[colIndex]
);
retVal
);
Get Target = Function({colIndex},{Default Local},
retVal = .;
If (!IsMissing(capdat:target[colIndex]),
retVal = capdat:target[colIndex]
,
Get Specs(colIndex);
retVal = capdat:target[colIndex]
);
retVal
);
Get USL = Function({colIndex},{Default Local},
retVal = .;
If (!IsMissing(capdat:usl[colIndex]),
retVal = capdat:usl[colIndex]
,
Get Specs(colIndex);
retVal = capdat:usl[colIndex]
);
retVal
);
Standard Capability Analysis = Function({colIndex,distType},{Defalt Local},
lsl = Get LSL(colIndex);
target = Get Target(colIndex);
USL = Get USL(colIndex);
pY = Column( this:yCols[colIndex] ) << Get Name;
funcDef = Eval Insert( "\[
this:dd = this:tempDt << Distribution(
Continuous Distribution(
Column( ^pY^ ),
Quantiles( 0 ),
Moments( 0 ),
Vertical( 0 ),
Outlier Box Plot( 0 ),
Capability Analysis( LSL(^lsl^),USL(^usl^),Target(^target^) ),
Fit Distribution(
^distType^(
Goodness of Fit( 1 )
),
)
)
);
]\");
Eval( Parse( funcDef ) );
);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Optional arguments in functions
Well,
in the end I decided to have a procedure that converts a list
of strings like, say,
{"xrange=[-1,6]","WinSize=[200,400]","yRange=[-3.5, 7.77]"}
into an associative array and then use the associative array as
input in my plot function.
The converter checks that the key=value pairs have keys that belong
to the list of "allowed" keys and doesn't care about the order, such that
{"yRange=[-3.5, 7.77]","xrange=[-1,6]"}
is also an acceptable input.
Arguably that's only marginally different then creating the array
directly... but it does have the advantage to reject keywords that
aren't allowed and can also set default values if needed.
In the plot function I also check for missing keys and set them to a
default value.
This would be easier if we could create objects directly
Ciao,
Paolo