cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
Hegedus1
Level III

Run Script - OK versus Add-In Script Not OK

Hi,

 

Thanks to the fellow board users, I have a script working that includes column switchers and local data filters. The script works as intended and the next step is I wanted to package as an add-in for the client base.  I think I details of the add-in working and I can launch the script and it goes through the data import, clean up and summarization and makes the interface.  HOWEVER, the interface is now giving me errors when I try to execute the column switcher that worked fine if I launch the script by itself. If I click on a new item in the column switcher I get the following error I have attached the code than creates this view.  In my code I attach this to a summary data table and then execute it from within the script. If I run via add-in (where I just attached the script) it gives error. If I then close that window and click the button on the data table build the same display it works as intended without errors. So I am a bit confused as what I should change and insights?

Andy

Hegedus1_0-1649196193060.png

cell_sum << new script(
	"Main Interface",
	cell_sum = Current Data Table();
	test = Fit Group(
		Oneway(
			Y( :Max Discharge Capacity ),
			X( :Cathode Recipe.x ),
			Quantiles( 1 ),
			Means( 1 ),
			Box Plots( 1 ),
			Mean Diamonds( 0 ),
			X Axis Proportional( 0 ),
			Points Jittered( 1 ),
			Grand Mean( 0 ), 
		
		), 
	
		Oneway(
			Y( :"Cycle Number (>0.8)"n ),
			X( :Cathode Recipe.x ),
			Quantiles( 1 ),
			Means( 1 ),
			Box Plots( 1 ),
			Mean Diamonds( 0 ),
			X Axis Proportional( 0 ),
			Points Jittered( 1 ),
			Grand Mean( 0 ), 
		
		),
		Oneway(
			Y( :"Discharge Capacity @ 50 Cycles"n ),
			X( :Cathode Recipe.x ),
			Quantiles( 1 ),
			Means( 1 ),
			Box Plots( 1 ),
			Mean Diamonds( 0 ),
			X Axis Proportional( 0 ),
			Points Jittered( 1 ),
			Grand Mean( 0 ), 

		),
		Oneway(
			Y( :"Remain % @ 50 Cycles"n ),
			X( :Cathode Recipe.x ),
			Quantiles( 1 ),
			Means( 1 ),
			Box Plots( 1 ),
			Mean Diamonds( 0 ),
			X Axis Proportional( 0 ),
			Points Jittered( 1 ),
			Grand Mean( 0 ), 
		
		), 

		<<{Arrange in Rows( 4 )}
	);
	colpick = test << Column Switcher(
		:Cathode Recipe.x,
		cell_sum << get column names( Ordinal, Nominal )
	

	);
	(test << top parent)[listboxbox( 1 )] << set script(
		Try( test << remove local data filter );
		mycurrent = ((test << top parent)[listboxbox( 1 )] << get selected)[1];
		test << Local Data Filter(
			Add Filter( columns( Column( mycurrent ) ), Display( Column( mycurrent ), N Items( 15 ), Find( Set Text( "" ) ) ) )
		);
	);
		
	test << Local Data Filter(
		Add Filter( columns( colpick << get current ), Display( colpick << get current, N Items( 15 ), Find( Set Text( "" ) ) ) )
	);
);
cell_sum << run script( "Main Interface" );

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ErraticAttack
Level VI

Re: Run Script - OK versus Add-In Script Not OK

JSL is unlike many other programming languages in that it doesn't do automatic scope control like, say, Python might.  In this case you're using the line 

(test << top parent)[listboxbox( 1 )] << set script(... to add a script to the list box.  When this script does run (by the user selecting an item), then any variable within that script must be resolved -- this is where the scope comes in.  In Python each function has a local scope and each scope is aware of it's parent scope and the global scope (and scopes are persistent), such that a variable in a function can access variables in the parent scope or global scope.  JSL does not do this -- functions don't create and remember scopes and any scope that is created does not keep a record of the scope that created it.  For JSL, when an unscoped variable is accessed (either by namespace:variable or As Scoped( namespace, variable ) then it will by default go to the Here or global scope and that is it.

 

Scope lookup for unscoped names is something like this:  Look at the local namespace if it exists (if you're in a Local( {}, ... ) function or Function( {}, {Default Local}, ... ) function are the most common), look at the Here namespace (if it exists), look at the global namespace.  Sometimes it looks at column names (such as in a For Each Row() function).

 

In your file you don't use any auto-scoping shortcuts (such as Names Default to Here( 1 )), so each variable is globally scoped.  Thus, when the List Box script runs it can find test because it looks in the global scope.  However, addin scripts by default utilize the Names Default to Here( 1 ) function whether or not it's in the script file.  Under this scoping, the files Here namespace is deleted once the script finishes, and the List Box script cannot find test in any scope that it has access to (namely, it's own Here namespace and the global namespace).  You can turn off the Names Default to Here( 1 ) in the addin version, but I recommend against this and it's better to explicitly control the scope.

 

That said, to disable the Names Default to Here( 1 ) in the addin version, uncheck the following box:

ErraticAttach_0-1649228861770.png

 

Jordan

View solution in original post

2 REPLIES 2
ErraticAttack
Level VI

Re: Run Script - OK versus Add-In Script Not OK

JSL is unlike many other programming languages in that it doesn't do automatic scope control like, say, Python might.  In this case you're using the line 

(test << top parent)[listboxbox( 1 )] << set script(... to add a script to the list box.  When this script does run (by the user selecting an item), then any variable within that script must be resolved -- this is where the scope comes in.  In Python each function has a local scope and each scope is aware of it's parent scope and the global scope (and scopes are persistent), such that a variable in a function can access variables in the parent scope or global scope.  JSL does not do this -- functions don't create and remember scopes and any scope that is created does not keep a record of the scope that created it.  For JSL, when an unscoped variable is accessed (either by namespace:variable or As Scoped( namespace, variable ) then it will by default go to the Here or global scope and that is it.

 

Scope lookup for unscoped names is something like this:  Look at the local namespace if it exists (if you're in a Local( {}, ... ) function or Function( {}, {Default Local}, ... ) function are the most common), look at the Here namespace (if it exists), look at the global namespace.  Sometimes it looks at column names (such as in a For Each Row() function).

 

In your file you don't use any auto-scoping shortcuts (such as Names Default to Here( 1 )), so each variable is globally scoped.  Thus, when the List Box script runs it can find test because it looks in the global scope.  However, addin scripts by default utilize the Names Default to Here( 1 ) function whether or not it's in the script file.  Under this scoping, the files Here namespace is deleted once the script finishes, and the List Box script cannot find test in any scope that it has access to (namely, it's own Here namespace and the global namespace).  You can turn off the Names Default to Here( 1 ) in the addin version, but I recommend against this and it's better to explicitly control the scope.

 

That said, to disable the Names Default to Here( 1 ) in the addin version, uncheck the following box:

ErraticAttach_0-1649228861770.png

 

Jordan
Hegedus1
Level III

Re: Run Script - OK versus Add-In Script Not OK

Hi,

 

Thank you very much for your complete description of what was happening and the explanation of namespaces.

I really didn't fully grasp what "Names Default to Here (1)" really was about.  Learned something new.

Thank you again.

Andy