Post Reply 
Sort Lists API: A collection of sort functions
09-15-2018, 10:52 PM (This post was last modified: 09-15-2018 10:55 PM by StephenG1CMZ.)
Post: #3
RE: Sort Lists API: A collection of sort functions
Version 0.3 now implements Pysort and fixes some bugs.

Code:


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

 //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);
 SortByKey(SORTL,Keynum);
 SortByKeyTBD(SORTL,Keynum);
 SortLST(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 RAISE(MN,ERRLST,ERR,CULPRIT,SEVERITY)
 BEGIN
 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:=SortLST(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:2ND LEVEL 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;

 //The following could return just the valuesO
 //or Values and counts in 2 lists
 //Whichis preferred?

 EXPORT SortByCounts(LST)
 //Returns {LSTV,LSTF} sorted by frequency of occurrence 
 //EG {{1,2,3},{10,30,20}} -> {{2,3,1},{10,20,30}}
 
 BEGIN
  ListANS:=ListCOUNTS(LST);//To omit this step, use SortByKey directly
  RETURN SortByKey(ListANS,2);
 END;

 EXPORT SortByKey(LSTS,Keynum)
 //LSTS is {LSTV,LSTF} as returned by
 //ListCOUNTS(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 SortLST(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
 //PyOpt KeyFunc: STRING EG "ABS" (NULL=NONE)
 //PyOpt PRReverse BOOL
 BEGIN
  LOCAL TMP;
  IF KeyFunc=="" THEN
   ListANS:=SORT(LST);
   RETURN IFTE(RReverse,Pyreverse(ListANS),ListANS);
  END;
  TMP:=EXPR(KeyFunc+"(LST)");
  ListANS:=SortN({LST,TMP},2);
  RETURN IFTE(RReverse,Pyreverse(ListANS(1)),ListANS(1)); 
 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}
 
  //SortByCounts
  PRINT(SortByCounts({1,2,3,2,3,3})); // -> {{1,2,3},{1,2,3}} 
  //SortByKey
  PRINT(SortByKey({{1,2,3},{10,30,20}},2)); //-> {{1,3,2},{10,20,30}}
  PRINT(SortByKey({{1,2,3},{1,22,3}},2));
  PRINT(ReverseLOL(SortByKey({{1,2,3},{1,22,3}},2)));

  //SortL
  PRINT(SortLST(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("Py");
  PRINT(Pyreverse({1,2,3}));
  PRINT(Pysort({1,22,3},"",0));
  PRINT(Pysort({1,22,3},"ABS",0));
  PRINT("Exampled");
  //RETURN 0; 
 END;

 EXPORT SORTL()
 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: Sort Lists API: A collection of sort functions - StephenG1CMZ - 09-15-2018 10:52 PM



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