Subscribe Bookmark RSS Feed

Parsing multiple commands into expr using substitute into

ptonge

Occasional Contributor

Joined:

Jul 10, 2017

I am trying to add an arbitrary number of reference lines into a graph based on the arguments given in a function.  And I can construct the string I need without too much trouble.  The issue I'm having is that I can't seem to get it into past parse() due to the commas in the string.  All I really want to do is peel off the outer quotes from the string and substitute it into and remove the \!'s if necessary.  Perhaps there's a much better way to do this but here's the guts of my attempt:

 

Expression that needs adjustment:

FixyAxis = expr( gbt <<
        SendToReport(
            Dispatch(
                {},
                "Graph Builder",
                OutlineBox,
                {myTitle}
            ),
            Dispatch(
                {},
                name,
                ScaleBox,
                {
                  Min( minY ), Max( maxY ), Inc( ticksY ),
                  IntRefLines,
                  Show Major Grid( 1 ), , Show Minor Grid( 1 )
                }
            )
        )
    ) ;

String variable I'm trying to substitute with (cr added for readability):

myRefLines = "Add Ref Line(60, Solid, \!"Medium Dark Red\!",\!"USL_lt_2.5\!", 2 ),
              Add Ref Line(30, Solid, \!"Medium Dark Red\!",\!"USL_gt_2.5_lt_4.5\!", 2 ),"

 

But parse() hits the first comma and quits:

substitute into(fixYaxis, Expr(IntRefLines), parse(myRefLines)) ;

 

Unexpected ",". Perhaps there is a missing ";" or ",".
Line 1 Column 60: ...rk Red","USL_lt_2.5", 2 )►,Add Ref Line(30, Solid, ...

 

In the end what I want fixYaxis to look like is:

FixyAxis = expr( gbt <<
        SendToReport(
            Dispatch(
                {},
                "Graph Builder",
                OutlineBox,
                {myTitle}
            ),
            Dispatch(
                {},
                //"Mean",
                name,
                ScaleBox,
                {
                  Min( minY ), Max( maxY ), Inc( ticksY ),
                  Add Ref Line(60, Solid, "Medium Dark Red","USL_lt_2.5", 2 ),
                  Add Ref Line(30, Solid, "Medium Dark Red","USL_gt_2.5_lt_4.5", 2 ),
                  Show Major Grid( 1 ), , Show Minor Grid( 1 )
                }
            )
        )
    ) ;
 

Thanks for any help!

 

Phil

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ian_jmp

Staff

Joined:

Jun 23, 2011

Solution

FWIW, here's an alternative you could probably build on:

NamesDefaultToHere(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
					Size( 528, 452 ),
					Show Control Panel( 0 ),
					Variables( X( :weight ), Y( :height ) ),
					Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ),
				);

// Make some reference lines
n = 3;
refLineList = {};
for(i=1, i<=n, i++,
	InsertInto(refLineList, EvalExpr(Add Ref Line( Expr(RandomInteger(55,65)), "Solid", "Medium Dark Green")));
);

// Add the reference lines
for(i=1, i<=n, i++,
	addLine = Expr(Report(gb)[axisBox(2)] << lineTBD);
	SubstituteInto(addLine, Expr(lineTBD), refLineList[i]);
	addLine;
);
9 REPLIES
txnelson

Super User

Joined:

Jun 22, 2012

When "Substitute" fails me, I fall back on generating the code I need 

I am not sure this is exactly what you want, but it should give you a potential of a way to solve the issue

Names Default To Here( 1 );
myExpr = Expr(
	TheExpr =
	"FixyAxis = Expr(
	gbt << SendToReport(
		Dispatch( {}, \!"Graph Builder\!", OutlineBox, {myTitle} ),
		Dispatch(
			{},
			name,
			ScaleBox,
			{Min( minY ), Max( maxY ), Inc( ticksY ),"
	 || myRefLines || ", Show Major Grid( 1 ), ,
			Show Minor Grid( 1 )}
		)
	)
);"
);

myRefLines =
"Add Ref Line(60, Solid, \!"Medium Dark Red\!",\!"USL_lt_2.5\!", 2 ),
              Add Ref Line(30, Solid, \!"Medium Dark Red\!",\!"USL_gt_2.5_lt_4.5\!", 2 )";
myexpr;
Parse( theexpr );
Jim
ian_jmp

Staff

Joined:

Jun 23, 2011

Solution

FWIW, here's an alternative you could probably build on:

NamesDefaultToHere(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
					Size( 528, 452 ),
					Show Control Panel( 0 ),
					Variables( X( :weight ), Y( :height ) ),
					Elements( Points( X, Y, Legend( 8 ) ), Smoother( X, Y, Legend( 9 ) ) ),
				);

// Make some reference lines
n = 3;
refLineList = {};
for(i=1, i<=n, i++,
	InsertInto(refLineList, EvalExpr(Add Ref Line( Expr(RandomInteger(55,65)), "Solid", "Medium Dark Green")));
);

// Add the reference lines
for(i=1, i<=n, i++,
	addLine = Expr(Report(gb)[axisBox(2)] << lineTBD);
	SubstituteInto(addLine, Expr(lineTBD), refLineList[i]);
	addLine;
);
pmroz

Super User

Joined:

Jun 23, 2011

Here's another way that builds strings dynamically and then executes the final result using eval(parse()).  Uses evalinsert to replace variables surrounded by carets (i.e. ^varname^).  Also uses the string escape characters \[ and ]\ to avoid having to escape double quotes inside a string.

 

myRefLines = "\[Add Ref Line(60, Solid, "Medium Dark Red","USL_lt_2.5", 2 ),
              Add Ref Line(30, Solid, "Medium Dark Red","USL_gt_2.5_lt_4.5", 2 ),]\";

FixyAxis = evalinsert("\[
	gbt << SendToReport(
            Dispatch( {}, "Graph Builder", OutlineBox, {myTitle}
            ),
            Dispatch( {}, name, ScaleBox,
                {
                  Min( minY ), Max( maxY ), Inc( ticksY ),
                  ^myRefLines^,
                  Show Major Grid( 1 ), , Show Minor Grid( 1 )
                }
            )
        )
    )]\");

eval(parse(fixyaxis));
ptonge

Occasional Contributor

Joined:

Jul 10, 2017

Thanks!

 

I tried the carat substitution idea too.  I had seen this method referred to but didn't understand it before.  Your code was very helpful with a straight forward implementation into my original code (copy, cut, paste and work!).  The "\[" is something I didn't know about, and I have another problem I can use this evalinsert solution on.

 

My apologies to all in the manner that my replies are getting added to the thread.  My intent was to address each code poster's reply after theirs but I keep seeing them somewhat randomly added. The reply with the graph picture in it was intended as comment to the 2nd code example.  This post is intended for the 3rd code example, and the others all pertain to the 1st code example.

ptonge

Occasional Contributor

Joined:

Jul 10, 2017

Thanks!

I had tried an idea like this but really didn't understand how to put together the message string to the graph.  I modified your script to use parse(refLinesList[i]) because my list item was more complicated than your example.  And since I intend to change the script to accept a limit list rather to build the from this solution meets my current need best.

 

This was also a segment of a larger function to build a generic graphing function (still a work in progress).  Completed graph looks like this:

 

graph.GIF

 

 

 

 

ptonge

Occasional Contributor

Joined:

Jul 10, 2017

Hi,

Thanks for responding. I'm trying this now and it appears to work as I wanted it to, although I had to modify other code to get it to work - JMP's syntactically requirements seemed to have changed with more "add ref lines" - that I hadn't noticed until I manually built another graph and dumped the script.

When I get done I'll update the discussion.

Thanks for your help!

Phil




markbailey

Staff

Joined:

Jun 23, 2011

Would it be simpler to launch the platform and follow with sending a series of messags to add the lines instead of trying to build the complicated launch message?

Learn it once, use it forever!
ptonge

Occasional Contributor

Joined:

Jul 10, 2017

txnelson,
I implemented your method but needed to make a couple of modifications. As I understand it it's basically a string construction that then gets unwrapped/unpacked. But in order for me to get it to work, I removed "FixyAxis =" from "myExpr = Expr(TheExpr ="FixyAxis = Expr(" and then assigned it to the output of the parse command. Then in order to get that to work, I had to eval(FixyAxis). So this "myexpr;Parse( theexpr );" became "myexpr; FixyAxis = Parse(theexpr) ;Eval(fixYaxis) ;". But eval(parse(theexpr)) did not.

Thanks!

ptonge

Occasional Contributor

Joined:

Jul 10, 2017

Thanks!

 

I implemented this idea first because it made the most sense to me initially.  I picked the second posters code over yours because it suited my future needs better.  However, I learned something from your method that I'm going to put to use on another problem I've got.