Post Reply 
Sort Lists API: A collection of sort functions
09-08-2018, 09:10 PM (This post was last modified: 09-27-2018 08:27 PM by StephenG1CMZ.)
Post: #2
RE: Sorts API: A collection of sort functions
Version 0.1 collects together the Sort functions previously contained in my List program (including Sortn from the forum), with minor implementation changes.
http://www.hpmuseum.org/forum/thread-9411.html
Requires List which should be compiled first.
Code:

Code

 LOCAL CRID:="Sorts API V0.1 © 2018 StephenG1CMZ";
 LOCAL MORETEXT:="A collection of sort routines brought to you by StephenG1CMZ,\n with some from the forum.";
 LOCAL MN:="Sorts.";//Name

 //IMPORT({List}); //Required

 LOCAL TYPELST:=TYPE({});
 LOCAL TYPEFLOAT:=TYPE(3.1);
 LOCAL TYPEINT:=TYPE(#3);
 LOCAL TYPESTR:=TYPE(" ");

 //Customise
 EXPORT SortableTypes:={TYPEFLOAT,TYPEINT,TYPESTR};
 LOCAL UNK0:=0;//EMPTY IS UNKNOWN,DEFAULT FALSE
 LOCAL UNK1:=1;//EMPTY IS UNKNOWN,DEFAULT TRUE
 //LOCAL SL:=1;
 //NB To test: sort >1 item
 //End

 //Forward
 IsSortablePortable(LST);
 SortL(LST);
 SortN(LST,NN);
 LOCAL NL:="\n";

 LOCAL ListANS;//OUTPUT LIST(WHEN NOT RETURNED)

 //ERR 
 LOCAL ListErrK:=1;
 LOCAL PyErrK:=3;
 EXPORT ListLastError:=0;
 LOCAL ERRKIND:={"","Error","","Py Error"};

 EXPORT EL:={
  "(/0) DivideBy0",
  "IndexOutofBoundsException",
  "ListIsEmptyError",
  "ListIsFullError",
  "ListSortError",
  "ListStatisticsError",
  "ItemNotFoundError",
  "ValueError"
 };
 //ERRNO IS ARBITRARY:INDEXES ERRLST
 EXPORT DivBy0Error:=1;
 LOCAL IndexOutOfBoundsException:=2;//List J
 EXPORT ListIsEmptyError:=3;
 LOCAL ListIsFullError:=4;//UNUSED YET
 LOCAL SortError:=5;
 EXPORT ListStatisticsError:=6;
 EXPORT ItemNotFoundError:=7;//List Py
 EXPORT ValueError:=8; // Py
 
 EXPORT ABOUT()
 BEGIN
  MSGBOX(CRID);
  MSGBOX(MORETEXT);
 END;

 TBD()
 BEGIN
  MSGBOX(MN+"TBD");
 END;

 EXPORT IsSortable(LST)
 //For now use Portable
 //Later: as SORT
 BEGIN
  RETURN IsSortablePortable(LST);
 END;

 EXPORT IsSortablePortable(LST)
 //0.Is parameter a list
 //1.Is TYPE of contents OF ORDERABLE DATA
 //2.Is SORTL implemented on that type yet
 //NOTE:
 //IsSORTABLE({Real})=1 AND IsSORTABLE({INT})=1 AND IsSORTABLE({string})=1 but
 //do not assume SORT({mixed}) will deliver your expectations
 //NB The current algorithm reports {1,"4"} as sortable
 //But native sort wont
 //The Portable variant assumes strings and numerics are sortable.
 BEGIN
  IF TYPE(LST)==TYPELST THEN
   IF SIZE(LST) THEN
    RETURN ListIsTYPE(LST,SortableTypes);
   END;
   RETURN UNK0;//EMPTY
  END;
  RETURN 0;//NOT LIST:CANNOT BE SORTED
 END;

 EXPORT IsSortedEQ(LST)
 //Tells whether a list is sorted...inefficiently
 //By sorting it and checking equality
 //(Useful for testing)
 BEGIN
  ListANS:=SortL(LST);
  RETURN EQ(ListANS,LST);
 END;
 
 EXPORT IsSorted(LST)
 //Looping until 1st descending will/may be quicker TBD
 BEGIN
  RETURN IsSortedEQ(LST);
 END;

 EXPORT SortByKey(SORTS,KeyNum)
 //Sort lists by list number KeyNum (with some input guards)
 BEGIN
  IF 0<KeyNum≤SIZE(SORTS) THEN
   IF SIZE(SORTS)>1 AND SORTS(1)≠{} AND SORTS(2)≠{} THEN
    RETURN SortN(SORTS,KeyNum);
   END;
  ELSE
   //Potential:not all checked
   //List small, not containing lists, key out of range, key list unsortable
   RAISE(MN+"SortByKey",EL,SortError,KeyNum,ListErrK);
  END;
  RETURN SORTS;
 END;

 EXPORT SortByOccurrences(LST)
 //Returns {LSTV,LSTF} sorted by frequency of occurrence
 //reverse so most popular is 1st and index is approx rank 
 BEGIN
  TBD();
  //ListANS:=ListOCCURRENCES(LST);
  RETURN REVERSE(SortByKey(ListANS,2));
 END;

 EXPORT SortL(LST)
 //This implementation uses native SORT
 BEGIN
  IF TYPE(LST)≠TYPELST THEN 
   RAISE(MN+"SortL",EL,SortError,"",ListErrK);
  END;
  RETURN SORT(LST);
 END;

 EXPORT SortN(list,n)
 // From http://www.hpmuseum.org/forum/thread-6179.html?highlight=sort+two+lists
 //Call via ListSORTBYKEY to guard parameters...or call directly with good inputs 
 BEGIN
  LOCAL li,ma;
  ma:=list2mat(list) ;
  li:=SORT(MAKELIST(mat2list(col(ma,I)),I,1,colDim(ma)),n);
  RETURN MAKELIST(mat2list(col(list2mat(li),I)),I,1,rowDim(ma));
 //For example:
 //SORTN({{3,2,1},{15,20,18}},1);// -> {{1,2,3},{18,20,15}}
 //SORTN({{3,2,1},{15,20,18},{32,35,27}},1);// -> {{1,2,3},{18,20,15},{27,35,32}}
 END;

 EXPORT SortsVERSION()
 BEGIN
  RETURN CRID;
 END;

 
 EXPORT Pyreverse(LST)
 //Python analogue
 BEGIN
  RETURN REVERSE(LST);
 END;

EXPORT Pysort(LST,KeyFunc,RReverse)
 //Python analogue SORT
 //TBD: KeyFunc: Selects sort key from item
 BEGIN
  IF TYPE(KeyFunc)==TYPEFLOAT AND KeyFunc==0 THEN
   //0=None=NO FUNC
  ELSE
   TBD();
   RAISE(MN+"Pysort",EL,ValueError,"",1);//TBD
  END;
  RETURN IFTE(RReverse,SORT(Pyreverse(LST)),SORT(LST));
 END;

EXPORT ListPuzzles()
 //SEE http://www.hpmuseum.org/forum/thread-8209.html?highlight=challenge
 BEGIN
  LOCAL VR;
  LOCAL LST:=MAKELIST("",VR,1,5);//40
  LST(2):="31. ListOCCURRENCESWITHSORT";
  CHOOSE(VR,MN+"Puzzles (See thread)",LST);
 END;

EXPORT SortSeeAlso ()
 BEGIN
  LOCAL KK;
  LOCAL CatFuns:={
   "REVERSE",
   "reverse",
   "revlist",
   "SORT",
   "sort"
   };
  //Just Listed as a reminder:not Selectable
  CHOOSE(KK,MN+" Relevant Cat Functions",CatFuns)

 END;
 
 EXPORT SortsExamples()
 //In real use, use XXX:=Sort...()
 BEGIN
  LOCAL LL:={1,2,3,4,5,6,7,8,9};
  PRINT();
  PRINT(SortsVERSION);
  PRINT("Is");
  PRINT(IsSortable(0));
  PRINT(IsSortable({})); 
  PRINT(IsSortable(LL));
  //PRINT(IsSortable(LL+{3.1}));

  PRINT(IsSorted(LL)); 
  //PRINT(ListIsTYPE({3.4},1-1));
  PRINT("Sort");
  //SortByABS
  //SortByKey
  //SortByOccurrences
  //TBD PRINT(SortByOccurrences({1,2,2,3,3,3}));
  //SortL
  PRINT(SortL(LL));
  //SortN
  PRINT(SortN({{3,2,1},{15,20,18}},1));// -> {{1,2,3},{18,20,15}}
  PRINT(SortN({{3,2,1},{15,20,18},{32,35,27}},1));// -> {{1,2,3},{18,20,15},{27,35,32}}
 
  PRINT("Exampled");
  //RETURN 0; 
 END;

 EXPORT SORTS()
 BEGIN
  ABOUT();
  //SortExamples();
 END;

Version 0.2 is reworked to minimise the need for my "List" program.
I had hoped it would now only be needed for error handling, but in fact there is still a dependency on ListIsTYPE too..
New routines ReverseLOL, SortByCount, SortByABS.
Code:


 LOCAL CRID:="Sorts API V0.2 © 2018 StephenG1CMZ";
 LOCAL MORETEXT:="A collection of sort routines brought to you by StephenG1CMZ,\n with some from the forum.";
 LOCAL MN:="Sorts.";//Name
 //Also includes REVERSE functions

 //IMPORT({List}); //for error handling

 LOCAL TYPELST:=TYPE({});
 LOCAL TYPEFLOAT:=TYPE(3.1);
 LOCAL TYPEINT:=TYPE(#3);
 LOCAL TYPESTR:=TYPE(" ");

 //Customise
 EXPORT SortableTypes:={TYPEFLOAT,TYPEINT,TYPESTR};
 LOCAL UNK0:=0;//EMPTY IS UNKNOWN,DEFAULT FALSE
 LOCAL UNK1:=1;//EMPTY IS UNKNOWN,DEFAULT TRUE
 //LOCAL SL:=1;
 //NB To test: sort >1 item
 //End

 //Forward
 IsSortablePortable(LST);
 SortByKeyTBD(SORTS,Keynum);
 SortL(LST);
 SortN(LST,NN);
 LOCAL NL:="\n";

 LOCAL ListANS;//OUTPUT LIST(WHEN NOT RETURNED)

 //ERR 
 LOCAL ListErrK:=1;
 LOCAL PyErrK:=3;
 EXPORT ListLastError:=0;
 LOCAL ERRKIND:={"","Error","","Py Error"};

 EXPORT EL:={
  "(/0) DivideBy0",
  "IndexOutofBoundsException",
  "ListIsEmptyError",
  "ListIsFullError",
  "ListSortError",
  "ListStatisticsError",
  "ItemNotFoundError",
  "ValueError"
 };
 //ERRNO IS ARBITRARY:INDEXES ERRLST
 EXPORT DivBy0Error:=1;
 LOCAL IndexOutOfBoundsException:=2;//List J
 EXPORT ListIsEmptyError:=3;
 LOCAL ListIsFullError:=4;//UNUSED YET
 LOCAL SortError:=5;
 EXPORT ListStatisticsError:=6;
 EXPORT ItemNotFoundError:=7;//List Py
 EXPORT ValueError:=8; // Py
 
 EXPORT ABOUT()
 BEGIN
  MSGBOX(CRID);
  MSGBOX(MORETEXT);
 END;

 TBD()
 BEGIN
  MSGBOX(MN+"TBD");
 END;

 EXPORT IsSortable(LST)
 //For now use Portable
 //Later: as native SORT
 BEGIN
  RETURN IsSortablePortable(LST);
 END;

 EXPORT IsSortablePortable(LST)
 //0.Is parameter a list
 //1.Is TYPE of contents OF ORDERABLE DATA
 //2.Is SORTL implemented on that type yet
 //NOTE:
 //IsSORTABLE({Real})=1 AND IsSORTABLE({INT})=1 AND IsSORTABLE({string})=1 but
 //do not assume SORT({mixed}) will deliver your expectations
 //NB The current algorithm reports {1,"4"} as sortable
 //But native sort wont
 //The Portable variant assumes strings and numerics are sortable.
 BEGIN
  IF TYPE(LST)==TYPELST THEN
   IF SIZE(LST) THEN
    RETURN ListIsTYPE(LST,SortableTypes);
   END;
   RETURN UNK0;//EMPTY
  END;
  RETURN 0;//NOT LIST:CANNOT BE SORTED
 END;

 EXPORT IsSortedEQ(LST)
 //Tells whether a list is sorted...inefficiently
 //By sorting it and checking equality
 //(Useful for testing)
 BEGIN
  ListANS:=SortL(LST);
  RETURN EQ(ListANS,LST);
 END;
 
 EXPORT IsSorted(LST)
 //Looping until 1st descending will/may be quicker TBD
 BEGIN
  RETURN IsSortedEQ(LST);
 END;

 EXPORT ReverseLOL(LSTS)
 //Reverse a list of lists
 //EG {{1,2},{3,4}} -> {{2,1},{4,3}}
 //NONRECURSIVE:TOP LISTS ONLY
 //ALL LISTS MUST BE REVERSIBLE
 BEGIN
  LOCAL II;
  ListANS:={};
  IF SIZE(LSTS) THEN
   //REVERSE EACH LST
   FOR II FROM 1 TO SIZE(LSTS) DO
    ListANS(II):=REVERSE(LSTS(II));
   END;//FOR  
  END;
  RETURN ListANS;
 END;

 EXPORT SortByABS(LST)
 BEGIN
  LOCAL TMP:={};
  IF SIZE(LST) THEN
   TMP:=SortN({ABS(LST),SIGN(LST)},1);
   RETURN TMP(1)*TMP(2);
  END;
  RETURN {};
 END;

 EXPORT SortByCount(LSTS,Keynum)
 //LSTS is {LSTV,LSTF} as returned by
 //ListOCCURRENCES(LST);
 //but additional fields are allowed
 //Returns {LSTV,LSTF} sorted by frequency of occurrence 
 //EG {{1,2,3},{10,30,20}} -> {{2,3,1},{10,20,30}}
 BEGIN
   IF SIZE(LSTS)≥Keynum THEN
    IF SIZE(LSTS(1))>1 AND SIZE(LSTS(Keynum))>1 THEN
     RETURN SortN(LSTS,K);
    END;
   END;
  RETURN {};
  //To reverse sequence call ReverseLOLS()
 END;
 //These routines are similar
 //Why does one fail TBD
 EXPORT SortByKeyTBD(LSTS,KeyNum)
 //Sort lists by list number KeyNum (with some input guards)
 //Hint: If this gives a data type error call SORTN directly (WHY?) 
 BEGIN
  IF 0<KeyNum≤SIZE(LSTS) AND SIZE(LSTS)>1 THEN
   IF LSTS(1)≠{} AND LSTS(2)≠{} THEN
    RETURN SortN(LSTS,KeyNum);
   END;
  ELSE
   //Potential:not all checked
   //List small, not containing lists, key out of range, key list unsortable
   RAISE(MN+"SortByKey",EL,SortError,KeyNum,ListErrK);
  END;
  RETURN {};
 END;

 EXPORT SortL(LST)
 //This implementation uses native SORT
 BEGIN
  IF TYPE(LST)≠TYPELST THEN 
   RAISE(MN+"SortL",EL,SortError,"",ListErrK);
  END;
  RETURN SORT(LST);
 END;

 EXPORT SortN(list,n)
 // From http://www.hpmuseum.org/forum/thread-6179.html?highlight=sort+two+lists
 //Call via ListSORTBYKEY to guard parameters...or call directly with good inputs 
 BEGIN
  LOCAL li,ma;
  ma:=list2mat(list) ;
  li:=SORT(MAKELIST(mat2list(col(ma,I)),I,1,colDim(ma)),n);
  RETURN MAKELIST(mat2list(col(list2mat(li),I)),I,1,rowDim(ma));
 //For example:
 //SORTN({{3,2,1},{15,20,18}},1);// -> {{1,2,3},{18,20,15}}
 //SORTN({{3,2,1},{15,20,18},{32,35,27}},1);// -> {{1,2,3},{18,20,15},{27,35,32}}
 END;

 EXPORT SortsVERSION()
 BEGIN
  RETURN CRID;
 END;

 
 EXPORT Pyreverse(LST)
 //Python analogue
 BEGIN
  RETURN REVERSE(LST);
 END;

EXPORT Pysort(LST,KeyFunc,RReverse)
 //Python analogue SORT
 //TBD: KeyFunc: Selects sort key from item
 BEGIN
  IF TYPE(KeyFunc)==TYPEFLOAT AND KeyFunc==0 THEN
   //0=None=NO FUNC
  ELSE
   TBD();
   RAISE(MN+"Pysort",EL,ValueError,"",1);//TBD
  END;
  RETURN IFTE(RReverse,SORT(Pyreverse(LST)),SORT(LST));
 END;

EXPORT ListPuzzles()
 //SEE http://www.hpmuseum.org/forum/thread-8209.html?highlight=challenge
 BEGIN
  LOCAL VR;
  LOCAL LST:=MAKELIST("",VR,1,5);//40
  LST(2):="31. ListOCCURRENCESWITHSORT";
  CHOOSE(VR,MN+"Puzzles (See thread)",LST);
 END;

EXPORT SortSeeAlso ()
 BEGIN
  LOCAL KK;
  LOCAL CatFuns:={
   "REVERSE",
   "reverse",
   "revlist (slower)",
   "SORT",
   "sort"
   };
  //Just Listed as a reminder:not Selectable
  CHOOSE(KK,MN+" Relevant Cat Functions",CatFuns)

 END;
 
 EXPORT SortsExamples()
 //In real use, use XXX:=Sort...()
 BEGIN
  LOCAL LL:={1,2,3,4,5,6,7,8,9};
  PRINT();
  PRINT(SortsVERSION);

  PRINT("Is");
  PRINT(IsSortable(0));
  PRINT(IsSortable({})); 
  PRINT(IsSortable(LL));
  PRINT(IsSortablePortable(LL));
  

  PRINT(IsSorted(LL)); 
  PRINT(IsSortedEQ(LL));
 
  PRINT("Reverse");

  PRINT(ReverseLOL({{1,2},{3,4},{5,6}}));
 
  PRINT("Sort");

  //SortByABS
  PRINT(SortByABS({1,2,3,−2})); // -> {1,2,−2,3}
 
  //SortByCount
  PRINT(SortByCount({{1,2,3},{10,30,20}},2)); // -> {{2,3,1},{10,20,30}} 
  //SortByKey

  //SortL
  PRINT(SortL(LL));

  //SortN
  PRINT(SortN({{3,2,1},{15,20,18}},1));// -> {{1,2,3},{18,20,15}}
  PRINT(SortN({{3,2,1},{15,20,18},{32,35,27}},1));// -> {{1,2,3},{18,20,15},{27,35,32}}
  
  //SortByOccurrences
  PRINT(SortByCount({{1,2,3},{1,22,3}},2));
  PRINT(ReverseLOL(SortByCount({{1,2,3},{1,22,3}},2)));
 
  PRINT("Py");
  PRINT(Pyreverse({1,2,3}));
  PRINT(Pysort({1,22,3},0,0));
  PRINT("Exampled");
  //RETURN 0; 
 END;

 EXPORT SORTS()
 BEGIN
  ABOUT();
  //SortExamples();
 END;

Stephen Lewkowicz (G1CMZ)
https://my.numworks.com/python/steveg1cmz
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: Sorts API: A collection of sort functions - StephenG1CMZ - 09-08-2018 09:10 PM



User(s) browsing this thread: 1 Guest(s)