8
$\begingroup$

For teaching purposes, I want to create a Mathematica notebook that will "notice" when the user defines or redefines a variable or function of a particular name, so that it can check the value and take some appropriate action. For example, the notebook might be monitoring the symbol "foo", so that if the user executes foo = 22/7 at any time, code that I've written and hidden (perhaps in an invisible cell, perhaps via an initialization cell that loads a package I've written) might write out some hint text, e.g. "You've guessed the right variable name, but not the right value yet." I know I could do this by having the user click an explicit "test" button or some such thing, but I'd rather have my code monitor the user invisibly and take action without the user invoking it.

Is this possible? If so, how might it be implemented?

$\endgroup$
  • 3
    $\begingroup$ Have at look at $NewSymbol, etc. $\endgroup$ – ciao Jul 4 '15 at 20:24
  • $\begingroup$ That looks like it solves half my problem beautifully: Noticing when the symbol is created. Hm… Perhaps the function given to $NewSymbol can define a Dynamic[...] that will detect subsequent changes… $\endgroup$ – ibeatty Jul 4 '15 at 20:29
  • 2
    $\begingroup$ I think this is a bad idea for reasons that have nothing to do with Mathematica. If I were one of your students, I would be very disturbed when required to work with a notebook that appeared to contain a automaton that was watching my every move. The world does not need the Big Brother approach to teaching. On the hand, a palette with buttons such as "Check my answer" or "Give me a hint" would be acceptable because it would leave me feeling I was in control. Further, the palette approach would be much easier to implement and debug than the Big Brother approach. $\endgroup$ – m_goldberg Jul 4 '15 at 23:42
  • $\begingroup$ @m_goldberg: "You've guessed the right sentiment, but not the right values yet."... :-} $\endgroup$ – ciao Jul 5 '15 at 4:14
  • 1
    $\begingroup$ @m_goldberg: You're making assumptions about how I plan on using this. I'm planning a special-purpose notebook that acts somewhat like an interactive computer game or tutorial; students won't perceive this as Big Brother "watching" them, but rather the notebook interacting with them. (My profession is Physics Education Research. I know a thing or two about interacting constructively with students.) $\endgroup$ – ibeatty Jul 7 '15 at 15:17
7
$\begingroup$

Something, that more or less does what you asked for, can be achieved by creating a hidden InitializationCell using a DynamicWrapper

DynamicWrapper["xxx", 
 If[foo == 23, MessageDialog["You guessed it!"], 
  MessageDialog["You've guessed the right variable name, but not the right value yet."]]]

A much more elegant method is to use NotebookDynamicExpression:

SetOptions[EvaluationNotebook[], 
  NotebookDynamicExpression :> 
   Refresh[If[foo == 23, MessageDialog["You guessed it!"], 
     MessageDialog[
      "You've guessed the right variable name, but not the right value yet."]], 
    TrackedSymbols :> {foo}]];

You can remove this cell after evaluating it once, as the NotebookDynamicExpression is now part of the notebook.


Yet another possibility is to use ValueFunction in a hidden InitializationCell:

ValueFunction[foo] = 
  If[#2 == 23, MessageDialog["You guessed it!"], 
    MessageDialog[
     "You've guessed the right variable name, but not the right value yet."]] &;
$\endgroup$
  • $\begingroup$ This is an elegant way of monitoring one symbol! $\endgroup$ – ibeatty Aug 8 '15 at 16:48
3
$\begingroup$

One can use $Pre to check if an input expression defines the correct variable and is doing so using the correct value.

SetAttributes[check, HoldAll]
check[new_Set] := (Print["You guessed it!"]; new) /; HoldForm@new == HoldForm@Set[foo, 23]
check[new_Set] := (Print[
  "You've guessed the right variable name, but not the right value yet."]; new) /; 
 Extract[HoldForm[new], {1, 1}, Hold] == Hold[foo]
check[new_] := new
$Pre = check;

Example

$\endgroup$
  • $\begingroup$ It seems Mathematica has some very deep, powerful hooks like $Pre and $NewSymbol that I didn't know about. Thanks! $\endgroup$ – ibeatty Jul 7 '15 at 15:24

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.