Subscribe Bookmark RSS Feed

How to script platforms requiring modal dialog box input

thomasz

Community Trekker

Joined:

Mar 11, 2016

How is it possible to automate the output from platforms requiring input from a modal dialog box?

Below are two examples. The first works when specifying all options in the dialog box.

I would expect the second to work the same way if it is possible to specify all options. My guess is that some options are not using the right names or syntax (Jmp doesn't provide any debugging information unfortunately). See examples below (works in Jmp 14 EA 7)...

 

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

//This Works when all options in Save Document Matrix are specified:
te=dt<<text explorer(Text Columns(:name));
te<<Save Document Term Matrix(Maximum number of terms(10),minimum term frequency(1),Weighting("TF IDF"));
te<<close window;

// This fails in the last statement. The group similar values dialog is opened, but it does not perform it's task
dt<<go to(:name);
rwin=dt<<recode();
wait(0);
rwin=current window();
rep=rwin["name"]<<get scriptable object;
rep<<Group similar values(Ignore Case(0),Ignore Non-Printable Characters(1), Ignore Whitespace(1),Ignore Punctuation(1),Allow Character Edits(1),Difference Ratio({1,0.4}),Max Character Difference({1,3}));

 

2 ACCEPTED SOLUTIONS

Accepted Solutions
ih

Community Trekker

Joined:

Sep 30, 2016

Solution

Unfortunatelly there is no way to make modal dialog boxes go away without clicking on them, unless the box closes itself. In this case you could script the recoding yourself; the hardest part would be finding or writing a string distance function.

 

The script below might get you started but do not use this distance function as is: it is very inefficient!  A distance of two on words with 5 characters is a lot but you can see that 'JANE', 'JAMES', and 'JOE' all become 'JANE'. 

Names default to here( 1 );

//  FUNCTION TO CALCULATE DISTANCE BETWEEN STRINGS

//Rewrite of example C code from wikipedia:
//https://en.wikipedia.org/wiki/Levenshtein_distance
//very inefficient

// len_s and len_t are the number of characters in string s and t respectively
LevenshteinDistance_ = function({s, len_s, t, len_t},
	// show(s || char(len_s) || t || char(len_t));
	// base case: empty strings
	if ( substr( s, 1, len_s ) == substr( t, 1, len_t ), 0, //strings match, distance is zero
		len_s == 0, len_t, //s empty, distance is the length of t
		len_t == 0, len_s, //t empty, distance is the length of s
		
		// return minimum of delete char from s, delete char from t, and delete char from both
		minimum(
			LevenshteinDistance_(s, len_s - 1, t, len_t    ) + 1,
			LevenshteinDistance_(s, len_s    , t, len_t - 1) + 1,
			LevenshteinDistance_(s, len_s - 1, t, len_t - 1) + 
				if (substr(s, len_s, 1) == substr(t, len_t, 1), 0, 1) // test if last characters of the strings match
			
		);
  	);
);

//Wrapper that finds strings lengths for you
LevenshteinDistance = function({s, t}, LevenshteinDistance_(s, length(s), t, length(t)));

//  EXAMPLE

//data table
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt << New Column( "name recoded", Character, "Nominal" );

//replace names with the first name in the table having a Levenshtein
//distance of two or less when compared to that value
for( i = 1, i <= min(15, N Rows( dt )), i++, //for each row in the table
	
	//if row one always use that value
	Column( dt, "name recoded")[i] = if( i == 0, Column( dt, "name")[i], 
newvalue = Column(dt, "name")[i]; //assume you will use this rows' value
match = 0; //flag indicating that a match is found for( j = 1, j < i & match == 0, j++, //look at all previous rows to find a match //if a match use the previous row value and stop looking for more matches if( LevenshteinDistance( Column(dt, "name")[i], Column(dt, "name")[j] ) <= 2, newvalue = Column(dt, "name")[j]; match = 1; ) ); newvalue; ); );

 

 

 

 

Wendy_Murphrey

Joined:

Jun 23, 2011

Solution

In general, the Recode dialog is not scriptable. I have passed along your feedback to the JMP Development team for consideration in a future release of JMP.
Thank you for using JMP!

 

Wendy
3 REPLIES
ih

Community Trekker

Joined:

Sep 30, 2016

Solution

Unfortunatelly there is no way to make modal dialog boxes go away without clicking on them, unless the box closes itself. In this case you could script the recoding yourself; the hardest part would be finding or writing a string distance function.

 

The script below might get you started but do not use this distance function as is: it is very inefficient!  A distance of two on words with 5 characters is a lot but you can see that 'JANE', 'JAMES', and 'JOE' all become 'JANE'. 

Names default to here( 1 );

//  FUNCTION TO CALCULATE DISTANCE BETWEEN STRINGS

//Rewrite of example C code from wikipedia:
//https://en.wikipedia.org/wiki/Levenshtein_distance
//very inefficient

// len_s and len_t are the number of characters in string s and t respectively
LevenshteinDistance_ = function({s, len_s, t, len_t},
	// show(s || char(len_s) || t || char(len_t));
	// base case: empty strings
	if ( substr( s, 1, len_s ) == substr( t, 1, len_t ), 0, //strings match, distance is zero
		len_s == 0, len_t, //s empty, distance is the length of t
		len_t == 0, len_s, //t empty, distance is the length of s
		
		// return minimum of delete char from s, delete char from t, and delete char from both
		minimum(
			LevenshteinDistance_(s, len_s - 1, t, len_t    ) + 1,
			LevenshteinDistance_(s, len_s    , t, len_t - 1) + 1,
			LevenshteinDistance_(s, len_s - 1, t, len_t - 1) + 
				if (substr(s, len_s, 1) == substr(t, len_t, 1), 0, 1) // test if last characters of the strings match
			
		);
  	);
);

//Wrapper that finds strings lengths for you
LevenshteinDistance = function({s, t}, LevenshteinDistance_(s, length(s), t, length(t)));

//  EXAMPLE

//data table
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt << New Column( "name recoded", Character, "Nominal" );

//replace names with the first name in the table having a Levenshtein
//distance of two or less when compared to that value
for( i = 1, i <= min(15, N Rows( dt )), i++, //for each row in the table
	
	//if row one always use that value
	Column( dt, "name recoded")[i] = if( i == 0, Column( dt, "name")[i], 
newvalue = Column(dt, "name")[i]; //assume you will use this rows' value
match = 0; //flag indicating that a match is found for( j = 1, j < i & match == 0, j++, //look at all previous rows to find a match //if a match use the previous row value and stop looking for more matches if( LevenshteinDistance( Column(dt, "name")[i], Column(dt, "name")[j] ) <= 2, newvalue = Column(dt, "name")[j]; match = 1; ) ); newvalue; ); );

 

 

 

 

thomasz

Community Trekker

Joined:

Mar 11, 2016

Thank you for your reply - maybe the Levenshtein distance will come in handy one day.

 

I am looking for a way to automate the last bit of the platforms by scripting in general. I am aware of there is no documentation for this - or at least I couldn't find it - but as you see in my first example, it is possible to avoid the modal dialog box when all values are supplied at call time. I am not sure it works for all dialog boxes, but since it worked for one, I believe there is a good chance this works in general. Otherwise, I plea to the developers, to make this work, so we can avoid repetitive tasks and unfold the full potential of the platforms and Jmp scripting!

Wendy_Murphrey

Joined:

Jun 23, 2011

Solution

In general, the Recode dialog is not scriptable. I have passed along your feedback to the JMP Development team for consideration in a future release of JMP.
Thank you for using JMP!

 

Wendy