15
$\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$
  • 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 '15 at 7:04
  • 2
    $\begingroup$ WolframLanguageData["ArrayReshape", "DateIntroduced"] may be useful. $\endgroup$ – Szabolcs Oct 22 '15 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 '15 at 13:43
  • $\begingroup$ @JasonB I would be happy to have a procrastination palette for that. :) $\endgroup$ – rhermans Oct 22 '15 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 '15 at 13:47
7
$\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$
  • $\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$ – freddieknets Oct 28 '15 at 16:40
  • $\begingroup$ @freddie, did any errors occur while symtable was evaluated? $\endgroup$ – J. M. is away Oct 28 '15 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$ – freddieknets Oct 28 '15 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$ – J. M. is away Oct 28 '15 at 16:55
  • $\begingroup$ @freddie, the code works in 10.2 on Xubuntu. Try it again in a fresh session. $\endgroup$ – J. M. is away Oct 29 '15 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$
  • 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$ – J. M. is away Oct 22 '15 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 '15 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$ – J. M. is away Oct 23 '15 at 7:51
  • 2
    $\begingroup$ @J.M. WolframLanguageData[WolframLanguageData[], {"Name", "VersionIntroduced", "VersionLastModified", "URL"}] is much faster. $\endgroup$ – WReach Oct 23 '15 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 '15 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.