PREP 2014 Question Authoring - Archived

Math mode in popup menus

Math mode in popup menus

by Michele Titcombe -
Number of replies: 5
Is there a math mode in popup menu entries? I tried without success to put the symbol for "less than or equal to" or "greater than or equal to". Finally I gave up.

Here is the (partial) code where I wanted to have math mode in the popup menu items:

Context("Numeric");
$popup1 = PopUp(
["?","p > 1","p > 0","p < 1","p > 1 or p = 1"],
"p > 1",
);
$popup2 = PopUp(
["?","p < 1 or p = 1","p > 1","p < 1","p > 0"],
"p < 1 or p = 1",
);

##############################################################
#
# Text
Context()->texStrings;
BEGIN_TEXT
The infinite series \( \sum\limits_{n=1}^\infty \dfrac{1}{n^p} \) is called a $BBOLD p-series. $EBOLD $BR
(a) The p-series converges if \{ $popup1->menu() \}
$BR$BR
(b) The p-series diverges if \{ $popup2->menu() \}
END_TEXT
Context()->normalStrings;

##############################################################
# Answers
install_problem_grader(~~&std_problem_grader);
$showPartialCorrectAnswers = 0;
ANS( $popup1->cmp() );
ANS( $popup2->cmp() );
In reply to Michele Titcombe

Re: Math mode in popup menus

by Paul Pearson -
Hi Michele,

First of all, I would like to encourage everyone who uses a webwork forum (or another online forum for computer code) to always post a complete minimal working example (i.e., all of your code, not a snippet).  This makes it possible for other people to try to reproduce your problem without having to fill in what is missing by guessing.

Here's an inelegant solution that actually works: use <= for "less than or equal to" and >= for "greater than or equal to".  This solution is given below my signature.

I can think of another solution, but I don't know how to make it work right now.  In particular, we could try replacing <= by &le; and >= by &ge;  However, in the second part of this question, when you submit the correct answer the answer preview box at the top of the problem reports {\rm p &le; 1} as the correct answer, the popup goes back to "?" instead of staying on the correct answer, and (most importantly) the correct answer is not marked correct.  Also, there is another issue with this attempt at a bug fix: it disregards what the PG file will do when the student generates a PDF hardcopy (it will throw an error).  So, we would probably have to define a mode-specific command such as $LEQ that will render as &le; in html mode and as \leq in PDF mode (which is rendered using LaTeX).

Best regards,

Paul Pearson

########################################
#  Working (though inelegant) example.

DOCUMENT();

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserPopUp.pl",
);
TEXT(beginproblem());

Context("Numeric");

$popup1 = PopUp(
["?","p > 1","p > 0","p < 1","p >= 1"],
"p > 1",
);
$popup2 = PopUp(
["?","p <= 1","p > 1","p < 1","p > 0"],
"p <= 1",
);

##############################################################
#
# Text
Context()->texStrings;
BEGIN_TEXT
The infinite series \( \sum\limits_{n=1}^\infty \dfrac{1}{n^p} \) is called a $BBOLD p-series. $EBOLD $BR
(a) The p-series converges if \{ $popup1->menu() \}
$BR$BR
(b) The p-series diverges if \{ $popup2->menu() \}
END_TEXT
Context()->normalStrings;

##############################################################
# Answers
install_problem_grader(~~&std_problem_grader);
$showPartialCorrectAnswers = 0;
ANS( $popup1->cmp() );
ANS( $popup2->cmp() );

ENDDOCUMENT();
In reply to Paul Pearson

Re: Math mode in popup menus

by Paul Pearson -
Hi Michele,

Another solution would be to make the question more open ended by using actual inequalities as answers, such as in the following PG code.

Best regards,

Paul Pearson

############ begin PG code

DOCUMENT();

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"contextInequalities.pl",
"AnswerFormatHelp.pl",
);
TEXT(beginproblem());

Context("Inequalities")->variables->are(p=>'Real');

$answer1 = Compute("p > 1");
$answer2 = Compute("p <= 1");

##############################################################
#
# Text
Context()->texStrings;
BEGIN_TEXT
The infinite series \( \sum\limits_{n=1}^\infty \dfrac{1}{n^p} \) is called a $BBOLD p-series. $EBOLD $BR
(a) The p-series converges if \{ $answer1->ans_rule(20) \} \{ AnswerFormatHelp("inequalities") \}
$BR$BR
(b) The p-series diverges if \{ $answer2->ans_rule(20) \} \{ AnswerFormatHelp("inequalities") \}
END_TEXT
Context()->normalStrings;

##############################################################
# Answers
#install_problem_grader(~~&std_problem_grader);
$showPartialCorrectAnswers = 1;
ANS( $answer1->cmp() );
ANS( $answer2->cmp() );

ENDDOCUMENT();
In reply to Paul Pearson

Re: Math mode in popup menus

by Joel Trussell -
This looks quite interesting for the various transform methods that we use in signal processing, where we are interested in region of convergence. Can you elaborate on the use of inequalities? e.g., 
1) can we use calculated quantities, p < $r
2) double sided $r1 < p < $r2
3) are the following equal  0<= p < $r1  and p < $r1
In reply to Joel Trussell

Re: Math mode in popup menus

by Davide Cervone -
You can read about inequalities in the POD documentation for the contextInequailities.pl macro file.

To answer your questions:

  1. Yes, you can use Compute("p < $r") (provided you have added the variable "p" to your context).

Yes you can use Compute("$r1 < p < $r2") or Compute("$r1 <= p < $r2") and so on. You can even use Compute("$r1 <= p and p < $r2"), or Compute("p < $r1 or p > $r2").

No, p < $r1 is equivalent to the interval (-infinity,$r1), while 0 <= p is the interval [0,$r1). These are not equal.

There are a couple of things to keep in mind. First, inequalities are a special way of specifying intervals, so the variable used is not taken into account (so x > 2 is the same as y > 2). If you want the variable to count, you need to use a custom checker, such as

    Context("Inequalities-Only");
    Context()->variables->add(y => 'Real');
    
    $I = Compute("x < 5");
    ...
    ANS($I->cmp(checker => sub {
      my ($correct,$student,$ans) = @_;
      return $correct == $student && $correct->{varName} eq $student->{varName};
    }));
Here x < 5 will be marked correct, but y < 5 will not. You could add code to give a hint like "You variable is not the correct one" if the variables don't match rather than just marking it incorrect.

Of course, it is not all that convenient to have to add that to each inequality, so you could use

    Context("Inequalities-Only");
    Context()->{cmpDefaults}{Inequality}{checker} = sub {
      my ($correct,$student,$ans) = @_;
      return $correct == $student && ($correct->{varName}||"") eq ($student->{varName}||"");
    };
    Context()->{cmpDefaults}{Inequality}{list_checker} = sub {
      my ($correct,$student,$ans) = ($_[2]->{correct_value},$_[2]->{student_value},$_[2]);
      my ($score,@errors) = $correct->cmp_list_compare(@_);
      $score = 0 if $score && $correct->{varName} ne $student->{varName};
      return ($score,@errors);
    };
    Context()->{cmpDefaults}{Inequality}{list_type} = "an Inequality";
so that every inequality uses the custom checker. Here we also add a list_checker since sets and unions are implemented as lists, so this is needed for answers like x = 5, or x < 1 or x > 5.

This stuff probably should be made available in the contextInequalities.pl file, but they currently aren't, but you could make your own macro file that does this (or better creates a copy of the Inequalities-Only context and modifies that).

To handle the issue of negative numbers, you could use

    Context()->{cmpDefaults}{Inequality}{checker} = sub {
      my ($correct,$student,$ans) = @_;
      return $correct == $student unless $correct->type eq "Interval";
      $correct = $correct->intersect("$correct->{varName} >= 0")
        if $correct->{leftInfinite} && $correct->{data}[1]->value > 0;
      $student = $student->intersect("$student->{varName} >= 0")
        if $student->{leftInfinite} && $student->{data}[1]->value > 0;
      return $correct == $student  && $correct->{varName} eq $student->{varName};
    };
instead, which prevents intervals from extending past 0.
In reply to Paul Pearson

Re: Math mode in popup menus

by Davide Cervone -
WeBWorK uses the native browser menus, and you can't use HTML layout within them, so can't include images or MathJax output in the menus. That means no math, and basically only standard ASCII characters. Technically, it is possible to put Unicode characters into browser menus, but WeBWorK isn't really set up for that. For one thing, the pop-up object needs to be able to produce both a TeX and an HTML version of the menu items, and that is harder if you use arbitrary Unicode characters. In fact, my attempts to test that cause the problem to fail to compile (error message indicating the use of require, so I'm assuming Perl is trying to load Unicode support somewhere along the line, but that is prevented within the restricted "safe" compartment where the problem runs).

Paul's suggestion of using &ge; falls prey to this problem, as it is an HTML-only solution, which accounts for the problems he had with the correct answer display (which is TeX). Also, the return value from the browser will have converted the &ge; into the actual unicode character U+2265 (≥), but since the "correct" answer includes the HTML entity rather than the actual character, they don't match and so you don't get the answer marked correct, and the system won't fond one of the choices that it equals, so you are left with the "?" choice as the default.

Now that WeBWorK uses jQuery and some other javascript libraries, it might be possible to use an HTML-based menu system rather than the browser's native ones, and that could allow math to be included, but that would require some considerable rewriting of the pop-up objects.