## WeBWorK Problems

by Michael Gallis -
Number of replies: 4
I use WeBWorK (currently version 2.2.1) for my physics courses, and I was trying to develop a custom answer evaluator for ranking tasks. Students would rank items (such slopes at points on a graph, or numerical answers) . For example, if A=1, B=3, C=5 and D=3 students would input C>B=D>A or C>D=B>A (either acceptable). The ranking would be randomly generated for each student.

I spent a bit of time playing with Perl and decided that using hashes and built in hash/list tools would be the way to go. I developed some snippets that seemed to do the tasks I needed, but when I tried them within a trial problem, I got caught with this message:
'sort' trapped by operation mask at line 30 of (eval 1433)
which seemed to tell me that the sort operation in use
30 foreach $key (sort mrg_hashValueAscendingNum (keys(%rankingtask_scores))) { 31$rankingtask_item_order{$key}=$order;
32 $order=$order+1;
33 }
was not allowed in .pg

Which (finally) brings me to my questions:
• Am I reinventing the wheel? Are already question and evaluator styles and mechanisms that do what I am trying to do, but called something else? I didn't see any likely candidates in the wiki, cut could easily have missed.
• Is it possible to get sort to work within a question and/or within an answer evaluation?
• Is there any heavier duty tutorials on writing answer evaluators? I keep running into the old doc's from 1.6 and I'm not sure everything works the same.
Thanks
-Mike Gallis

by Michael Gage -
sort itself is not allowed in .pg since it could cause
denial-of-service problems it was misused. There is a PGsort however which (supposedly) protects against this.

in PGbasicmacros.pl you have

Usage:
lex_sort(@list); # outputs list in lexigraphic (alphabetical) order
num_sort(@list); # outputs list in numerical order
uniq( @list); # outputs a list with no duplicates. Order is unspecified.
PGsort( \&sort_subroutine, @list);
# &sort_subroutine defines order. It's output must be 1 or 0 (true or false)
One of these will solve your immediate problem.

We're working on better tutorials (everyone welcome to help :-) ). The PG macro/library link in the wiki's Author's guide page is a very useful addition. There is also a database of almost all known PG macros at https://webwork.maa.org/moodle/mod/data/view.php?id=194

For the most part what you find in the 1.6 tutorials will still work in the current WeBWorK, but often there is a better way to do things -- particularly if you can put Davide Cervone's MathObjects to use.

In this particular case there might be some MathObjects (contextInequalities.pl) that would help evaluate simple equations. See the thread between Robin Cruz and Davide Cervone https://webwork.maa.org/moodle/mod/forum/discuss.php?d=5872

It's likely that using them will make the problem easier to write and to maintain.

-- Mike

by Michael Gallis -
Thanks, those pointers are VERY useful. Unfortunately I'm still running into a sort of a sort problem.

The PGsort looks like it should be just what I need, but I seem to be having trouble getting it to work. Using the code snipet (adapted from the example at http://webhost.math.rochester.edu/webworkdocs/docs/pglanguage/manpages/pg_sort/)
in a problem:

$A = join(" ",PGsort( sub {$_[0] <=> $_[1]} ,(23,2,10,11,11,31) ) ); BEGIN_TEXT$A $BR END_TEXT the result is 31 11 11 10 2 23 which is just the reverse order of the original list. I've gotten similar results from other experiments with PGsort, which at least suggests to me that PGsort isn't getting or using the sort routine correctly. Is it possible that my older version of WebWorK (2.2.1) has a buggy version of PGsort? I am trying to use a hash to sort, along the lines of PGsort( sub {$myhash{$_[0]} <=>$myhash{\$_[1]}} , @mylist )
which I've gotten to work in perl test scripts using perl's native sort.

Thanks for any directions you can provide.

-Mike Gallis

by Davide Cervone -
The problem is that PGsort doesn't expect the subroutine to return the result of the <=> operator, but rather just 1 or 0 depending on whether the first is less than the second or not. This is documented in
near the bottom (look for "Sorting and other list macros"). I'm not sure why they decided to do it that way, but that is the way it works.

Davide