Message Boards Message Boards

Constructing multiple choice questions for student notebooks.

Posted 10 years ago
Hello Community,
I have been constructing a set of tutorial notebooks for teaching materials science. Students are given some material and programming assignments.

I've trying create a method to pace the students' progress through the notebook--I'd like them to stop and think before they can proceed.

Here is a simplified example of a modal multiple choice interface:
 DialogInput[
   Column[{
     "What is 3 times 2?",
     TabView[{3 -> Tooltip["Wrong", "Oh you are just being silly"],
       Exp[3] -> "Wrong",
       6 -> DefaultButton["Correct", DialogReturn[True]],
       Cos[Pi/6] -> "Note quite",
       "VI" ->
        DefaultButton["Tu sunt rectam, sed asinus sapien.",
        DialogReturn[True], ImageSize -> Full]}, None]
    }
   ],
  Modal -> True];

Note modal is not a supported option for DialogInput, but it works anyways.

In the ultimate version, the DefaultButton would programmatically open subsequent cells that will allow the students to proceed (I've seen a thread someplace that shows how to do this, but can't find it now).


Here is where I am stuck: I'd like to embed this a button in the tutorial notebook.  This is the functionality that I'd like to have, but it hangs and complains about a Dynamic which doesn't evaluate (I don't see a Dynamic, but perhaps ToolTip invokes one).

Here is an example, but warning, if you evaluate the following you will have to try to abort the process 3 times.
 Button["Press Here to Continue",
 DialogInput[
    Column[{
      "What is 3 times 2?",
      TabView[{3 -> Tooltip["Wrong", "Oh you are just being silly"],
        Exp[3] -> "Wrong",
        6 -> DefaultButton["Correct", DialogReturn[True]],
        Cos[Pi/6] -> "Note quite",
        "VI" ->
        DefaultButton["Tu sunt rectam, sed asinus sapien.",
         DialogReturn[True], ImageSize -> Full]}, None]
     }
    ],
   Modal -> True];
]

Can anyone see a way to acheive my multiple choice blocking dialog?  (And, if you could see a way for cumulative progress to be related to an instructor, that would be terrific.)

WCC
POSTED BY: W. Craig Carter
8 Replies
Ah, I'm so happy it works for you! This is a cool concept for education.
POSTED BY: Erin Craig
Here is an idea... it is a modification of your code above. If the student gets the answer right, then it writes the new content to the end of the notebook. So, the student wouldn't be able to see anything about the upcoming content until they get the right answer on the current question.

(You could also use AutoScroll to have the notebook scroll to the new section.)

 CreateDocument[{
  
   Cell["Tutorial", "Title"], Cell["Words of wisdom...."],
  
   Cell["Here is how to integrate in Mathematica", "Section"],
   ExpressionCell[
    Defer[InputForm[
      Integrate[
       Cos[4 Pi x/lambda] Cos[2 Pi x/lambda], {x, 0, lambda}]]],
   "Input"],
 
  ExpressionCell[
   Button["Continue",
    CreateDialog[
     Column[
      {
       "Why is the integral above equal to zero?",
       TabView[
        {
         "because the integrand is zero" ->
          Tooltip["Wrong", "Oh you are just being silly"],
         "because the integrand is odd about lambda/2" -> "Wrong",
         "this is because of the orthogonality of cosines" ->
          DefaultButton[
           "Correct",
           DialogReturn[
            SelectionMove[nb, After, Notebook];
            NotebookWrite[
             nb,
             {
              Cell["Coding Challenge", "Subtitle"], 
              Cell["Derive the grand unified theory with Mathematica",
                "Subsubtitle"]
              }
             ];
            True
            ]
           ],
         Cos[Pi/6] -> "Not quite"
         },
        None
        ]
       }
      ],
     Modal -> True
     ]
    ]
   ]
  }
]
POSTED BY: Erin Craig
Hello Erin,
Very nice!

Your code works perfectly, but I had to make a trivial addition:
nb = CreateDocument[{
   Cell["Tutorial", "Title"], Cell["Words of wisdom...."],
(*** and the rest is the same as your code ***)
Thanks Erin!
WCC
POSTED BY: W. Craig Carter
 Hi All
 Very detailed description of the testing  program is on the site:   http://www.youtube.com/watch?v=GkfhCIR9zvw 
 Here is part of code (package for exit the testing program)  
 BeginPackage["ProgrammingInMath`exit`"]
 
 exit::usage = "quit"
 
 Begin["`Private`"]
 
 nb = NotebookPut[
 
     Notebook[{Cell[

          BoxData[StyleBox["Exit", FontFamily -> "Verdana", FontSize -> 18,

              FontColor -> RGBColor[0.996109, 0, 0]]], "Title",

          TextAlignment -> Center, ShowCellBracket -> False]},

      WindowTitle -> "Exit", WindowElements->None, WindowFrameElements->None,

      WindowClickSelect->False,WindowSize -> {100, 70},

      Background -> Hue[.2]]]; Pause[2]

NotebookClose[nb];

Quit[];

End[]

EndPackage[]
POSTED BY: Silvia Torosyan
Thank you everyone, but I am after something  a bit different.  Arnoud, that was a useful hint. Thanks.  I've put a bit more work into this:

My goal here is not to have students be quized on correct answers, but to make them read and understand before they can proceed. (n.b., I am finding students treat instructional workbooks like a video game, they click and go without thinking).

Here are some working examples that I hope illustrate what I am after.

This works, but still does not achieve my goal.
 CreateDocument[
  {
   groupOpen = 1;
   Cell["Tutorial", "Title"],
   Cell["Words of wisdom...."],
   Cell["Here is how to integrate in Mathematica", "Section"],
   ExpressionCell[
    Defer[InputForm[
      Integrate[
      Cos[4 Pi x/lambda] Cos[2 Pi x/lambda], {x, 0, lambda}]]],
   "Input"],
  ExpressionCell[Button["Continue",
    CreateDialog[
     Column[{
       "Why is the integral above equal to zero?",
       TabView[{"because the integrand is zero" ->
          Tooltip["Wrong", "Oh you are just being silly"],
         "because the integrand is odd about lambda/2" -> "Wrong",
         "this is because of the orthogonality of cosines" ->
          DefaultButton["Correct", DialogReturn[True]],
         Cos[Pi/6] -> "Note quite"}, None]
       }
      ],
     Modal -> True]
    ]
   ],
  CellGroup[
   {
    TextCell["Coding Challenge", "Subtitle"],
    TextCell["Derive the grand unified theory with Mathematica",
     "Subsubtitle"]
    }, groupOpen
   ]
  }
]


This also works, but doesn't achieve my goal.
 CreateDocument[
  {
   groupOpen = All; (*the difference from above, All is not documented..*)
   Cell["Tutorial", "Title"],
   Cell["Words of wisdom...."],
   Cell["Here is how to integrate in Mathematica", "Section"],
   ExpressionCell[
    Defer[InputForm[
      Integrate[
      Cos[4 Pi x/lambda] Cos[2 Pi x/lambda], {x, 0, lambda}]]],
   "Input"],
  ExpressionCell[Button["Continue",
    CreateDialog[
     Column[{
       "Why is the integral above equal to zero?",
       TabView[{"because the integrand is zero" ->
          Tooltip["Wrong", "Oh you are just being silly"],
         "because the integrand is odd about lambda/2" -> "Wrong",
         "this is because of the orthogonality of cosines" ->
          DefaultButton["Correct", DialogReturn[True]],
         Cos[Pi/6] -> "Note quite"}, None]
       }
      ],
     Modal -> True]
    ]
   ],
  CellGroup[
   {
    TextCell["Coding Challenge", "Subtitle"],
    TextCell["Derive the grand unified theory with Mathematica",
     "Subsubtitle"]
    }, groupOpen
   ]
  }
]

I would have expected this to work with Dynamic, but it doesn't and I don't know why....
 CreateDocument[
  {
   groupOpen = 1;
   Cell["Tutorial", "Title"],
   Cell["Words of wisdom...."],
   Cell["Here is how to integrate in Mathematica", "Section"],
   ExpressionCell[
    Defer[InputForm[
      Integrate[
      Cos[4 Pi x/lambda] Cos[2 Pi x/lambda], {x, 0, lambda}]]],
   "Input"],
  ExpressionCell[Button["Continue",
    CreateDialog[
     Column[{
       "Why is the integral above equal to zero?",
       TabView[{"because the integrand is zero" ->
          Tooltip["Wrong", "Oh you are just being silly"],
         "because the integrand is odd about lambda/2" -> "Wrong",
         "this is because of the orthogonality of cosines" ->
          DefaultButton["Correct",
           DialogReturn[groupOpen = All; True]], (*changes value of groupOpen*)
         Cos[Pi/6] -> "Note quite"}, None]
       }
      ],
     Modal -> True]
    ]
   ],
  CellGroup[
   {
    TextCell["Coding Challenge", "Subtitle"],
    TextCell["Derive the grand unified theory with Mathematica",
     "Subsubtitle"]
    }, Dynamic[groupOpen] (*second argument to CellGroup is Dynamic*)
   ]
  }
]

I am going to try NotebookFind by CellTags next and then programmatically open cells that way, but I thought this method would have been easier.

Any insights welcome!
POSTED BY: W. Craig Carter
We should keep in mind that with the power of symbolic WL programming we could go also beyond multiple choice. Some preliminary thoughts from here:

Automatically check student answers in tests







POSTED BY: Sam Carrettie
Try adding Method->"Queued" to your button?
 Button["Press Here to Continue",
  DialogInput[
   Column[{"What is 3 times 2?",
     TabView[{3 -> Tooltip["Wrong", "Oh you are just being silly"],
       Exp[3] -> "Wrong",
       6 -> DefaultButton["Correct", DialogReturn[True]],
       Cos[Pi/6] -> "Note quite",
       "VI" -> DefaultButton["Tu sunt rectam, sed asinus sapien.",
         DialogReturn[True], ImageSize -> Full]}, None]}],
  Modal -> True], Method -> "Queued"]
POSTED BY: Arnoud Buzing
Posted 10 years ago
Here is an attempt to generalize and perhaps serve as motivation for others,
 qna[q_, a_, alt_] :=
 
  DynamicModule[
 
   {ln, funs, var, enb, layout, cusum, vis = "", perc},
 
   ln = Length[q];
 
   enb = Table[Unique["e"], {ln}];

  Map[(#[_] := True) &, enb];

  funs = Table[Unique["f"], {ln}];

  var = Table[Unique["v"], {ln}];

  MapThread[(#1[u_] := If[u == #2, 1, 0]) &, {funs, a}];

  layout = MapThread[Column[{

       #1,

       RadioButtonBar[Dynamic@#2, Thread[Range[Length@#3] -> #3],

        Enabled -> Dynamic@#5[#2], Appearance -> "Vertical"],

       Button["Lock in answer", #5[#2] := False]

       }] &, {q, var, alt, funs, enb}];

  cusum = Dynamic[Total@MapThread[#1[#2] &, {funs, var}]];

  perc = Dynamic[N[100 Total@MapThread[#1[#2] &, {funs, var}]/ln, 2]];

  Column[Join[

    layout, {Button["Cumulative score",

      If[! Or @@ MapThread[#1[#2] &, {enb, var}],

       vis = Style[Row[{cusum, "(", perc, "%)"}], 20, Red],

       vis = ""]], Dynamic@vis}], Frame -> True,

   BaseStyle -> {FontFamily -> "Kartika", Blue, 20}]]

 The first argument is list of questions, the second argument is the number of the correct answer, the third argument is list question alternatives.

Testing:
qna[{"What is 2 x 3?", "What is sin(\[Pi]/6)?","What is \!\(\*SuperscriptBox[\(16\), \(1/2\)]\) ?"}, {2,3,1}, {{1, 6, 2}, {1, 0, 1/2}, { 4, 5, 6, 7}}]

You can correct number forms  or other stylistic differences etc. Note that cumulative sum only shows when all questions answered.
POSTED BY: Mark Dooris
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract