16
$\begingroup$

The Wolfram Language has more than 5000 built-in functions and constants.

functionslist = Flatten[
   Names[#] & /@ Flatten[
     {# <> "*", "$" <> # <> "*"} &
      /@ CharacterRange["A", "Z"]
     ]
   ];
Length @ functionslist
5689

OK, 5689 have documentation in Mathematica 10.3, to be more precise. In order to keep up with that, I would like to pick randomly a function documentation to refresh.

SystemOpen["paclet:ref/" <> RandomChoice[functionslist]]

But I would like to refresh new functions more often than old ones.

SystemOpen["paclet:guide/SummaryOfNewFeaturesIn103"]

How can we implement a "New function of the day" function that focuses on functions new to the current version?

Bonus if it picks from all functions with decaying probability as a function of "age".

Code adapted from this question.

$\endgroup$
5
  • 1
    $\begingroup$ There are more symbols there than there is documentation for them. I'd scan FileBaseNames in References directory. To get dates you can prse the notebook to get "History" cell. ImportNotebook would be of great help but it is quite slow in context of 5k repetitions. $\endgroup$
    – Kuba
    Oct 22, 2015 at 7:04
  • 2
    $\begingroup$ WolframLanguageData["ArrayReshape", "DateIntroduced"] may be useful. $\endgroup$
    – Szabolcs
    Oct 22, 2015 at 7:58
  • $\begingroup$ Where would you put this command? If you put it in your init.m file it would pop up a new function every time you restarted the kernel. Is there some equivalent file that only loads when you open the frontend? $\endgroup$
    – Jason B.
    Oct 22, 2015 at 13:43
  • $\begingroup$ @JasonB I would be happy to have a procrastination palette for that. :) $\endgroup$
    – rhermans
    Oct 22, 2015 at 13:44
  • $\begingroup$ Do you mean a button? like press the button to get a new random function? hmmmmm, I don't know how to make panels (are they called pallettes? I haven't used the pallettes since I first found this software) $\endgroup$
    – Jason B.
    Oct 22, 2015 at 13:47

2 Answers 2

9
$\begingroup$

Here is an alternative procedure using EntityValue[] and Dataset[]. The idea is to build a Dataset[] containing function names and the version numbers they were introduced in, and then use a query to pull all the names that are new in a particular version. One can then pick any of these names randomly. A way to bias newer functions over older ones is to use RandomChoice[] on the list of version numbers, with each version number being its own weight.

$versions = {1, 2, 2.2, 3, 4, 4.1, 4.2, 5, 5.1, 5.2, 6, 7, 8, 9,
             10, 10.1, 10.2, 10.3};

symtable = Dataset[AssociationThread[{"Name", "VersionIntroduced"}, #] & /@
           EntityValue["WolframLanguageSymbol", {"Name", "VersionIntroduced"}]];

randomHelpPage := With[{version = RandomChoice[$versions -> $versions]},
         SystemOpen["paclet:ref/" <> RandomChoice[Normal[
                    symtable[Select[#VersionIntroduced == version &], "Name"]]]]]

Button["Random WL Function", randomHelpPage]

This should now function in a similar manner to Jason's solution.

$\endgroup$
6
  • $\begingroup$ When I run this code the button is created, but when I press it I get the errors RandomChoice::lrwl: The items for choice EntityValue[][All,Name] should be a list or a rule weights -> choices. >> and String expected at position 2 in \ paclet:ref/<>RandomChoice[EntityValue[][All,Name]]. >>. I'm on MMa 10.2 on OS X; removing the 10.3 from $versions didn't help either. $\endgroup$ Oct 28, 2015 at 16:40
  • $\begingroup$ @freddie, did any errors occur while symtable was evaluated? $\endgroup$ Oct 28, 2015 at 16:43
  • $\begingroup$ no but it is not much of a Dataset as it has only two elements and zero levels. It seems that EntityValue didn't do anything (I don't know what it is supposed to do, but running ` EntityValue['WolframLanguageSymbol', {'Name', 'VersionIntroduced'}]]` just outputs itself again). $\endgroup$ Oct 28, 2015 at 16:51
  • $\begingroup$ Ah, that's why. I don't know why it's not working in 10.2; I'll do a confirmatory test later in that version. $\endgroup$ Oct 28, 2015 at 16:55
  • $\begingroup$ @freddie, the code works in 10.2 on Xubuntu. Try it again in a fresh session. $\endgroup$ Oct 29, 2015 at 13:35
10
$\begingroup$

First we get a list of the functions, indexed by their introduction date. The method suggested by Szabolics turned out to be very slow - although it has the advantage that it gives a date rather than just the year.

And as Kuba mentioned, the functions gathered by Rhermans's function do not all have help pages, so we just grab the file list from the help pages directory.

functiondatelist = Module[{dir, symbolslist, datelist, mmagrep},

   (*
   Here I'm scanning only what is in the 'ReferencePages/
   Symbols' directory, we could add other directories to scan 
   *)
   dir = 
    FileNameJoin@{$InstallationDirectory, "Documentation", "English", 
      "System", "ReferencePages", "Symbols"};
   symbolslist = FileNames@FileNameJoin[{dir, "*"}];
   Print["Found " <> IntegerString@Length@symbolslist <> 
     " symbols with help pages"];
   (*
   Now we scan the notebooks for the phrase "Introduced in" and \
   thereby grep the year it was created.
   *)
   mmagrep[file_, patt_] := 
    With[{data = Import[file, "Lines"]}, 
     Pick[Transpose[{Range[Length[data]], data}], 
      StringFreeQ[data, patt], False]];
   Print["Scanning for introduction dates:"];

   Monitor[
    datelist = 
      Table[StringCases[
          mmagrep[symbolslist[[n]], "Introduced in"][[1, 2]], 
          DigitCharacter ..][[1]] // ToExpression, {n, 
        Length@symbolslist}];
    , n];

   (*Now bin up the list of functions by their year *)

   Reverse@SortBy[
     GatherBy[
      Transpose[{FileBaseName /@ symbolslist, 
        datelist}], #[[2]] &], #[[1, 2]] &]

   ];

The symbol-introduction years aren't evenly distributed,

DeleteDuplicates[Flatten@functiondatelist[[All, All, 2]]]

(*  {2015, 2014, 2012, 2010, 2008, 2007, 2005, 2004, 2003, 2002, 2000, 
      1999, 1996, 1993, 1991, 1988} *)

Choose some directory in your $Path where you like to keep packages, and create a folder titled RandomHelp to write this data to. I don't mind having a cluttered home directory so I just use

Export[FileNameJoin[{directoryinyourpath,"RandomHelp", "mma_symbollist.m"}], 
  functiondatelist];

Copy this text either into a text file named init.m inside the RandomHelp directory,

{symbollist, symbolintyears} = 
  Module[{temp}, 
   temp = Import[FileNameJoin[{"RandomHelp", "mma_symbollist.m"}]];
   {temp[[All, All, 1]], 
    DeleteDuplicates[Flatten@temp[[All, All, 2]]]}];

randomintroductionyear := Module[{test, gamma},
   gamma = 0.15;
   test = Length@symbolintyears + 1;
   While[test > Length@symbolintyears,
    test = Ceiling@RandomVariate[ExponentialDistribution[gamma]];
    ];
   test
   ];

randomnewhelppage :=
  Module[{year, symbol},
   year = randomintroductionyear;
   SystemOpen[
    "paclet:ref/" <> 
     symbollist[[year, RandomInteger[{1, Length@symbollist[[year]]}]]]]

   ];

Button["Procrastination Button", randomnewhelppage]

If you want to increase the bias towards the new, simply make the gamma value larger. Here I have gamma set to 0.15 and 0.5, respectively

enter image description here

Save the init.m file, and now all you have to do is type

<< "RandomHelp`"

and you get a nice button

enter image description here

$\endgroup$
7
  • 4
    $\begingroup$ Nicely done. :) A note: it's safest to get the list of documented symbols from EntityValue[#, "Name"] & /@ WolframLanguageData[] instead of Names["System`*"]; to use my favorite example, SequenceLimit[] is an undocumented system function, and it is indeed present in the latter list, but not the former. $\endgroup$ Oct 22, 2015 at 15:54
  • $\begingroup$ @J.M. , what would the advantage that be over just getting the list of *.nb files in the ReferencePages/Symbols/ directory? Running EntityValue[#, "Name"] & /@ WolframLanguageData[] ran for over ten minutes and I got impatient and cancelled it. $\endgroup$
    – Jason B.
    Oct 23, 2015 at 7:42
  • $\begingroup$ Admittedly, it is slower than reading files (another current annoyance of Entity[] objects). It's short, which is apparently its only appeal. :( $\endgroup$ Oct 23, 2015 at 7:51
  • 2
    $\begingroup$ @J.M. WolframLanguageData[WolframLanguageData[], {"Name", "VersionIntroduced", "VersionLastModified", "URL"}] is much faster. $\endgroup$
    – WReach
    Oct 23, 2015 at 14:33
  • 1
    $\begingroup$ @J.M. and @WReach, it's interesting to note that there are many undocumented symbols when you make the WolframLanguageData call. For example, you get InverseWishartMatrixDistribution or TravelDirectionsData, and 73 other symbols that have no documentation page. $\endgroup$
    – Jason B.
    Oct 23, 2015 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.