Web Conference Notes
Prep 2011 Main Page > Web Conference 1 > Conference Notes
Contents 
Notes from Web Conference 1
 Introduction to the workshop
 What WeBWorK problems are
 An Introduction to problem authoring
 WeBWorK is a Perl application, with layers on top of that. These layers are
 PG, the problem generating language, and
 MathObjects
Therefore we start thinking about writing problems for WeBWorK using Perl.
Perl
Basic Ideas from Perl
 The pound sign indicates a comment: anything in a line after a # sign is ignored by Perl.
 Any line of code must be ended with ;, a semicolon.
Perl Datatypes
Basic datatypes in Perl:
 Scalar: We define a scalar variable with a $ prepending the name of the variable. Thus
$astring = "this is a string"; $anumber = 5;
define scalar variables which are, respectively, the string "this is a string" and the number 5.
 Array: arrays are defined with a @ prepending the name of the variable. Thus
@strarray = ( "string1", "string2", "string3" ); @numarray = ( 1, 2, 2.71828, 3.1415 );
define, respectively, an array of strings and of numbers. Note that arrays may mix strings and numbers in their elements.
 Array elements: Array elements are scalars, so we access them by using a dollar sign:
$strarray[2];
will return the value "string3" (because arrays are indexed from 0).
 Array slices: We can also create a new array that is defined from elements of another array:
@newarray = @strarray[1..2];
will define (given the definition of @strarray above) an array which is the same as the definition
@newarray = ( "string2", "string2" );
 Hashes: there are also associative arrays in Perl, which we don't discuss here.
Perl Mathematics
Perl supports the arithmetic operations we would expect: +, , *, /, ** (which is exponentation), and % (which is modulo, or remainder)
Things to be careful about:
 ^ does not exponentiate; it's a bitwise shift, which isn't what we want.
 something like
5  3
will work, but53
will invoke the decrement operator
, which is not what we (necessarily) expect.  fractional exponents require some care as well:
(3)**(2/3)
will not work, while((3)**(2))**(1/3)
will.
Perl also has named functions: sin(2)
returns the sine of 2, etc: functions include
 sin
 sqrt
 exp
 log (is the natural log)
 ln (is also)
 logten
 abs
Relational Operators
To test whether things are equal to each other, or greater or less than each other:
 For numbers, we use the operators
==
to test equality,!=
to test inequality, and>
,>=
,<
, and<=
as expected. These all return 1 (for true), and 0 (for false).  For strings, we use the operators
eq
for equality andne
for inequality.
We can combine tests by using && for and and  for or: thus
(3 == (2+1)) && ("one" eq "two")
is false (0), while
(3 != (4+1))  ("one" eq "one")
is true (1).
Flow Control
We can control how a Perl script executes by using conditional and looping statements.
Conditional Statements
The basic conditional statement is if
then
:
$a = 3; if ( $a == 3 ) { $b = 4; }
will define the variable $b to be 4. Similarly,
$a = 3; if ( $a == 4 ) { $b = 3; } else { $b = 2; }
will define the variable $b to be 2. Finally, we can use elsif
for additional conditions:
$a = 3; if ( $a == 4 ) { $b = 3; } elsif ( $a == 3 ) { $b = 2; } else { $b = 1; }
will define $b to be 2.
Loops
There are three basic ways to set up a loop: the first iterates over a variable that we define to keep track of where we are in the loop:
$n = 4; for ( $i=1; $i<5; $i++ ) { $n = $n + $i; }
will result in $n having the value 14.
We can also iterate over elements in an array:
@evens = (); foreach my $i ( 0..50 ) { $evens[$i] = 2*$i; }
will define the array @evens to be the even numbers between 0 and 100, inclusive. Two additional notes here:

my
localizes the value of the variable to the block in which loop is defined: thus the definition of the variable $i in this loop will not change any value of $i that already existed; and  the notation
( 0..50 )
is the same as that we used in the array slice, and returns the values between 0 and 50 inclusive.
Finally, we can do
until
:
$a = 3; do { $a = $a + 1; } until ( $a == 10 );
Will loop through adding one to the variable $a
Problem Authoring
WeBWorK problems are written in the PG language. PG was developed by Mike & Arnie, and is the language that we use to write problems. It includes a number of macros that are provided "on top" of Perl
Thus, every problem file is a Perl script that uses the language that Perl provides plus a number of additional macros (functions) that allow us to create problems.
MathObjects were written by Davide Cervone to extend PG. They have the advantages that they
 correct some Perl quirks
 make writing problems easier
 provide more macros
 make answer checker feedback better for students
Thus, when we author a problem we create a PG file, which should always have a standard format. It should contain the sections:
 Tagging info (for indexing of the NPL)
 Initialization (loading macros, etc)
 Setup (defining parameters, etc)
 Main Text (what students see)
 Answer evaluation (checking the submitted answers)
 Solution (optional) and end document (mandatory)
A Sample Problem File
Notes About the Sample Problem File
 The Tagging section of the file defines metadata that may be used to categorize the problem if it is added to the National Problem Library.
 The Initialization section loads macros that are to be used, and defines the initial information about the problem.
 When loading macros, the default should be to load the macro files
PGStandard.pl
, andMathObjects.pl
. There may be other macros that will be needed; this will be clear as we author other problem types.  The
TEXT(beginproblem());
line does a number of things, including setting the problem number on the page.
 When loading macros, the default should be to load the macro files
 The Problem SetUp section defines what we need to know to set up the problem, including the variables that will be randomly determined for each student, and other data that are needed for the problem.
 Note that it is worth avoiding overrandomization. Try to make the problem generate values that you would want to work by hand.
 The Text section of the problem defines what the student sees when s/he views the problem.
 The Text section is delimited by
BEGIN_TEXT
andEND_TEXT
. Between these delimiters, we are in Text mode rather than in Pel. In this mode we can use LaTeX to display mathematics. This is discussed more below.
 The Text section is delimited by
 The Answer Evaluation section defines how the student's answer is checked.
 Note that all MathObjects have a
cmp
method, which allows us to check a student's answer.  We embed this comparison in the
ANS
macro, which then records the correctness of the student's answer in the WeBWorK database.
 Note that all MathObjects have a
 The Solution and Enddocument section gives a full solution (if any) to the problem, and puts in the allimportant
ENDDOCUMENT()
command. In this section, the
COMMENT();
command include a comment that will be displayed in the Library Browser when a professor views the problem there.  Be sure to end every PG file with the
ENDDOCUMENT();
command.
 In this section, the
Text
A few notes about text mode. We embed mathematics in the text that is shown to the student with the notation \( \)
(to embed an equation inline) or \[ \]
(to put the equation in display mode).
We can also embed Perl commands in the text section by using \{ \}
: this executes the code between the braces. Note that this is how we embed answer blanks in the problem.
MathObjects
In Perl, we can define a string:
$f = "sin(x)";
but the MathObject defined by
$f = Formula("sin(x)");
is an object that knows a lot about what the function is. Thus we can do all of the following:
$f>eval(x=>5); # plug 5 in for x $f>D('x'); # differentiate wrt x $g = Formula("sin(x) + 4")>reduce(); # simplifies $g to sin(x)  4
And MathObjects can produce TeX output:
BEGIN_TEXT What is the derivative of \( $f>TeX() \)? END_TEXT
As we saw before, they can check student answers, too:
ANS( $f>cmp() );
More Perl: note that

$f>D()
calls the method called "D" of the MathObject $f. (A method is a function associated with the object.) 
x=>5
defines an association between x and 5; this is really an associative array definition, which we didn't discuss before.
Contexts
MathObjects live in a Context, which defines the way MathObjects are interpreted. Thus we can have
Context("Numeric"); $f = Formula("sin(x^2)");
which defines the Context in which the MathObjects that are defined to be numeric. This is the most common Context. We can modify the Context:
Context()>texStrings; BEGIN_TEXT Find the derivative of \( $f \). $BR \{ ans_rule(20) \} END_TEXT Context()>normalStrings();
Note that:
 The caret ^ works in MathObjects
 When we changed to texStrings in the Context, we got
$f>TeX()
by default  We have to change back to normalStrings after this for the ANS() to work.
Another way to modify Contexts is to add variables:
Context("Numeric")>variables>add( y=>"Real" ); $f = Formula("x^2 + y^2");
or
Context("Nuumeric"); Context()>variables>are(t=>"Real"); $g = Formula("sin(t+pi)");
If we put these sequentially in the file, the second Context() call will reset the Context, and we then explicitly note that t is the only variable.
Note that:
 By default,
Context("Numeric");
sets up a Context with one variable, x.
We can also modify Contexts by disabling operators or functions:
Context("Numeric"); Context()>operators>undefine("^","**"); Context()>functions>disable("Trig"); Context()>functions>disable("exp"); $f = Formula("x^2"); # will return an error $g = Formula("sin(x)"); # will return an error
Note:
 Disabling functions or operators will mean that they are unavailable for both instructors (defining the problem) and students (providing answers).
 We might want to do this if we are writing a problem where we want a student to enter a value rather than what a function returns, e.g., sqrt(3)/2 instead of sin(pi/3)
More Context modification: we may need to set the domain for a problem:
Context("Numeric"); Context()>variables>set( x => {limits=>[2,5]} ); $g = Compute("sqrt(x1)");
This becomes important because of the way WeBWorK checks answers: it numerically evaluates the correct and student's answer at a set of points (say, 10), and requires that the values be equal at each. This, however, requires that the values picked for comparison be in the expected domain.
We note that this is a very robust way of checking formula answers.
We can also set the domain without modifying the Context:
Context("Numeric"); $f = Compute("sqrt(x)"); $f>{limits} = [2,5]; $g = Compute("e^(20x)"); $g>{limits} = [.25,.25];
Note that:
 Compute generates a MathObject for you: it picks the most likely type of MathObject for you, and has the very desirable characteristic that it preserves the format of the answer you enter for display to the student. This is very desirable.
 The second domain issue here is a little more subtle: something like this exponential needs to be evaluated on a small x domain if the numerical values are to be easy to evaluate