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

    Ugo Di Luca- EasySort calculation - HELP DECIPHERING PLEASE

    ian.moree

      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
          ian.moree

          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
            sporobolus

            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

            you post this kind of stuff, please help out your readers by showing them how

            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"]
                   )
               )
            )