compoundProblem5.pl - Provides support for multi-part problems where later parts are not visible until earlier parts are completed correctly.
This file defines a Scaffold()
macro that creates the structure needed to manage scaffolded problems. The sections are then defined using DISPLAY_SECTION()
or DISPLAY_PGML_SECTION()
calls surrounding the text of the sections. These keep track of the answers in each section so that the system knows when one section is complete and the next is to be made available. To make that work, use SECTION_ANS()
and SECTION_NAMED_ANS()
rather than ANS()
and NAMED_ANS()
to assign answer checkers to answer blanks. Solutions can be provided for each section using the SECTION_SOLUTION()
or SECTION_PGML_SOLUTION()
macros. At the end of the problem, use PROCESS_SECTIONS()
to finalize all the sections.
Here is a sample:
loadMacros("compoundProblem5.pl");
$scaffold = Scaffold(); # create the scaffold
Context("Numeric");
##########################################
# Section 1
##########################################
$f = Compute("x^2-1");
Context()->texStrings;
DISPLAY_SECTION("Section 1: The equation",<<'END_SECTION');
Enter the function \($f\): \{ SECTION_ANS($f->cmp); $f->ans_rule(10) \}
END_SECTION
Context()->normalStrings;
##########################################
# Section 2
##########################################
$x = Compute("sqrt(3)/2");
DISPLAY_SECTION("Section 2: The number",<<'END_SECTION');
What is \(\sin(\pi/3)\)? \{ SECTION_ANS($x->cmp); $x->ans_rule \}
END_SECTION
##########################################
PROCESS_SCAFFOLD();
The DISPLAY_SECTION()
and DISPLAY_PGML_SECTION()
macros can accept optional arguments by replacing the title with an array reference that consists of the title followed by the options. For example, to force a section to always be displayed, you could use
DISPLAY_SECTION(["Part 2: Always Open", canshow => "1"],<<'END_SECTION');
...
END_SECTION
It is also possible to pass a HASH reference as the first argument:
DISPLAY_SECTION({name => "Part 2: Always Open", canshow => "1"},<<'END_SECTION');
...
END_SECTION
Here you must specify the name
option in order to give the section its title.
The possible options are the following:
iscorrect => condition
This gives the condition to use to tell if the section is fully correct. It is a string that is evaluated and should return 0 or 1 (or true or false) to indicate if the section is correct or not. It can also be a reference to a subroutine that is called with a pointer to the section object whose return value should be 0 or 1.
In the past, the problem author had to supply this option in order to tell which answers belong to this section, but this version of the scaffolding macros handles that automatically, so you only need to provide it if you want to override the default.
The Scaffold-
requireCorrect()> function is provided to allow you to check if the given answers are checked. You pass it a list of integers representing the answer blanks that you want to be correct. Here, 1 represents the first answer blank, 2 the next one, and so on.
canshow => condition
This gives the condition to use to tell if the student is allowed to open this section. It is a string that is evaluated and should return 0 or 1 (or true or false) to indicate if the section can ope or not. It can also be a reference to a subroutine that is called with a pointer to the section object whose return value should be 0 or 1.
In the past, the problem author had to supply this option in order to tell which answers need to be correct in order for this section to be openable, but this version of the scaffolding macros handles that automatically, so you only need to provide it if you want to override the default.
The Scaffold-
requireCorrect()> function is provided to allow you to check if the given answers are checked. You pass it a list of integers representing the answer blanks that you want to be correct. Here, 1 represents the first answer blank, 2 the next one, and so on.
name => "title"
This is the title of the section as it should appear in the colored title area of the section.
PGML => 0 or 1
This indicates whether the text of the section is PGML text, or text suitable for use in BEGIN_TEXT/END_TEXT
. It is set automatically by the DISPLAY_PGML_SECTION()
macro.
Within the text of the section, you can use ANS()
as you would normally to obtain answer checkers. E.g.,
$r = Real(2);
DISPLAY_SECTION("Part 1",<<'END_SECTION');
\(1 + 1\) = \{ANS($r->cmp); $r->ans_rule(5)\}
END_SECTION
If you want to assign answer checkers after the section is created, you must use SECTION_ANS()
or SECTION_NAMED_ANS()
to do so. E.g.,
$r = Real(2);
DISPLAY_SECTION("Part 1",<<'END_SECTION');
\(1 + 1\) = \{$r->ans_rule(5)\}
END_SECTION
SECTION_ANS($r->cmp);
If you want a solution for a section, use SECTION_SOLUTION()
or SECTION_PGML_SOLUTION()
to create it. E.g.,
$r = Real(2);
DISPLAY_SECTION("Part 1",<<'END_SECTION');
\(1 + 1\) = \{ANS($r->cmp); $r->ans_rule(5)\}
END_SECTION
SECTION_SOLUTION(<<'END_SOLUTION');
When you add 1 to 1 you get 2.
END_SOLUTION
Normally, a solution will be tied to the section that preceeded it, but if you want to put all your solutions at the end, for example, you can pass options the solution macros that tell it the section to attach to:
$r1 = Real(2);
DISPLAY_SECTION("Part 1",<<'END_SECTION');
\(1 + 1\) = \{ANS($r1->cmp); $r1->ans_rule(5)\}
END_SECTION
$r2 = Real(4);
DISPLAY_SECTION("Part 1",<<'END_SECTION');
\(2\times 2\) = \{ANS($r2->cmp); $r2->ans_rule(5)\}
END_SECTION
SECTION_SOLUTION({section => 1},<<'END_SOLUTION')
When you add 1 to 1 you get 2.
END_SOLUTION
SECTION_SOLUTION({section => 2},<<'END_SOLUTION')
When you multiply 2 by 2 you get 4.
END_SOLUTION
At the bottom of your problem file you should use the command
PROCESS_SCAFFOLD();
so that the contents of the scaffold will be properly displayed.