cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
jthi
Super User

Tips and Tricks from JMP Scripters Club Q2 (2022)

I did very quickly present some tips and tricks for JMP Scripting during JMP Scripters Club Q2 .

This video is currently being processed. Please try again in a few minutes.
(view in My Videos)

 

My technical explanations might not be correct and I might use wrong terms here and there, as I don't fully care to understand everything  (only most) what is going on JMP and JSL, I just want my code to work well and fast.

 

Tip1 Enable JMP Script Editor's Embedded Log

Enabling embedded log allows you to quickly and easily see JMP Log directly in JMP's Script Editor. You can enable Embedded Log from JMP Preferences under Script Editor. JMP16 also allows you to change the height of Embedded log (I personally use values between 25%-30%).

jthi_0-1652960163910.png

Maybe helpful links

Text Log in JMP (jmp.com help) 

 

Tip2 For JMP16+ enable Enhanced Log

With JMP16 new feature was released called Enhanced Log. This keeps track what you have done interactively in JMP and provides script to those actions and makes it easier to let JMP write scripts for you.
Enhanced Log can be enabled from JMP's Preferences. You can also make modifications on what is captured and how the Enhanced Log looks.

jthi_1-1652960347034.png

Maybe helpful links

Enhanced Log and Action Recorder - New in JMP 16 and JMP Pro 16 

The Enhanced Log in JMP 16: This changes everything 

Enhanced Log in JMP (jmp.com) 

 

 

Tip3 Evaluating values from variables to expressions

This is fairly common topic in JMP Community: why value from variable isn't getting evaluated into formula for example. This basically means that the values didn't get evaluated "out of" the expressions (variables). Below are for examples to demonstrate the issue and possible solutions (my preferred method is Eval(EvalExpr()) + Expr()).

Example1 Formula

In this example two columns are being created, one without and with Eval(EvalExpr()). The one without is left with the variable name in formula

 

View more...
Names Default To Here(1);

// Create demo table	
dt = New Table("Demo",
	Add Rows(6),
	New Column("Label", Character, "Nominal", Set Values({"A", "A", "A", "B", "B", "B"})),
	New Column("x", Numeric, "Continuous", Format("Best", 12), Set Values([1, 2, 3, 4, 5, 6])),
	New Column("y1", Numeric, "Continuous",
		Set Values(
			[0.540628764079884, 0.0138843499589711, 0.363861175486818, 0.697015449637547, 0.114948588656262, 0.685370508348569]
		)
	),
	New Column("y2", Numeric, "Continuous",
		Set Values(
			[0.540628764079884, 0.0138843499589711, 0.363861175486818, 0.697015449637547, 0.114948588656262, 0.685370508348569]
		)
	)
);


power = 3;
new_col = dt << New Column("x to " || char(power), Numeric, Continuous, Formula(:x^power));
Show(new_col << Get Formula);

power = 4;
Eval(EvalExpr(new_col = dt << New Column("x to " || char(power), Numeric, Continuous, Formula(:x^Expr(power)))));
Show(new_col << Get Formula);

Data table and formulas (take note how formulas look like and what has happened to x to 3 values (they are to power 4 now))

 

jthi_2-1652961665754.png

If you were to save this data table, reopen it and added new row, you would get following error message, because the data table doesn't know what power's value is.

jthi_3-1652961688027.png

This is because I'm using Names Default To Here(1); in the example script, but the error is a good thing in this case. If I wasn't using Names Default To Here(1); to start my script (see extra tip), I would add the power variable to global namespace and the data table would still know power value in the same JMP session. Now I might thing that my data table works as it is supposed to and I go sharing the table and who ever I shared it to will be left wondering why it isn't working.

 

Example2 Set Spec Limits

This example script demonstrates how you can use Eval(EvalExpr()) to get values into column properties (in this case Spec Limits). 

 

View more...
Names Default To Here(1);

// Create demo table	
dt = New Table("Demo",
	Add Rows(6),
	New Column("Label", Character, "Nominal", Set Values({"A", "A", "A", "B", "B", "B"})),
	New Column("x", Numeric, "Continuous", Format("Best", 12), Set Values([1, 2, 3, 4, 5, 6])),
	New Column("y1", Numeric, "Continuous",
		Set Values(
			[0.540628764079884, 0.0138843499589711, 0.363861175486818, 0.697015449637547, 0.114948588656262, 0.685370508348569]
		)
	),
	New Column("y2", Numeric, "Continuous",
		Set Values(
			[0.540628764079884, 0.0138843499589711, 0.363861175486818, 0.697015449637547, 0.114948588656262, 0.685370508348569]
		)
	),
	New Column("y3", Numeric, "Continuous",
		Set Values(
			[0.540628764079884, 0.0138843499589711, 0.363861175486818, 0.697015449637547, 0.114948588656262, 0.685370508348569]
		)
	)
);

Column(dt, "y1") << Set Property(
	"Spec Limits",
	{LSL(-1), USL(1), Show Limits(1)}
);

lower_limit = 0.5;
upper_limit = 1.5;
Column(dt, "y2") << Set Property(
	"Spec Limits",
	{LSL(lower_limit), USL(upper_limit), Show Limits(1)}
);

Eval(
	EvalExpr(
		Column(dt, "y2") << Set Property(
			"Spec Limits",
			{LSL(Expr(lower_limit)), USL(Expr(upper_limit)), Show Limits(1)}
		);
	)
);

 

 

Example3 << On Close

As a last example I will demonstrate how you could protect your script from overwriting references by accident. I shortly talked about this in the 2022_Q1 MakeOverChallenge: Action on mouse click in various ways Challenge B

 

If you run this script and close the bivariate window, you will notice that Semiconductor Capability table is being closed instead of Big Class. This is because when the bivariate window is closed, dt is already referencing to Semiconductor Capability (could have also used different variable name, for example dt_semi)

View more...
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);

biv << On Close(
	close(dt, no save)
);
dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");

And if you run this code, the correct table will get closed. This is because we are evaluating the reference into the Big Class table to the << On close statement

View more...
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
biv = dt << Bivariate(Y(:Weight), X(:Height), Nonpar Density);

Eval(EvalExpr(
	biv << On Close(
		Close(Expr(biv << Get Data Table), no save)
	);
));

dt = Open("$SAMPLE_DATA/Semiconductor Capability.jmp");

Maybe helpful links

Insert one expression into another using Eval Insert, Eval Expr, Parse, and Substitute 

Expression Handling Functions: Part I - Unraveling the Expr(), NameExpr(), Eval(), ... Conundrum 

Expressions (JMP Help, jmp.com) 

Expression Functions (JMP Help, jmp.com) 

 

Extra Tip Start your scripts with Names Default To Here(1);

This will protect you from polluting namespace with global variables and avoid issues down the road. This is something I do always when I start a new script file even if I were to to use custom namespace. I do this to avoid even creating by accident variables in global namespace.

Maybe helpful links

Advanced Scoping and Namespaces (JMP Help, jmp.com)  (very good read, it has multiple pages, make sure to check most of them!)

Rules for Resolving Names (JMP Help, jmp.com) 

Essential Scripting for Efficiency and Reproducibility: Do Less to Do More (2019-US-TUT-290) 

-Jarmo
4 REPLIES 4
Ressel
Level VI

Re: Tips and Tricks from JMP Scripters Club Q2 (2022)

With regards to the 

Names default to here (1);

I also saw some people use

Clear globals (1);

in addition at the beginning of a script.

 

I feel I can understand why that would be useful, but what is your opinion on that?

Re: Tips and Tricks from JMP Scripters Club Q2 (2022)

@Ressel, personally I'd avoid Clear Globals(1) since it may interfere with other scripts that may be running. It would be much safer to scope any script variables locally or to their own Namespace.

SDF1
Super User

Re: Tips and Tricks from JMP Scripters Club Q2 (2022)

Hi @Ressel ,

 

  I agree with @DonMcCormack , it's better not to clear the global variables. One example of why you wouldn't want to do that could be when you have a "Recall" functionality in your script, where you can click the Recall button and then any variables or columns that you've cast into roles or values you've entered for use in a JMP platform are automatically replaced and you don't have to go back and do that manually. If you have the clear globals(1) at the start of your script, each time you run the script, your recall variables will be cleared from memory, effectively making the recall function useless.

 

DS

jthi
Super User

Re: Tips and Tricks from JMP Scripters Club Q2 (2022)

If I see it, I tend to remove it / comment it out due to the reasons given by @DonMcCormack 

-Jarmo