Modifying WeBWorK library problems that are not PreTeXt-compatible

35 views
Skip to first unread message

Sean Fitzpatrick

unread,
Feb 17, 2023, 5:07:00 PM2/17/23
to PreTeXt support
I'm working on an update for my linear algebra notes.

I'd like this to become a Runestone book, and as part of that, I am taking the WeBWorK problems I used to assign separately (on our WeBWorK server) and putting them into the book.

Of course, around a third of these are not PreTeXt-compatible.

Are there particular things I should look for that would tell me a problem is not going to work with PreTeXt? (and that I possibly could modify?)

An example is the problem at 
Library/Hope/Multi1/03-02-Vector-subspaces/Subspaces_zero_09.pg

I think in this case, the drop-down selection is the thing that doesn't work.

I'm considering re-writing this so that the parts using drop-down become Runestone multiple-choice, and the remaining parts are WeBWorK, but I don't know how feasible this is.

Alex Jordan

unread,
Feb 17, 2023, 6:22:40 PM2/17/23
to pretext...@googlegroups.com
Use something like this, but pointed at your own server (change the
domain appropriately) and host course (change the courseID
appropriately):

https://webwork.uleth.ca/webwork2/html2xml?&problemSeed=1&answersSubmitted=0&displayMode=PTX&courseID=anonymous&userID=anonymous&course_password=anonymous&outputformat=ptx&sourceFilePath=Library/Hope/Multi1/03-02-Vector-subspaces/Subspaces_zero_09.pg

If using a browser, view the source. In this case, I see:
<p><OL></p>

And the problem file here:
https://github.com/openwebwork/webwork-open-problem-library/blob/main/OpenProblemLibrary/Hope/Multi1/03-02-Vector-subspaces/Subspaces_zero_09.pg

seems to be using these things from unionLists.pl. I haven't looked
into it, but probably no effort was made to make unionLists give PTX
output.

Options:
* Make unionLists give good PTX output. (If so, please in a way that
gets distributed, which will be tricky because they are reorganizing
macros right now.)
* Edit this OPL problem to use PGML.
* Code the exercise in PTX source.
* Don't use that exercise.

All of the options take some labor.

The next problem file you hit may have a different issue, but you can
use a URL like the above as one way to quickly peek at the actual PTX
static version. (There are other ways too, but I've settled on this
one in my own workflow.)
> --
> You received this message because you are subscribed to the Google Groups "PreTeXt support" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pretext-suppo...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/3c5fe507-8b94-4dc2-b66c-9aa5c805fe88n%40googlegroups.com.

Sean Fitzpatrick

unread,
Feb 17, 2023, 6:57:27 PM2/17/23
to pretext...@googlegroups.com
I might try to write a version of these in PTX source.
But I'm stuck on how to deal with things like answer checkers.

E.g. this problem, which is Library/NAU/setLinearAlgebra/span.pg (source
below) has two custom answer checkers.

In ptx source I want to put something like <var name="$answer" width="20"/>
but in the PG source, we have first:

$answer->ans_array(5)

and later, after END_TEXT,

ANS( $answer->cmp( checker=>~~&mycheck ) );

I think the ans_array brings in a 2x2 array of answer boxes, which I
don't think we support.

So this would probably have to be redone from scratch?



## DBsubject(Linear algebra)
## DBchapter(Abstract vector spaces)
## DBsection(Span)
## Date(10/5/2013)
## Institution(NAU)
## Author(Nandor Sieben)
## Level(2)
## MO(1)
## KEYWORDS('linear algebra','span')

DOCUMENT();
loadMacros(
  "PGstandard.pl",
  "MathObjects.pl",
  "parserMultiAnswer.pl",
  "AnswerFormatHelp.pl",
  "MatrixReduce.pl",
  "rank.pl",
  "PGcourse.pl"
);
$showPartialCorrectAnswers = 1;
TEXT(beginproblem());

Context("Fraction");
Context() -> parens -> set ("[" => {formMatrix => 1});
{
$a11= random(-5,5,1);
$a12= random(-5,5,1);
$a22= random(-5,5,1);
$b11= random(-5,5,1);
$b12= random(-5,5,1);
$b22= random(-5,5,1);
Context() -> parens -> set ("[" => {formMatrix => 1});
$A = Matrix([[$a11,$a12],[$a12,$a22]]);
$B = Matrix([[$b11,$b12],[$b12,$b22]]);
redo if(rank(Matrix([[$a11,$a12,$a22],[$b11,$b12,$b22],[0,0,0]]))<2);
}
$answer = $A+$B;
$answer = $A-$B if (rank($answer) == 0);

{
$c1 = Compute(random(-2,2,1));
$c2 = Compute(random(-2,2,1));
$c3 = Compute(1);
Context() -> parens -> set ("[" => {formMatrix => 1});
$answer2=Matrix([[$c1,$c3],[$c3,$c2]]);
redo if (rank(Matrix([$a11,$a12,$a22],[$b11,$b12,$b22],
[$answer2->element(1,1),$answer2->element(1,2),$answer2->element(2,2)]))
== 2);
}

sub mycheck {
  my ($correct, $student, $ansHash) = @_;
  if ( ! $student->is_symmetric )
    { return 0; }
  if ( rank(Matrix($student)) == 0 )
    { return 0; }
  if (rank(Matrix([$a11,$a12,$a22],[$b11,$b12,$b22],
[$student->element(1,1),$student->element(1,2),$student->element(2,2)]))
== 2) {
    return 1;
  }
  return 0;
}

sub mycheck2 {
  my ($correct, $student, $ansHash) = @_;
  if ( ! $student->is_symmetric )
    { return 0; }
  if (rank(Matrix([$a11,$a12,$a22],[$b11,$b12,$b22],
[$student->element(1,1),$student->element(1,2),$student->element(2,2)]))==3)
{
    return 1;
  }
  return 0;
}


Context()->texStrings;
BEGIN_TEXT
Let \(V\) be the vector space of symmetric \(2\times 2\) matrices and
\(W\) be the subspace \[W=\operatorname{span}\left\{ $A,$B \right\} .\]

a. Find a nonzero element \(X\) in \( W \).
$BR
\( X = \)
\{ $answer->ans_array(5) \}

$BR
$BR

b. Find an element \(Y\) in \( V \) that is not in  \( W \).
$BR
\( Y = \)
\{ $answer2->ans_array(5) \}

END_TEXT
Context()->normalStrings;

ANS( $answer->cmp( checker=>~~&mycheck ) );
ANS( $answer2->cmp( checker=>~~&mycheck2 ) );



ENDDOCUMENT();

Alex Jordan

unread,
Feb 18, 2023, 1:09:25 AM2/18/23
to pretext...@googlegroups.com
You can make the answer MathObject first, and then get its cmp method
to be in the PTX answer blank. There are examples in the sample
chapter like this one:
https://github.com/PreTeXtBook/pretext/blob/master/examples/webwork/sample-chapter/sample-chapter.xml#L232

Those examples are using answer hints, but you don't need that part.
Just something like:
$evaluator = $answer->cmp();

And then later:
<var name="$answer" evaluator="$evaluator" width="20"/>
or even just:
<var name="$evaluator" width="20"/>


You can use @form=array and it should work now (for the past roughly 2
months). So like;
<var name="$evaluator" form="array"/>

If you also specify a width, it should apply to each entry in the
array. Although that doesn't matter much if you are using MathQuill
now.


On Fri, Feb 17, 2023 at 3:57 PM Sean Fitzpatrick
> To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/c6ed0d94-91c3-9fbd-c4aa-48fa8786556c%40gmail.com.

Sean Fitzpatrick

unread,
Feb 18, 2023, 9:36:12 AM2/18/23
to pretext...@googlegroups.com
Thanks. I'll try this and see how it goes.

A lot of the problems I'm trying to modify have custom answer checkers because you want the correct answer to be any element of a substance, rather than a particular one.

So this will be a bit beyond my current WeBWorK programming ability, but I do have some time next week.

Alex Jordan

unread,
Feb 18, 2023, 12:09:44 PM2/18/23
to pretext...@googlegroups.com
Generally with that kind of exercise, you can design the matrix whose null space is the space where the student answer should come from. Then check the student answer is nonzero and the matrix-vector product is 0. You can do it all elegantly using Math objects. On the wiki, familiarize yourself with Matrix methods and Vector methods.

Sean Fitzpatrick

unread,
Feb 22, 2023, 1:56:32 PM2/22/23
to PreTeXt support
So far I've been fairly successful with converting existing problems to PGML.
(Many of these use MathObjects, but also have custom answer checkers that are 20-30 lines of code, so I think this is more likely to succeed than trying to code from scratch.)

One place where I can't get valid PGML is when  problem uses an answer array for a matrix.
Since there are custom checkers, doing [____]*{$ans} doesn't work.
I can get valid PG by doing [@ $ans->ans_array(4) @]* and having an ANS evaluator after the PGML.
But this doesn't give valid PTX.

My workaround for now is to use [@ $ans->ans_rule() @]*, since my students will be familiar with the [[a,b],[c,d]] syntax for entering matrices.

As far as writing my own:

I got stumped on the process for passing a student answer as a variable.

As a simple example: say I want a student to enter an example of an idempotent matrix.
I think I have to initialize, and then pass to a formula?

Something like 

$M = Matrix([[1,2],[3,4]]);
$f = Formula("M*M-M");
$zer = Matrix([[0,0],[0,0]]);

($M will be the student answer, but it has to be set to something initially, I think.)

and then
BEGIN_PGML
Enter a [` 2\times 2 `] idempotent matrix.
[____]
END_PGML

and below the PGML, define an answer checker that returns 1 if $f==$zer, and 0 otherwise,
then
ANS($M->cmp(checker->my_check));

But probably there is a better way to do this.

Sean Fitzpatrick

unread,
Feb 22, 2023, 1:57:24 PM2/22/23
to PreTeXt support

OK, this works. Except you have to make sure that the initial value for $M is correct:

Context("Matrix");

$M = Matrix([[1,0],[0,1]]);

$zer = Matrix([[0,0],[0,0]]);
$f = Formula("$M*$M-$M");

$ans = $M->cmp(
    checker => sub {

        my ($correct, $student, $ansHash) = @_;
        my $M = $student->value;
        return ($zer == $f ? 1 : 0);
    }
);

BEGIN_PGML
Input a [` 2\times 2 `] idempotent matrix.

[_____]*{$ans}
END_PGML

Alex Jordan

unread,
Feb 22, 2023, 2:09:49 PM2/22/23
to pretext...@googlegroups.com
Your recent inquiries have made us WW developers aware that:

[_]*{$cmp}

does not work as expected, when $cmp is an AnswerEvaluator object for
something like a matrix which should make an array of answer blanks.
It's not clear to me if this is a bug, or just a feature that was
never implemented. But Glenn is making it work for the next version.

So now I'm confused if you are saying the above is working for you. By
my understanding, it would work for the custom answer checking, but be
giving you only a single input field to type the matrix using next
brackets.




On Wed, Feb 22, 2023 at 10:57 AM Sean Fitzpatrick
> To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/6435cfc9-b434-4556-a9e0-be9889b8c7bdn%40googlegroups.com.

Sean Fitzpatrick

unread,
Feb 22, 2023, 3:13:30 PM2/22/23
to PreTeXt support
I mean it is working, with the result being a single answer blank, with expected input in the format [[1,0],[0,1]].
It doesn't work if I want to produce an answer array.

But any time I've produced a WW problem that does have an answer array, I don't get valid PTX.

So for now I am just producing a single answer blank. This is for a course where students will be using Python, so they are familiar with the syntax for entering a matrix.

Alex Jordan

unread,
Feb 22, 2023, 3:17:39 PM2/22/23
to pretext...@googlegroups.com
> But any time I've produced a WW problem that does have an answer array, I don't get valid PTX.

It should work though. Consider:
Exercise 10.6: Answer Arrays
https://pretextbook.org/examples/webwork/sample-chapter/html/section-10.html#exercise-37

Could the invalid PTX in those cases be unrelated to an array of inputs?

Or be tied up with this issue of custom answer checkers being in play?


On Wed, Feb 22, 2023 at 12:13 PM Sean Fitzpatrick
> To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/db7dbe5a-bda0-425f-93ea-a5f809d7b220n%40googlegroups.com.

Sean Fitzpatrick

unread,
Feb 22, 2023, 3:23:55 PM2/22/23
to PreTeXt support
If I had a problem without a custom answer checker, where the syntax [___]*{$ans} works to produce an answer array, I would get valid PTX, presumably.
But at the moment I don't have any such problems in use.

When an answer checker is in use, I can use the syntax [@ $ans->ans_array(4) @]* to get an answer array, but I do not get valid PTX.
Changing this to [@ $ans->ans_rule(10) @]* gives me valid PTX with no other changes to the .pg file.

Sean Fitzpatrick

unread,
Feb 22, 2023, 8:01:38 PM2/22/23
to PreTeXt support
Hmm...

Now I wonder if maybe I need to do something on my server, or if arrays only work when authored in PTX.

Here is my example: Library/Hope/Multi1/04-01-Linear-transformations/Lin_trans_20.pg

I've converted this to PGML (see below). There are no answer checkers in use for this one.

With the .pg file as below, I get valid PTX.
If I change [_____]{$AX1} to [_____]*{$AX1}, I no longer get valid PTX, although I do get an answer array as expected in WeBWorK.
My server for this is up-to-date 2.17. Maybe I need to be on a development branch?

Updated version:

## DESCRIPTION
## Linear transformations
## ENDDESCRIPTION

## DBsubject(Linear algebra)
## DBchapter(Linear transformations)
## DBsection(Properties)
## Date(July 2013)
## Institution(Hope College)
## Author(Paul Pearson)
## Level(3)
## TitleText1('Multivariable Mathematics')
## AuthorText1('')
## EditionText1('')
## Section1('.')
## Problem1('')
## KEYWORDS('linear transformations')


DOCUMENT();
loadMacros(
  "PGstandard.pl",
  "MathObjects.pl",
  "parserVectorUtils.pl",
  "parserMultiAnswer.pl",
  "contextLimitedVector.pl",
  "parserPopUp.pl",
  "PGML.pl",
  "PGchoicemacros.pl",
  "PGcourse.pl"
);
TEXT(beginproblem());
$showPartialCorrectAnswers = 1;
$refreshCachedImages = 1;

Context("Matrix");
Context()->noreduce('(-x)-y');

@w = (2..7);
@shuff = shuffle(6);
@w = @w[@shuff];
unshift(@w,'1');

# w[7] through w[9]
push(@w, random(-5,-2,1) );
push(@w, random(2,4,1) );
push(@w, random(5,7,1) );


@a = ();
foreach my $i (1..3) {
  foreach my $j (1..2) {
    $a[$i][$j] = non_zero_random(-5,5,1);
  }
}

$A = Matrix([
[ $a[1][1], $a[1][2] ],
[ $a[2][1], $a[2][2] ],
[ $a[3][1], $a[3][2] ],
]);


$X1 = Matrix([
[ -1*$w[1] ],
[ $w[2] ]
]);

$AX1 = $A * $X1;

@b = ();
foreach my $i (1..2) {
  foreach my $j (1..3) {
    $b[$i][$j] = non_zero_random(-5,5,1);
  }
}

$B = Matrix([
[ $b[1][1], $b[1][2], $b[1][3] ],
[ $b[2][1], $b[2][2], $b[2][3] ],
]);

$X2 = Matrix([
[ $w[3] ],
[ $w[4] -1*$w[6] ],
[ -1*$w[5] ],
]);

$BX2 = $B * $X2;

@c = ();
foreach my $i (1..2) {
  foreach my $j (1..3) {
    $c[$i][$j] = non_zero_random(-5,5,1);
  }
}

$C = Matrix([
[ $c[1][1], $c[1][2], $c[1][3] ],
[ $c[2][1], $c[2][2], $c[2][3] ],
]);

$X3 = Matrix([
[$w[7]],
[$w[8]],
[$w[9]],
]);

$CX3 = $C * $X3;

$ve = vectorstyle("e");
$vv = vectorstyle("v");

Context()->texStrings;
BEGIN_PGML

* Suppose [` f : \mathbb{R}^{2} \to \mathbb{R}^{3} `] is a linear transformation such that
[```
f \left( \begin{array}{c} 1 \\ 0 \end{array} \right)
=
\left( \begin{array}{r} [$a[1][1]] \\ [$a[2][1]] \\ [$a[3][1]] \end{array} \right),
\quad
f \left( \begin{array}{c} 0 \\ 1 \end{array} \right)
=
\left( \begin{array}{r} [$a[1][2]] \\ [$a[2][2]] \\ [$a[3][2]] \end{array} \right).
```]
Then [`` f \left( \begin{array}{r} -[$w[1]] \\ [$w[2]] \end{array} \right) = ``][________]{$AX1}.

    (Enter your vectors using the format [|[[a],[b],[c]]|].)

* Suppose [` f : \mathbb{R}^{12} \to \mathbb{R}^{2} `] is a linear transformation such that
[```
f \left( \begin{array}{c} {[$ve]}_4 \end{array} \right)
=
\left( \begin{array}{r} [$b[1][1]] \\ [$b[2][1]] \end{array} \right),
\quad
f \left( \begin{array}{c} {[$ve]}_7 \end{array} \right)
=
\left( \begin{array}{r} [$b[1][2]] \\ [$b[2][2]] \end{array} \right),
\quad
f \left( \begin{array}{c} {[$ve]}_8 \end{array} \right)
=
\left( \begin{array}{r} [$b[1][3]] \\ [$b[2][3]] \end{array} \right).
```]
Then [`` f ( [$w[3]] {[$ve]}_4 + [$w[4]] {[$ve]}_7 ) - f ( [$w[5]] {[$ve]}_8 + [$w[6]] {[$ve]}_7 )= ``][________]{$BX2}

* Let [` V `] be a vector space and let [` {[$vv]}_1, {[$vv]}_2, {[$vv]}_3 \in V `].
Suppose [` T : V \to \mathbb{R}^{2} `] is a linear transformation such that
[```
T({[$vv]}_1) = \left( \begin{array}{r} [$c[1][1]] \\ [$c[2][1]] \end{array} \right),
\quad
T({[$vv]}_2) = \left( \begin{array}{r} [$c[1][2]] \\ [$c[2][2]]  \end{array} \right),
\quad
T({[$vv]}_3) = \left( \begin{array}{r} [$c[1][3]] \\ [$c[2][3]]  \end{array} \right).
```]
Then [` [$w[7]] T({[$vv]}_1) + T([$w[8]] {[$vv]}_2 + [$w[9]] {[$vv]}_3) = `][________]{$CX3}
END_PGML
Context()->normalStrings;

#ANS( $AX1->cmp );
#ANS( $BX2->cmp );
#ANS( $CX3->cmp );

COMMENT("Vectors are formated using the subroutine vectorstyle in pg/macros/customizeLaTeX (update your version of pg if you do not have this file). The subroutine can be overwritten in PGcourse.pl.");

ENDDOCUMENT();

Alex Jordan

unread,
Feb 26, 2023, 6:25:29 PM2/26/23
to pretext...@googlegroups.com
> I no longer get valid PTX
What PTX do you get?

If it's not clear from the error message, use a URL like:
https://YOURWEBWORKSERVER/webwork2/html2xml?&problemSeed=1&answersSubmitted=0&sourceFilePath=PATHTOTHISPGFIILE&displayMode=PTX&courseID=anonymous&userID=anonymous&course_password=anonymous&outputformat=ptx

where you should change
YOURWEBWORKSERVER
PATHTOTHISPGFIILE
and possibly the instances of
anonymous

Then when viewing that address in a browser, view source to see the PTX.

On Wed, Feb 22, 2023 at 5:01 PM Sean Fitzpatrick
> To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/60c0f0e6-985b-40a3-b0ef-a5a3c3454072n%40googlegroups.com.

Sean Fitzpatrick

unread,
Feb 26, 2023, 6:52:27 PM2/26/23
to PreTeXt support
Attached is the output in each case.

without_ans_arry.ptx: in this case, I have, for example, [________]{$AX1} for an answer blank.

Then I changed this, and the other two answer blanks, to [________]*{$AX1}.

I made no other changes, and refreshed the page using the URL 

You can see that making this change causes all sorts of span and div elements to be inserted around the answer blank.

Note: to avoid impacting anyone who might want to use this problem in the current version of my book, I've saved the version of this problem with answer arrays as a version "b".
So you should use the following URL to see the problematic version:

without_ans_array.ptx
with_ans_array.ptx

Alex Jordan

unread,
Feb 26, 2023, 7:38:46 PM2/26/23
to pretext...@googlegroups.com
You had it right, there is something in pg develop that is needed for
this. I'm sorry for not putting 2 and 2 together more quickly. Here is
the commit:
https://github.com/openwebwork/pg/pull/758/commits/e201a8a04dde7a85bae2d1094b663ecad9a5cddc

It is isolated to one file, only affecting PTX output. So if you would
like to have it now, you have that option. Otherwise this is in
develop ready for 2.18. (And of course I applied it early to the AIM
server.)

On Sun, Feb 26, 2023 at 3:52 PM Sean Fitzpatrick
> To view this discussion on the web visit https://groups.google.com/d/msgid/pretext-support/4bdf84e7-3456-4585-a84c-3c9ada652cbfn%40googlegroups.com.

Sean Fitzpatrick

unread,
Feb 27, 2023, 4:02:17 PM2/27/23
to pretext...@googlegroups.com
OK, thanks.

I will probably leave things as-is for now, since the audience for this
book should be comfortable with using matrix syntax rather than an array
of answer blanks.

Since I have a dedicated server for PreTeXt, I suppose I could also move
over to the development branch. Worst case scenario is something ends up
not working right in APEX somewhere. (There are no courses running on my
development server.)
Reply all
Reply to author
Forward
0 new messages