Difference between revisions of "Web Conference Notes"

From WeBWorK_wiki
Jump to navigation Jump to search
Line 6: Line 6:
 
* What WeBWorK problems are
 
* What WeBWorK problems are
 
* An Introduction to problem authoring
 
* An Introduction to problem authoring
** WeBWorK is a Perl application, with layers on top of that. Therefore we start thinking about writing problems for WeBWorK using Perl.
+
** WeBWorK is a Perl application, with layers on top of that. These layers are
*** Perl: basic ideas:
+
** PG, the problem generating language, and
**** the pound sign # indicates a comment
+
** MathObjects
**** a semicolon ; ends a line of code
+
**** datatypes:
+
Therefore we start thinking about writing problems for WeBWorK using Perl.
***** scalar variables start with a dollar sign $: $string = "a string"; $number = 5;
+
***** array variables start with an at sign @: @stringarray = ( "one", "two" ); @numarray = ( 1, 3.14 );
+
==Perl==
***** an element in an array is a scalar, so we get it with a scalar variable name: $stringarray[1] is the string "two"
+
===Basic Ideas from Perl===
***** the number of elements in an array is available by using the notation $#stringarray; or scalar(@stringarray);
+
***** a set of elements from an array is an array, which can be obtained with a slice: e.g., @newarray = @stringarray[0..1];
+
# The pound sign indicates a comment: anything in a line after a # sign is ignored by Perl.
***** finally, there is a "hash" datatype, which we aren't discussing here.
+
# Any line of code must be ended with ;, a semicolon.
**** arithmetic in Perl:
+
***** Perl has the expected operations: +, -, *, /, ** (exponentiation), and % (modulo, or remainder)
+
====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 <code>5 - -3</code> will work, but <code>5--3</code> will invoke the decrement operator <code>--</code>, which is not what we (necessarily) expect.
  +
# fractional exponents require some care as well: <code>(-3)**(2/3)</code> will not work, while <code>((-3)**(2))**(-1/3)</code> will.
  +
  +
Perl also has named functions: <code>sin(2)</code> 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 <code>==</code> to test equality, <code>!=</code> to test inequality, and <code>&gt;</code>, <code>&gt;=</code>, <code>&lt;</code>, and <code>&lt;=</code> as expected. These all return 1 (for true), and 0 (for false).
  +
* For strings, we use the operators <code>eq</code> for equality and <code>ne</code> 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 <code>if</code> <code>then</code>:
  +
$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 <code>elsif</code> 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:
  +
* <code>my</code> 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 <code>( 0..50 )</code> is the same as that we used in the array slice, and returns the values between 0 and 50 inclusive.
  +
  +
Finally, we can <code>do</code> <code>until</code>:
  +
$a = 3;
  +
do {
  +
$a = $a + 1;
  +
} until ( $a == 10 );
  +
Will loop through adding one to the variable $a
  +
  +
==The PG Language==
  +
  +
PG: is a language 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
  +
  +
MathObjects: are an extension of PG, which
  +
* correct some Perl quirks
  +
* make writing problems easier
  +
* provide more macros
  +
* make answer checker feedback better for students
  +
  +
A PG file: is a little Perl script that uses PG macros and MathObjects. It will include the following 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)
  +
  +
Sample problem file
  +
TEXT(beginproblem());
  +
does a number of things, including setting the problem number on the page.
  +
  +
Set-up:
  +
Context("Numeric");
  +
$a = non_zero_random(-5,5,1);
  +
$b = random(2,9,1);
  +
  +
Structure of a PG file:
  +
# Comments on Tagging
  +
# Comments on Initialization - always include PGStandard and MathObject, always use TEXT(beginproblem());
  +
# Problem setup - avoid over randomization
  +
# Text section: BEGIN_TEXT/END_TEXT enters a mode that is Text, rather than Perl. In TEXT mode you can use LaTeX to display mathematics: \( \) for inline math, and \[ \] for display math. Further, we can execute Perl in the Text section with \{ \}, which executes the command in the braces.
  +
# in Answer Evaluation, every MO has a cmp() method, so that Formula("$a*x/$b)->cmp() is a method, which will compare the student's answer to the correct answer and return 0 or 1; ANS() takes that result and records it to the database of student scores.
  +
# COMMENT("this is a comment"); provides comments when the problem is viewed in the library browser, and
  +
# ENDDOCUMENT(); must be included at the end of the document.
  +
  +
==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
  +
* <code>$f->D()</code> calls the method called "D" of the MathObject $f. (A method is a function associated with the object.)
  +
* <code>x=>5</code> 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 <code>$f->TeX()</code> 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, <code>Context("Numeric");</code> sets up a Context with one variable, ''x''.

Revision as of 15:44, 26 May 2011

Prep 2011 Main Page > Web Conference 1 > Conference Notes

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

  1. The pound sign indicates a comment: anything in a line after a # sign is ignored by Perl.
  2. 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:

  1. ^ does not exponentiate; it's a bitwise shift, which isn't what we want.
  2. something like 5 - -3 will work, but 5--3 will invoke the decrement operator --, which is not what we (necessarily) expect.
  3. 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 and ne 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

The PG Language

PG: is a language 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

MathObjects: are an extension of PG, which

  • correct some Perl quirks
  • make writing problems easier
  • provide more macros
  • make answer checker feedback better for students

A PG file: is a little Perl script that uses PG macros and MathObjects. It will include the following sections:

  1. Tagging info (for indexing of the NPL)
  2. Initialization (loading macros, etc)
  3. Setup (defining parameters, etc)
  4. Main Text (what students see)
  5. Answer evaluation (checking the submitted answers)
  6. Solution (optional) and end document (mandatory)

Sample problem file

TEXT(beginproblem());

does a number of things, including setting the problem number on the page.

Set-up:

Context("Numeric");
$a = non_zero_random(-5,5,1);
$b = random(2,9,1);

Structure of a PG file:

  1. Comments on Tagging
  2. Comments on Initialization - always include PGStandard and MathObject, always use TEXT(beginproblem());
  3. Problem setup - avoid over randomization
  4. Text section: BEGIN_TEXT/END_TEXT enters a mode that is Text, rather than Perl. In TEXT mode you can use LaTeX to display mathematics: \( \) for inline math, and \[ \] for display math. Further, we can execute Perl in the Text section with \{ \}, which executes the command in the braces.
  5. in Answer Evaluation, every MO has a cmp() method, so that Formula("$a*x/$b)->cmp() is a method, which will compare the student's answer to the correct answer and return 0 or 1; ANS() takes that result and records it to the database of student scores.
  6. COMMENT("this is a comment"); provides comments when the problem is viewed in the library browser, and
  7. ENDDOCUMENT(); must be included at the end of the document.

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.