2 Replies Latest reply on Mar 25, 2012 9:28 PM by sporobolus

# Ugo Di Luca- EasySort calculation - HELP DECIPHERING PLEASE

Hey Everyone;

Genius moment again by Ugo Di Luca many years ago. I am confused deciphering what the heck is going on here.

I have attached his sample file i found over @ http://www.filemakerhacks.com/?p=1389.

I have started to look @ his calculation and am confused about a few things here. Also in his file, he has a script that looks like this:

@parameters being passed are confusing to me but here they are:

1: 03Name

2. 14AnyNum

3. 25AnyDate

//Script name: Sort

Set Field: Middle(Get ( ScriptParameter ); 1+Choose (Sort::gScriptParameter= Left(Get ( ScriptParameter );1);0;1);1) //DONT UNDERSTAND THIS EITHER

Sort Records

Go to Record/Request :[First]

Let ( [

VL = "Header"; // Name of my Value List is Header

L = ValueListItems ( Get ( FileName ) ;VL); //grab the Value ListItems from "Header"

X = PatternCount( L;"¶") +1; // in Result above, find WHY ADD 1 +1 starts @ 1 so we need ot add 1 to account for that?

N = 1 + Mod (X +Sort::gScriptParameter; X); // if the result of 1 + X + Scriptparameter is divisible by self put result in N

E = MiddleWords( L; N; 1); // look in L and our starting wors is result above, then get the numberofWords( Result of X) = in my case 10

T = MiddleWords(FieldType (Get ( FileName ) ;E);2;1); // Get next word in list i am thinking here

P = Sort::gScriptParameter; // our scriptparameter ( global field)

G = GetField(E) //Get the field type in E

];

L & ¶ &

Choose( P > 2; // Test the condition if P > 2, the perform results below

Case( // If

T="Number"; // This isNumber

Right( "00000000"& G; 8); //Why do we need to Concat G here ?

G);

Case(

T= "Number";

1 / (G + 2); // why do this condition?

T="Date";Date(12;12;3000) - G; // Why minus G

T="Hour"; Time( 23; 59; 59) - G;

T="Text";

Substitute( Upper(G); // ok Genius moment. Make list opposite if asc, des,etc - JKEWL. Seems to me that this Substitute function every master developer LOVES!! - I am thinking i need to learn to master this one..

["A"; "z"];

["B"; "y"];

["C"; "x"];

["D"; "w"];

["E"; "v"];

["F"; "u"];

["G"; "t"];

["H"; "s"];

["I"; "r"];

["J"; "q"];

["K"; "p"];

["L"; "o"];

["M"; "n"];

["N"; "m"];

["O"; "l"];

["P"; "k"];

["Q"; "j"];

["R"; "i"];

["S"; "h"];

["T"; "g"];

["U"; "f"];

["V"; "e"];

["W"; "d"];

["X"; "c"];

["Y"; "b"];

["Z"; "a"] ) )))

• ###### 1. Re: Ugo Di Luca- EasySort calculation - HELP DECIPHERING PLEASE

Steve Harley:: I hope i did a good job formatting this time.

LaRetta: Please tell me i did good on this one? I hope so..

• ###### 2. Re: Ugo Di Luca- EasySort calculation - HELP DECIPHERING PLEASE

on 2012-03-25 1:50 ian.moree wrote

Genius moment again by Ugo Di Luca many years ago. I am confused deciphering what the heck is going on here.

I have attached his sample file i found over @  http://www.filemakerhacks.com/?p=1389 http://www.filemakerhacks.com/?p=1389.

this one is interesting, but has lots of bugs; this is also the last of these

exercises i'm doing (except for pay)

@parameters being passed are confusing to me but here they are:

>

>> 1: 03Name

>> 2. 14AnyNum

>> 3. 25AnyDate

>> //Script name: Sort

>> Set Field: Middle(Get ( ScriptParameter ); 1+Choose (Sort::gScriptParameter= Left(Get ( ScriptParameter );1);0;1);1) //DONT UNDERSTAND THIS EITHER

hints to understand these parameters:

• note the numerals in the script parameters are 0 1 2 3 4 5

• watch the value of gScriptParameter as you click the sort buttons

• pop quiz: if there were four sorting columns, what would the possible

parameter values be?

>> Sort Records

>> Go to Record/Request :[First]

so above was the script assigned to each sort button, and below is the

definition of a specific field, the calc field used for the dynamic sort; when

the pieces connect so they don't have to dissect the source materials to catch

up with you …

>> L = ValueListItems ( Get ( FileName ) ;VL);                //grab the Value ListItems from "Header"

notice that the Header value list contains the names of the fields on which the

user can sort …

>> X = PatternCount( L;"¶") +1;                          // in Result above, find  WHY ADD 1 +1 starts @ 1 so we need ot add 1 to account for that?

please try it — decompose the expression in the Data Viewer like this:

PatternCount (ValueListItems (Get (FileName); "Header"); "¶") + 1

… when you want the number of items in a defined value list, does this

patternCount() expression give you the right answer?

>> N = 1 + Mod (X +Sort::gScriptParameter; X); // if the result of 1 + X + Scriptparameter  is divisible by self put result in N

if you make this a global script variable (\$\$N) and watch the value as you

click the sort buttons, what happens?

>> E = MiddleWords( L; N; 1);                          // look in L and our starting wors is result above, then get the numberofWords( Result of X) = in my case 10

if you figured out what N is above, you'll see how this makes E the name of the

sort field

>> T = MiddleWords(FieldType (Get ( FileName ) ;E);2;1); // Get next word in list i am thinking here

please try this expression in the Data Wiewer and think again

>> P = Sort::gScriptParameter;                           // our scriptparameter ( global field)

the global field's name is a little misleading; it holds only part of the

script parameter, a number in the set (0 1 2 3 4 5)

>> G = GetField(E)                                //Get the field type in E

get the value of the field named in E in the current record (remember, this is

a calc field, and will get a different value for each record)

note that all the Let() variables above are recalculated for each record, but

that this effort is redundant because they will have the same value for each

record; can you think of a way to calculate these values once and make them

available for the calculation as it executes on each record?

here is the big Choose() expression you quoted, with interspersed comments; the

multiple tabs and long line-end comments in your post made the email version

into spaghetti; here's a suggestion of how to format something like this for

ease of comprehension (there is no one way to do this); i've used a two-space

indent and nested everything according to the hierarchy of evaluation; i've

also placed your comments on the line above what they refer to (helps

especially when comments are long); my comments are indicated with ^^^

```// Test the condition if P > 2, the perform results below
/*
^^^ Choose() selects either the 1st or 2nd Case() expression,
because P > 2 returns either 0 or 1;
there's a bug here: the expressions above are flexible for different
numbers of items (X) in the value list (VL), but P > 2 works
only when X = 3
*/
Choose( P > 2;
// If
/*
^^^ yes, using Choose with a logical expression (P > 2) is the same as
using If(); the following Case() runs if P is 0 1 or 2,  which, if you've
reasoned through the above, means that the sort is in ascending order
*/
Case(
// This isNumber
// ^^^ the type of the field on which to sort is Number
T="Number";
// Why do we need to Concat G here ?
/*
^^^ because the SortKey calc field result type is Text, and
numbers as text need to be padded with zeroes to sort correctly
*/
Right( "00000000"& G; 8);
/*
^^^ there's a bug here: the author doesn't test for Date,
assuming that a date will sort OK as text, but this only works if
an ISO date format is used
*/
G);
// ^^^ below evaluates if P is 3 4 or 5 — sort in descending order
Case(
T= "Number";
// why do this condition?
/*
^^^ to sort descending, each field type needs a different technique;
for numbers, the theory is that the reciprocal of the number will
always be of the form 0.nnnnnn, and (as text) will makes the numbers
sort in reverse;
but there's a bug here: the numbers must be positive …
any negative will make the sort wonky, and -2 will cause an error
*/
1 / (G + 2);
T="Date";
// Why minus G?
/*
^^^ the idea is that a date very far in the future minus
the date in question will invert the sort order;
(this formula introduces a Y3K bug)
*/
Date(12;12;3000) - G;
/*
^^^ bug: T can ever be "Hour"; i think this was meant to be:
T="Time";
*/
T="Hour";
Time( 23; 59; 59) - G;
T="Text";
/*
ok Genius moment. Make list opposite if asc, des,etc - JKEWL.
Seems to me that this Substitute function every master developer LOVES!!
- I am thinking i need to learn to master this one..
*/
/*
^^^ bug: spaces, numerals, punctuation and non-low-ASCII characters
will make the descending sort incorrect
*/
Substitute( Upper(G);
["A"; "z"];
["B"; "y"];
["C"; "x"];
["D"; "w"];
["E"; "v"];
["F"; "u"];
["G"; "t"];
["H"; "s"];
["I"; "r"];
["J"; "q"];
["K"; "p"];
["L"; "o"];
["M"; "n"];
["N"; "m"];
["O"; "l"];
["P"; "k"];
["Q"; "j"];
["R"; "i"];
["S"; "h"];
["T"; "g"];
["U"; "f"];
["V"; "e"];
["W"; "d"];
["X"; "c"];
["Y"; "b"];
["Z"; "a"]
)
)
)
```