Hi,
I often face the problem that a code doesn't work because 1 out of 10 semicolons is a comma or one comma which belongs to the if block is actually missing.
Is there an easy trick to make the blocks in an if-else clause more visible?
Hm, I just thought:
If there is this wonderful GraphBuilder in Jmp which helps you to generate every kind of graph within 5 seconds,
it should also be possible to analyze complicated If & Match structures in < 5 seconds to find any error in the structure.
Automatic indentation via "reformat script" is great - it shows the complete hierarchy of the code structure - at a single glance.
But that's also the disadvantage: The complete hierarchy
This is why a human eye needs some time to analyze the information - and even needs some support from the brain to do so.There are ways to encode information in a format where the "eye" needs less support from the brain - as one can learn from @XanGregg :Plenary: All Graphs Are Wrong, but Some Are Useful - Xan Gregg
Thinking along this line ...
A Click on a bracket to highlight the If statement is very useful
- but it would be great if the shading of the included text was not uniform (like in the picture on the left) - but in a meaningful way (like in the picture on the right).
Jmp has all the information that is needed (it uses it to adjust the indentation) - why not use it for the shading?
It's clear that there is NO additional information in the picture on the right which cannot be deduced from the indentation on the left.
And the indentation can even show more: the complete hierarchy of the complex code structure at a single glance. Yes.
But the right image looks quite convinding, right?edit: link to the wish
Right click on the JSL window, and select "Reformat Script".
That will align the blocks at standard indentations.
You can also click on any function or matrix boundary bracket {} [] and it will select the matching bracket
I liked what this man had to say here.
JMP doesn’t care about this formatting but you will quickly get into a mess if you don’t have the discipline to write the code in a way that reflects the hierarchy of display boxes.
This statement doesn't exclusively apply to display boxes, but JSL in general. I am still learning myself, but it is a good investment of time to visually structure code into logical parts, even if it sometimes turns into a forensic exercise (which, coincindentally, is where most learning tends to happen).
I like your thinking on this, and other thoughts you are having on improvements to JMP and JSL.....I suggest you add these to the JMP Wish List,. That will get your input to the individuals who can actually make the changes.
thank you for your support here is the wish:optimized syntax highlighting in JSL editor
My solution to this is to put important commas at the level of the enclosing fence. Here is an example -- notice that the commas separating the IF blocks are at the level of the IF statement, and the same for TRY
Names Default to Here( 1 ); dt = Current Data Table(); Try( If( Contains( dt << Get Column Names, As Name( "height" ) ), mean = Col Mean( dt:height ); max = Col Max( dt:height ); min = Col Min( dt:height ); std dev = Col Std Dev( dt:height ); Write( "\!NSome stats on :HEIGHT:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ) , Contains( dt << Get Column Names, As Name( "weight" ) ), mean = Col Mean( dt:weight ); max = Col Max( dt:weight ); min = Col Min( dt:weight ); std dev = Col Std Dev( dt:weight ); Write( "\!NSome stats on :WEIGHT:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ) , Contains( dt << Get Column Names, As Name( "age" ) ), mean = Col Mean( dt:age ); max = Col Max( dt:age ); min = Col Min( dt:age ); std dev = Col Std Dev( dt:age ); Write( "\!NSome stats on :AGE:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ) , Print( "Cannot find columns 'height', 'weight', or 'age'" ) ) , Print( "mistakes were made" ) )
I use a bit similar style as @ErraticAttack but I separate conditions to same line as , and might even comment else and catch if the blocks are long
Names Default To Here(1); dt = Current Data Table(); Try( If(Is Empty(dt), print("no table found"); , N Rows(dt) == 0, print("table has no data"); , N Rows(dt) <= 10, print("not enough data"); , // else print("ok") ); , // catch show(exception_msg); );
I try to avoid using jsl re-formatting after my scripts gets long /complicated enough as I usually have to clean-up after using it. Even if reformat was as flexible as I would need it to be, I think I wouldn't bother configuring it properly...
@jthi wrote:configuring [re-formatting] properly...
configuring [re-formatting] properly...
is there a way to configure re-formatting?
Not to my knowledge. Currently the few changes you can are found from preferences Script Editor page.
Also writing customizable auto-formatter isn't the most simple task (at least I would think so) and I'm not even sure if it is a good idea. I think opinionated auto-formatters are more common and most likely better than fully customizable ones. But JSL has no style guides to follow, so there is no common opinion to base the auto-formatter on (JSL is very small language).
Here is a video regarding black auto-formatter for Python Łukasz Langa - Life Is Better Painted Black, or: How to Stop Worrying and Embrace Auto-Formatting (youtube.com)
I agree with @jthi , I avoid using re-format. It's my job as a programmer to have a clear style guide and enforce it as I write the code.
Annotations such as
, // else
can help give a visual guide when there are a large number of lines of code.
I too, think aligning the comma with the main if statement is the preferable style.
Hi @hogi ,
This is not an exact answer to your specific question. But i think this jsl extension for visual studio provides a better scripting experience in general.
https://marketplace.visualstudio.com/items?itemName=VinceFaller.jmp-scripting
Oh no - once again, after some copy & paste and re-arrangement of my code it behaves as if there was a wrong comma somewhere in an if statement
- and I wished there was a highlight function implemented already in Jmp17
Hm, not yet ...
So I went back to the suggestions in the posts and searched for some help.
While reading the suggestions the first time I thought: sounds good, many of them will help me when I have the next problem.
Now, when searching for the erroneously placed comma, actually it was @txnelson's suggestion which helped me to find it:Click on reformat script and check where the indentation doesn't fit to the expected one.
Quite simple - and as expected.
On the other hand, while searching again and again for the wrong comma, the other suggestions read a bit like
"there is a comma where it should not be? you have to find it and correct it".
To combine both approaches ,to write your code
1) in a readable way2) such that reformat script doesn't change the formatting.
One could put an empty line in front of the commas in the if statements. This will prevent reformat script from moving the commas to the end of the previous line. Unfortunately, it will also shift the code after the commas to the next line, just leaving the commas there - which makes the code a bit "wide-meshed" and difficult to read. Hm.
Names Default To Here( 1 ); dt = Current Data Table(); If( Is Empty( dt ), Print( "no table found" ); , N Rows( dt ) == 0, Print( "table has no data" ); , // else Print( "ok" ) );
Try on your own: Wherer is the erroneously placed commacode as it was provided by ErraticAttack, but with a comma where there should be a semicolon:
Names Default to Here( 1 ); dt = Current Data Table(); Try( If( Contains( dt << Get Column Names, As Name( "height" ) ), mean = Col Mean( dt:height ); max = Col Max( dt:height ); min = Col Min( dt:height ); std dev = Col Std Dev( dt:height ), Write( "\!NSome stats on :HEIGHT:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ) , Contains( dt << Get Column Names, As Name( "weight" ) ), mean = Col Mean( dt:weight ); max = Col Max( dt:weight ); min = Col Min( dt:weight ); std dev = Col Std Dev( dt:weight ); Write( "\!NSome stats on :WEIGHT:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ) , Contains( dt << Get Column Names, As Name( "age" ) ), mean = Col Mean( dt:age ); max = Col Max( dt:age ); min = Col Min( dt:age ); std dev = Col Std Dev( dt:age ); Write( "\!NSome stats on :AGE:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ) , Print( "Cannot find columns 'height', 'weight', or 'age'" ) ) , Print( "mistakes were made" ) )
Names Default To Here( 1 ); dt = Current Data Table(); Try( If( Contains( dt << Get Column Names, As Name( "height" ) ), mean = Col Mean( dt:height ); max = Col Max( dt:height ); min = Col Min( dt:height ); std dev = Col Std Dev( dt:height );, // <- wrong comma Write( //<- "wrong" indentation gives the hint "\!NSome stats on :HEIGHT:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev ), Contains( dt << Get Column Names, As Name( "weight" ) ), mean = Col Mean( dt:weight ); max = Col Max( dt:weight ); min = Col Min( dt:weight ); std dev = Col Std Dev( dt:weight ); Write( "\!NSome stats on :WEIGHT:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev );, Contains( dt << Get Column Names, As Name( "age" ) ), mean = Col Mean( dt:age ); max = Col Max( dt:age ); min = Col Min( dt:age ); std dev = Col Std Dev( dt:age ); Write( "\!NSome stats on :AGE:", "\!NMin: ", min, "\!NMax: ", max, "\!NMean: ", mean, "\!NStd Dev: ", std dev );, Print( "Cannot find columns 'height', 'weight', or 'age'" ) ) , Print( "mistakes were made" ) );
Pasting the If() statement into the Formula editor helps spot it pretty quickly.
cool, very convenient