NAME

draggableProof.pl

DESCRIPTION

This macro helps the instructor create a drag-and-drop environment in which students are asked to arrange predefined statements into a correct sequence.

TERMINOLOGY

An HTML element into or out of which other elements may be dragged will be called a "bucket".

An HTML element which houses a collection of buckets will be called a "bucket pool".

USAGE

To initialize a DraggableProof bucket pool in a .pg problem, insert the line:

$draggable = DraggableProof(
    $statements,
    $extra_statements,
    option1 => $value1,
    option2 => $value2,
    ...
);

Then insert the draggable proof bucket pool into the problem text with

BEGIN_TEXT
\{$draggable->ans_rule\}
END_TEXT

for basic PG, or

BEGIN_PGML
[_]{$draggable}
END_PGML

for PGLM. Note the following also works, but is deprecated. However, if you want your problem to be compatible with previous versions of PG this must be used. Call

\{$draggable->Print\} (or [@ $draggable->Print @]* )

within the BEGIN_TEXT / END_TEXT (or BEGIN_PGML / END_PGML ) environment. Then call

ANS($draggable->cmp)

after END_TEXT (or END_PGML).

$statements, e.g. ["Socrates is a man.", "Socrates is mortal.", ...], is an array reference to the list of statements used in the correct proof.

$extra_statements, e.g. ["Roses are red."], is an array reference to the list statements extraneous to the proof. If there are no extraneous statements, use the empty array reference [].

By default, the score of the student answer is 100% if the draggable statements are placed in the exact same order as in the array referenced by $statements, with no inclusion of any statement from $extra_statements. The score is 0% otherwise.

Available Options:

NumBuckets         => 1 or 2
SourceLabel        => <string>
TargetLabel        => <string>
Levenshtein        => 0 or 1
DamerauLevenshtein => 0 or 1
InferenceMatrix    => <array reference>
IrrelevancePenalty => <float>
ResetButtonText    => <string>

Their usage is explained in the example below.

EXAMPLE

DOCUMENT();
loadMacros(
    'PGstandard.pl',
    'PGML.pl',
    'MathObjects.pl',
    'draggableProof.pl'
);

$draggable = DraggableProof(
    # The proof given in the correct order.
    [
        'All men are mortal.', # index 0
        'Socrates is a man.',  # index 1
        'Socrates is mortal.'  # index 2
    ],

    # Extra statements that are not part of the correct answer.
    [
        'Some animals are men.',
        'Beauty is immortal.',
        'Not all animals are men.'
    ],

    # Number of drag and drop buckets.  Must be either 1 or 2.
    # The default value if not given is 2.
    NumBuckets => 2,

    # Label of first bucket if NumBuckets = 2.
    # The default value if not given is 'Choose from these sentences:'
    SourceLabel => "${BBOLD}Axioms${EBOLD}",

    # Label of second bucket if NumBuckets = 2,
    # or of the only bucket if NumBuckets = 1.
    # The default value if not given is 'Your Proof:'.
    TargetLabel => "${BBOLD}Reasoning${EBOLD}",

    # If equal to 1, scoring is determined by the Levenshtein edit distance
    # between student answer and correct answer.
    # The default value if not given is 0.
    Levenshtein => 1,

    # If equal to 1, scoring is determined by the Damerau-Levenshtein
    # distance between student answer and correct answer.  A pair of
    # transposed adjacent statements is counted as two mistakes under
    # Levenshtein scoring, but as one mistake under Damerau-Levenshtein
    # scoring.
    # The default value if not given is 0.
    DamerauLevenshtein => 1,

    # (i, j)-entry is nonzero <=> statement i implies statement j.  The
    # score of each corresponding inference is weighted according to the
    # value of the matrix entry.
    # The default value if not given is [].
    InferenceMatrix => [
        [0, 0, 1],
        [0, 0, 1],
        [0, 0, 0]
    ],

    # This option is processed only if the InferenceMatrix option is set.
    # Penalty for each extraneous statement in the student answer is
    # <IrrelevancePenalty> divided by the total number of inference points
    # (i.e. sum of all entries in the InferenceMatrix).
    # The default value if not given is 1.
    IrrelevancePenalty => 1

    # This is the text label for the button shown that resets the drag and
    # drop element to its default state.  The default value if not given is
    # "Reset".
    ResetButtonText => 'zurücksetzen'

    # These are options that will be passed to the $draggable->cmp method.
    cmpOptions => { checker => sub { ... } }
);

BEGIN_PGML
Show that Socrates is mortal by dragging the relevant *Axioms* into the
*Reasoning* box in an appropriate order.

[_]{$draggable}
END_PGML

ENDDOCUMENT();

CUSTOM CHECKERS

Custom checkers can also be used by passing the checker or list_checker options to the cmp method. See https://webwork.maa.org/wiki/Custom_Answer_Checkers, and https://webwork.maa.org/wiki/Custom_Answer_Checkers_for_Lists for details on how to use these.

Note that if using a standard checker the the correct and student answers will be the MathObject List of indices corresponding to the only bucket if NumBuckets is 1, and will be the MathObject List of indices corresponding to the second bucket if NumBuckets is 2. The checker should return a number between 0 and 1 inclusive.

For a list_checker the correct and student answers will be perl arrays containing MathObject Lists for all buckets. So if NumBuckets is 1, the arrays will only contain one list corresponding to the only bucket, and if NumBuckets is 2, the arrays will contain two lists corresponding to the two buckets. Usually the first (source) list is ignored for grading if NumBuckets is 2. So if you want to determine the score using both buckets this is the only option. Note that the checker should return a number between 0 and 1 inclusive regardless of the number of buckets.