WeBWorK Problems

Converting from perl to webwork

Converting from perl to webwork

by Helena Verrill -
Number of replies: 3
I am trying to understand how to write problems for webwork.

1) Since webwork is based on perl, shouldn't something that runs in perl run in webwork? 

2) Is there some help on how to convert from a perl program to a webwork program?

3) My specific problem is the following.
I have a perl program, which does run:

#!/usr/bin/perl

sub gcd {
    my $a = shift;
    my $b = shift;
    my $u = shift;
    my $v = shift;
    my $uold = shift;
    my $vold = shift;
    my $q = shift;

    if ($b == 0)
    { 
       my @vec = ( $a, $uold , $vold);
       return \@vec;
    }
    $q = ($a - ($a % $b))/$b;   
    my $unew = $uold - $q * $u;
    my $vnew = $vold - $q * $v;
    return gcd($b, ($a % $b),$unew,$vnew,$u,$v,$q);
    }

#for ($j = 0; $j < 10; $j++){

#my $a=int(rand(100))+1;
#my $b=int(rand(100))+1;

$a = 43;
$b = 17;

if ($a < $b)
    {
    my $temp = $a;
    $a = $b;
    $b = $temp;
}

@thegcd = gcd($a,$b,0,1,1,0,0);
$g = $thegcd[0][0];
$u = $thegcd[0][1];
$v = $thegcd[0][2];
 if ($u < 0){
   $u=$u+$b;
   $v=$v-$a;
 }

print " a = ", $a, "  ";
print " b = ", $b, "  ";
print " g = ", $g, "  ";
print " u = ", $u, "  ";
print " v = ", $v, "  ";
print $a*$u + $b*$v;
print "\n";

#}

However, the almost identical code in webwork does not run.
Can someone help me work out what the difference is, and how to fix this?
Thanks!

Not an ARRAY reference at line 50 of [TMPL]/tmpEdit/webwork_extended_gcd_2.pg.verrill.tmp

Error details

        Problem1
ERROR caught by Translator while processing problem file:tmpEdit/webwork_extended_gcd_2.pg.verrill.tmp
****************
Not an ARRAY reference at line 50 of [TMPL]/tmpEdit/webwork_extended_gcd_2.pg.verrill.tmp

****************

------Input Read
1 ## DESCRIPTION
2 ## Extended euclidean algorithm
3 ## ENDDESCRIPTION
4
5 DOCUMENT();
6 loadMacros('PG.pl',
7 'PGbasicmacros.pl',
8 'PGchoicemacros.pl',
9 'PGanswermacros.pl'
10 );
11 TEXT(beginproblem());
12 $showPartialCorrectAnswers = 1;
13
14 sub gcd {
15 my $a = shift;
16 my $b = shift;
17 my $u = shift;
18 my $v = shift;
19 my $uold = shift;
20 my $vold = shift;
21 my $q = shift;
22
23 if ($b == 0)
24 {
25 my @vec = ( $a, $uold , $vold);
26 return \@vec;
27 }
28 $q = ($a - ($a % $b))/$b;
29 my $unew = $uold - $q * $u;
30 my $vnew = $vold - $q * $v;
31 return gcd($b, ($a % $b),$unew,$vnew,$u,$v,$q);
32 }
33
34 #for ($j = 0; $j < 10; $j++){
35 # $a = random(10,30);
36 # $b = random(10,30);
37
38 $a = 43;
39 $b = 17;
40
41 if ($a < $b)
42 {
43 my $temp = $a;
44 $a = $b;
45 $b = $temp;
46 }
47
48 @answer = gcd($a,$b,0,1,1,0,0);
49
50 $g = $answer[0][0];
51 $u = $answer[0][1];
52 $v = $answer[0][2];
53 if ($u < 0){
54 $u=$u+$b;
55 $v=$v-$a;
56 }
57
58 BEGIN_TEXT
59 gcd($a, $b) = \{ans_rule(5)\}
60 = $a \(\times \) \{ans_rule(5)\}
61 + $b \(\times \) \{ans_rule(5)\}
62 $PAR
63 END_TEXT
64
65 ANS(num_cmp($g));
66 ANS(num_cmp($u));
67 ANS(num_cmp($v));
68
69 ENDDOCUMENT();

In reply to Helena Verrill

Re: Converting from perl to webwork

by Michael Gage -
I can't guarantee this is the only problem in the code -- but here is one of them.

In the .pg language you need to use ~~@foobar to indicate a reference to an array foobar. This is because \ is reserved for all of the TeX commands. (Similarly you can't use $equation$ in TeX and must use \( equation \) instead.

One reference that might help in general is at:
http://webwork.dartmouth.edu/webwork_local_html/
WeBWorK Newbie Guide, ver 1.7 (its for an earlier version of
WeBWorK but still largely valid.)

Technically what happens is that every instance of \ in a .pg file is first replaced with \\ before any further processing happens. And then the ~~ are replaced with \. This preserves backslashes for TeX commands and allows one to create references to perl variables using ~~.

To add a bit to the confusion: if you were to put your code above in a macro file, say myMacros.pl, and load it into your problem it would work. In a .pl file (as opposed to a .pg file) the backslashes are not protected -- you can use them to create perl variable references and every TeX command in a string must have a doubled backslash e.g. "\\par".

The thinking is that in .pg files one uses lots of TeX commands but few perl references (unless you are creating a one-off subroutine). In the .pl macro files the reverse is true.

Hope that makes some sense.

--Mike
In reply to Helena Verrill

Re: Converting from perl to webwork

by Davide Cervone -
I suspect the problem is with the line
        return \@vec;
as WeBWorK usurps the use of the backslash. You need to replace normal Perl backslashes by two tildes (~~). So try using
        return ~~@vec;

As for your question 1, no, not every perl program will work in WeBWorK. WeBWorK has a preprocessor that it runs before passing the program to Perl, and when it does pass it to Perl it uses a restricted environment where not all Perl commands are allowed (iin particular, file access commands are not allowed, nor eval, or print, or several others). So there are lots of Perl things you can't do in a .pg file.

Davide

In reply to Davide Cervone

Re: Converting from perl to webwork

by Helena Verrill -
Thanks for both the replies.  After making the change of \@vec to ~~@vec
it works fine!