I teach a class where students do a weekly lab in Mathematica. They do it in a computer lab, and because there are many of them, and only one of me, I encourage them to help one another. Unfortunately, that means I get a lot of labs with the exact same Plot commands, or the exact same "make up your own example" solutions, etc.

What I would like to do is, in some sense, "randomize" the lab when each student opens it. To keep things simple, Let us consider a question that looks like

Find the square root of the following number: #

Here, # would ideally be replaced by a random number as soon as the student opens the lab. That is, I am looking for a way to do the following:

  • run a command as soon as the lab is opened
  • the only remnant of this command, after it is run, is its output

I know that second one is probably difficult, but I would even be satisfied with a way to have # reference the output of a hidden command, for example.


PS: I have no idea what the tags should be for this question, so I chose by best guesses; please feel free to improve them.

  • $\begingroup$ given that you say "run a command as soon as the lab is opened", you use "lab" as a synonym for notebook (sometimes) here, right? so you'd like to have a notebook that, every time it is opened, has some randomized elements? $\endgroup$ – acl Oct 21 '12 at 18:54
  • 1
    $\begingroup$ How about generating a notebook for each student/computer? Then you would have complete control... $\endgroup$ – Ajasja Oct 21 '12 at 19:02
  • $\begingroup$ @acl: Yes, sorry, I mean notebook wherever I write lab. $\endgroup$ – Steve D Oct 21 '12 at 19:24
  • $\begingroup$ @Ajasja: I don't think you understand how difficult that would be with 120 students all using Blackboard. $\endgroup$ – Steve D Oct 21 '12 at 19:25

Based on my answers here and here, you may proceed as follows:

  1. Change the global setting that allows auto-execution of Initialization Cells:

    SetOptions[$FrontEndSession, GlobalInitializationCellWarning -> False]
      Either for session as above, or persistently with `$FrontEnd`.  

    This must be done before the Notebook is opened.

  2. Set Notebook options for auto-execution of Initialization Cells:

      InitializationCellEvaluation -> True,
      InitializationCellWarning -> False]
  3. Create an Initialization Cell that defines AutoDestruct and sets $HistoryLength = 0:

    AutoDestruct[] := (If[$FrontEnd =!= $Failed, 
       SelectionMove[EvaluationNotebook[], All, EvaluationCell];
    $HistoryLength = 0;
  4. Define Initialization work Cells that generate desired random output and finish with AutoDestruct[] on a separate line (for each cell):

    CellPrint @ Cell[ToBoxes@RandomInteger[100], "Input"]
  • 1
    $\begingroup$ Often, such lab exercises must be performed in a lab managed by an IT department where the instructor has no control -- at least once applications are installed and disk images are frozen -- over Global settings for Mathematica. Wouldn't that preclude Step 1? $\endgroup$ – murray Oct 22 '12 at 0:57
  • $\begingroup$ @murray If it does I believe there may be no solution as otherwise that setting is defective and there is a security risk that needs to be patched. As an alternative one could generate each Notebook programmatically but that is not what was requested. $\endgroup$ – Mr.Wizard Oct 22 '12 at 6:36
  • $\begingroup$ I like this answer very much, but yes, I was afraid there would need to be some setting that were changed, which I will not be able to do. I guess the problem is Mathematica will not, by default, execute commands automatically? However the rest of your answer is great! I think what I will do is add a button at the beginning of the lab that says "Click to start" and will run these randomizations. My only concern now is "greying out" all the other cells until that button is clicked. But that is another question... Thanks! $\endgroup$ – Steve D Oct 22 '12 at 16:15
  • 1
    $\begingroup$ @SteveD I'm not sure to what degree you need to or can hide things from your users. You might use something like: makeHidden = Function[expr, Defer@Uncompress@# &@Compress@Unevaluated@expr, HoldAll]; and then makeHidden[ RandomInteger[99, 3] ] -- then you would put only the output of that in your distributed Notebook. (This could be done using AutoDestruct[] in your master copy, just be sure not to save over the top of it.) Go ahead and post another question if you want to; I'm sure you'll get some good answers. $\endgroup$ – Mr.Wizard Oct 22 '12 at 16:23

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.