Difference between revisions of "SamsExampleProblem"

From WeBWorK_wiki
Jump to navigation Jump to search
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<nowiki>
 
  +
# PG problems are essentially Perl source files, with one exception: Perl<br/>
+
# PG problems are essentially Perl source files, with one exception: Perl
+
# backslashes (\) are replaced by double-tildes (~~) since TeX uses
# backslashes (\) are replaced by double-tildes (~~) since TeX uses
+
# backslashes. For more about the format of PG files, consult the Translator.pm
# backslashes. For more about the format of PG files, consult the Translator.pm
+
# documentation at:
# documentation at:
+
# <http://webwork.maa.org/pod/pg/lib/WeBWorK/PG/Translator.html>
# <http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/lib/WeBWorK/PG/Translator.pm.html#translate>
+
+
# The first section in this file is a list of tags for the database problem
# The first section in this file is a list of tags for the database problem
+
# library project. For more about the tagging format, look at:
# library project. For more about the tagging format, look at:
+
# <http://hobbes.la.asu.edu/webwork-stuff/Tagging.html>
# <http://hobbes.la.asu.edu/webwork-stuff/Tagging.html>
+
+
##DESCRIPTION
##DESCRIPTION
+
## Plots a piecewise function made up of a horizontal line, a diagonal line, and
## Plots a piecewise function made up of a horizontal line, a diagonal line, and
+
## a parabola and asks the student to determine the derivative at various
## a parabola and asks the student to determine the derivative at various
+
## interesting points.
## interesting points.
+
##ENDDESCRIPTION
##ENDDESCRIPTION
+
## DBsubject('Calculus')
## DBsubject('Calculus')
+
## DBchapter('Limits and Derivatives')
## DBchapter('Limits and Derivatives')
+
## DBsection('Definition of the Derivative')
## DBsection('Definition of the Derivative')
+
## KEYWORDS('calculus', 'derivatives', 'slope')
## KEYWORDS('calculus', 'derivatives', 'slope')
+
## TitleText1('Calculus')
## TitleText1('Calculus')
+
## EditionText1('1')
## EditionText1('1')
+
## AuthorText1('Rogawski')
## AuthorText1('Rogawski')
+
## Section1('3.1')
## Section1('3.1')
+
## Problem1('11')
## Problem1('11')
+
## Author('Sam Hathaway')
## Author('Sam Hathaway')
+
## Institution('W.H.Freeman')
## Institution('W.H.Freeman')
+
+
# The DOCUMENT() call sets up initial values for PG internals. It should always
# The DOCUMENT() call sets up initial values for PG internals. It should always
+
# be the first executable line in the problem.
# be the first executable line in the problem.
+
DOCUMENT();
DOCUMENT();
+
+
# loadMacros() calls load macro files (which are Perl source files) into the
# loadMacros() calls load macro files (which are Perl source files) into the
+
# problem environment. These first three files are required by all problems.
# problem environment. These first three files are required by all problems.
+
# Documentation:
# Documentation:
+
# <https://webwork.maa.org/pod/pg/macros/PG.html>
# <http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/macros/PG.pl.html>
+
# <https://webwork.maa.org/pod/pg/macros/PGbasicmacros.html>
# <http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/macros/PGbasicmacros.pl.html>
+
# <https://webwork.maa.org/pod/pg/macros/PGanswermacros.html>
# <http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/macros/PGanswermacros.pl.html>
+
loadMacros("PG.pl","PGbasicmacros.pl","PGanswermacros.pl");
loadMacros("PG.pl","PGbasicmacros.pl","PGanswermacros.pl");
+
+
# Parser.pl is the main macro file for MathObjects. This file defines macros
# Parser.pl is the main macro file for MathObjects. This file defines macros
+
# such as Real() and Formula(). You'll load it in pretty much all problems.
# such as Real() and Formula(). You'll load it in pretty much all problems.
+
# Parser docs are available at:
# Parser docs are available at:
+
# <https://webwork.maa.org/pod/pg/doc/MathObjects>
# <http://devel.webwork.rochester.edu/twiki/bin/view/Webwork/MathObjects>
+
loadMacros("Parser.pl");
loadMacros("Parser.pl");
+
+
# This is our macro file that provides the textbook_ref_exact() and
# This is our macro file that provides the textbook_ref_exact() and
+
# textbook_ref_corr() macros. You'll load it in all problems.
# textbook_ref_corr() macros. You'll load it in all problems.
+
loadMacros("freemanMacros.pl");
loadMacros("freemanMacros.pl");
+
+
# This macro file contains the ceil(), floor(), max(), and (min) macros, which
# This macro file contains the ceil(), floor(), max(), and (min) macros, which
+
# we use in this problem. If you're not using macros from this package, you do
# we use in this problem. If you're not using macros from this package, you do
+
# not need to load it.
# not need to load it.
+
loadMacros("PGauxiliaryFunctions.pl");
loadMacros("PGauxiliaryFunctions.pl");
+
+
# This macro file contains the init_graph() and plot_functions() macros. We need
# This macro file contains the init_graph() and plot_functions() macros. We need
+
# these to create the graph for this problem. Don't load this unless you need
# these to create the graph for this problem. Don't load this unless you need
+
# it. Documentation at:
# it. Documentation at:
+
# <https://webwork.maa.org/pod/pg/macros/PGgraphmacros.html>
# <http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/macros/PGgraphmacros.pl.html>
+
loadMacros("PGgraphmacros.pl");
loadMacros("PGgraphmacros.pl");
+
+
# These are the values in the book version of the problem. Note that they are
# These are the values in the book version of the problem. Note that they are
+
# commented out.
# commented out.
+
#$base = 1;
#$base = 1;
+
#$rise = 2;
#$rise = 2;
+
#$vertex_y = -2.25;
#$vertex_y = -2.25;
+
+
# Here are the randomized values. Each student will get a different (but
# Here are the randomized values. Each student will get a different (but
+
# persistent) value from each of these calls.
# persistent) value from each of these calls.
+
$base = random(1,3,1);
$base = random(1,3,1);
+
$rise = random(1,2,1);
$rise = random(1,2,1);
+
$vertex_y = random(1,4,0.25)*list_random(-1,1);
$vertex_y = random(1,4,0.25)*list_random(-1,1);
+
+
# Create a MathObject formula for the initial height of the first horizontal
# Create a MathObject formula for the initial height of the first horizontal
+
# line.
# line.
+
$horiz_line = Formula($base);
$horiz_line = Formula($base);
+
+
# Represent the slope of the diagonal line. Set the reduceConstants flag of the
# Represent the slope of the diagonal line. Set the reduceConstants flag of the
+
# MathObjects context to 0, so that "$rise/2" is not reduced.
# MathObjects context to 0, so that "$rise/2" is not reduced.
+
Context()->flags->set(reduceConstants=>0);
Context()->flags->set(reduceConstants=>0);
+
$slope = Formula("$rise/2");
$slope = Formula("$rise/2");
+
+
# This is the formula for the diagonal line.
# This is the formula for the diagonal line.
+
$diag_line = Formula("$slope*(x-3)+$base");
$diag_line = Formula("$slope*(x-3)+$base");
+
+
# This is the formula for the parabola.
# This is the formula for the parabola.
+
$par = Formula("-($vertex_y/4)(x-5)(x-9)+$base+$rise");
$par = Formula("-($vertex_y/4)(x-5)(x-9)+$base+$rise");
+
+
# Get the y-value of the vertex of the porabola. We know that it occurs at x=7,
# Get the y-value of the vertex of the porabola. We know that it occurs at x=7,
+
# so we evaluate the $par formula with at x=7.
# so we evaluate the $par formula with at x=7.
+
$real_vertex = $par->eval(x=>7);
$real_vertex = $par->eval(x=>7);
+
+
# Now we set some temporary variables that we'll pass into init_graph below:
# Now we set some temporary variables that we'll pass into init_graph below:
+
+
# Minimum and maximum x and y values to graph.
# Minimum and maximum x and y values to graph.
+
$xmin = -1;
$xmin = -1;
+
$ymin = min(-1, ceil($real_vertex)-1);
$ymin = min(-1, ceil($real_vertex)-1);
+
$xmax = 9;
$xmax = 9;
+
$ymax = max(5, $base+$rise+1, floor($real_vertex)+1);
$ymax = max(5, $base+$rise+1, floor($real_vertex)+1);
+
+
# We want grid lines on each integer value, but we have to specify the total
# We want grid lines on each integer value, but we have to specify the total
+
# number of grid lines on each axis, so we just use the x and y range.
# number of grid lines on each axis, so we just use the x and y range.
+
$xrange = $xmax-$xmin;
$xrange = $xmax-$xmin;
+
$yrange = $ymax-$ymin;
$yrange = $ymax-$ymin;
+
+
# Size of the graph in pixels.
# Size of the graph in pixels.
+
$xsize = $xrange*25;
$xsize = $xrange*25;
+
$ysize = $yrange*25;
$ysize = $yrange*25;
+
+
# init_graph returns a graph object that we can then add functions to.
# init_graph returns a graph object that we can then add functions to.
+
$graph = init_graph(
$graph = init_graph(
+
$xmin, $ymin,
$xmin, $ymin,
+
$xmax, $ymax,
$xmax, $ymax,
+
grid => [$xrange,$yrange],
grid => [$xrange,$yrange],
+
axes => [0,0],
axes => [0,0],
+
size => [$xsize,$ysize],
size => [$xsize,$ysize],
+
);
);
+
+
# Add three functions to the graph. The language used in specifying plots is
# Add three functions to the graph. The language used in specifying plots is
+
# described in the PGgraphmacros.pl docs. When a MathObject is used in double-
# described in the PGgraphmacros.pl docs. When a MathObject is used in double-
+
# quotes, it is stringified into the quasi-TI notation that WeBWorK uses.
# quotes, it is stringified into the quasi-TI notation that WeBWorK uses.
+
plot_functions($graph,
plot_functions($graph,
+
"$horiz_line for x in [0,3] using color:red and weight:2",
"$horiz_line for x in [0,3] using color:red and weight:2",
+
"$diag_line for x in [3,5] using color:red and weight:2",
"$diag_line for x in [3,5] using color:red and weight:2",
+
"$par for x in [5,9] using color:red and weight:2",
"$par for x in [5,9] using color:red and weight:2",
+
);
);
+
+
# This changes how MathObjects are stringified. Instead of quasi-TI syntax,
# This changes how MathObjects are stringified. Instead of quasi-TI syntax,
+
# we switch to TeX stringification.
# we switch to TeX stringification.
+
Context()->texStrings;
Context()->texStrings;
+
+
# A BEGIN_TEXT...END_TEXT block is replaced by the preprocessor with:
# A BEGIN_TEXT...END_TEXT block is replaced by the preprocessor with:
+
# TEXT(EV3(<<'END_TEXT'));
# TEXT(EV3(<<'END_TEXT'));
+
# ...
# ...
+
# END_TEXT
# END_TEXT
+
# The <<'END_TEXT' part is the beginning of a Perl here document. Anyway, this
# The <<'END_TEXT' part is the beginning of a Perl here document. Anyway, this
+
# is just a convenience function, so you don't have to type that whole thing.
# is just a convenience function, so you don't have to type that whole thing.
+
# Basically whenever you see BEGIN_TEXT, you can read it as
# Basically whenever you see BEGIN_TEXT, you can read it as
+
# TEXT(EV3(<<'END_TEXT'));
# TEXT(EV3(<<'END_TEXT'));
+
#
#
+
# TEXT() is the basic macro that outputs (well, accumulates actually) problem
# TEXT() is the basic macro that outputs (well, accumulates actually) problem
+
# "text", which can be HTML of TeX depending on the display mode.
# "text", which can be HTML of TeX depending on the display mode.
+
#
#
+
# EV3() is a macro that interpretes it's contents according to these rules:
# EV3() is a macro that interpretes it's contents according to these rules:
+
# * Perl variables are evaluated in double-quoted string context. That is,
# * Perl variables are evaluated in double-quoted string context. That is,
+
# they get stringified.
# they get stringified.
+
# * \{ EXPR \} blocks are replaced by the result of evaluating the perl code
# * \{ EXPR \} blocks are replaced by the result of evaluating the perl code
+
# inside.
# inside.
+
# * \( TEX \) blocks are replaced by equations described by the TEX code
# * \( TEX \) blocks are replaced by equations described by the TEX code
+
# within. Depending on the display mode, this can be plain text, an image, a
# within. Depending on the display mode, this can be plain text, an image, a
+
# jsMath block, or raw TeX.
# jsMath block, or raw TeX.
+
# * \[ TEX \] blocks are treated similarly to \( TEX \) blocks, except that
# * \[ TEX \] blocks are treated similarly to \( TEX \) blocks, except that
+
# the display math is used instead of inline math.
# the display math is used instead of inline math.
+
#
#
+
# In the original version of this problem, there was one BEGIN_TEXT/END_TEXT
# In the original version of this problem, there was one BEGIN_TEXT/END_TEXT
+
# block, but because I have to comment, I'm going to split it up into multiple
# block, but because I have to comment, I'm going to split it up into multiple
+
# blocks.
# blocks.
+
+
# beginproblem() prints the point value of the problem, the beginning of the
# beginproblem() prints the point value of the problem, the beginning of the
+
# HTML form (in HTML-based display modes), and other header-type stuff.
# HTML form (in HTML-based display modes), and other header-type stuff.
+
BEGIN_TEXT
BEGIN_TEXT
+
\{ beginproblem() \}
\{ beginproblem() \}
+
END_TEXT
END_TEXT
+
+
# We use our textbook_ref_exact() macro to print "From Rogawski ET, section 3.1
# We use our textbook_ref_exact() macro to print "From Rogawski ET, section 3.1
+
# problem 11".
# problem 11".
+
BEGIN_TEXT
BEGIN_TEXT
+
\{ textbook_ref_exact("Rogawski ET", "3.1","11") \}
\{ textbook_ref_exact("Rogawski ET", "3.1","11") \}
+
END_TEXT
END_TEXT
+
# $PAR is a double-line break. It contains &lt;P&gt; in HTML-based modes and \par in
+
# TeX mode. Note the use of \( ... \) to typeset f(x).
# $PAR is a double-line break. It contains "<P>" in HTML-based modes and \par in
+
BEGIN_TEXT
# TeX mode. Note the use of \( ... \) to typeset "f(x)".
+
$PAR
BEGIN_TEXT
+
Let \( f(x) \) be the function whose graph is shown below.
$PAR
+
END_TEXT
Let \( f(x) \) be the function whose graph is shown below.
+
END_TEXT
+
# We insert the graph that we generated before. insertGraph() actually generates
+
# the image, and it returns the pathname of the image. image() takes that image
# We insert the graph that we generated before. insertGraph() actually generates
+
# and actually generates code needed to place the image in the output. These
# the image, and it returns the pathname of the image. image() takes that image
+
# macros are in dangerousMacros.pl, which is always loaded. Documentation at:
# and actually generates code needed to place the image in the output. These
+
# <https://webwork.maa.org/pod/pg/macros/dangerousMacros.html>
# macros are in dangerousMacros.pl, which is always loaded. Documentation at:
+
BEGIN_TEXT
# <http://devel.webwork.rochester.edu/doc/cvs/pg_HEAD/macros/dangerousMacros.pl.html>
+
$PAR
BEGIN_TEXT
+
\{ image(insertGraph($graph)) \}
$PAR
+
END_TEXT
\{ image(insertGraph($graph)) \}
+
END_TEXT
+
# Now we ask the question.
+
BEGIN_TEXT
# Now we ask the question.
+
$PAR
BEGIN_TEXT
+
Determine \( f'(a) \) for \( a = 1,2,4,7 \).
$PAR
+
END_TEXT
Determine \( f'(a) \) for \( a = 1,2,4,7 \).
+
END_TEXT
+
# And generate the answer blanks. $BR is a single-line break.
+
BEGIN_TEXT
# And generate the answer blanks. $BR is a single-line break.
+
$BR
BEGIN_TEXT
+
\( f'(1) = \) \{ans_rule()\}
$BR
+
$BR
\( f'(1) = \) \{ans_rule()\}
+
\( f'(2) = \) \{ans_rule()\}
$BR
+
$BR
\( f'(2) = \) \{ans_rule()\}
+
\( f'(4) = \) \{ans_rule()\}
$BR
+
$BR
\( f'(4) = \) \{ans_rule()\}
+
\( f'(7) = \) \{ans_rule()\}
$BR
+
END_TEXT
\( f'(7) = \) \{ans_rule()\}
+
END_TEXT
+
# Switch back to normal strings now that we're done with the text block.
+
Context()->normalStrings;
# Switch back to normal strings now that we're done with the text block.
+
Context()->normalStrings;
+
# The ANS() macro takes an "answer evaluator" as its argument. An answer
+
# evaluator is a perl function that gets passed the student's answer and
# The ANS() macro takes an "answer evaluator" as its argument. An answer
+
# determines if it is correct or not. We don't have to write them ourselves,
# evaluator is a perl function that gets passed the student's answer and
+
# because MathObjects know how to generate them, using the ->cmp method. These
# determines if it is correct or not. We don't have to write them ourselves,
+
# ANS() calls must be in the same order as the ans_rule() calls above.
# because MathObjects know how to generate them, using the ->cmp method. These
+
ANS(Real(0)->cmp);
# ANS() calls must be in the same order as the ans_rule() calls above.
+
ANS(Real(0)->cmp);
ANS(Real(0)->cmp);
+
ANS($slope->cmp);
ANS(Real(0)->cmp);
+
ANS(Real(0)->cmp);
ANS($slope->cmp);
+
ANS(Real(0)->cmp);
+
# Switch back to TeX stringification.
+
Context()->texStrings;
# Switch back to TeX stringification.
+
Context()->texStrings;
+
# SOLUTION() works like TEXT() except that it's only shown if the "show
+
# solutions" flag is given. $SOL evaluates to "Solution: " in bold. Note the
# SOLUTION() works like TEXT() except that it's only shown if the "show
+
# MathObjects embedded in math expressions in the solution. Remember that they
# solutions" flag is given. $SOL evaluates to "Solution: " in bold. Note the
+
# are stringifying to their TeX representations.
# MathObjects embedded in math expressions in the solution. Remember that they
+
SOLUTION(EV3(<<'END_SOLUTION'));
# are stringifying to their TeX representations.
+
$PAR
SOLUTION(EV3(<<'END_SOLUTION'));
+
$SOL
$PAR
+
Remember that the value of the derivative of \( f \) at \( x=a \) can be
$SOL
+
interpreted as the slope of the line tangent to the graph of \( y = f(x) \) at
Remember that the value of the derivative of \( f \) at \( x=a \) can be
+
\( x=a \). From the figure, we see that the graph of \( y = f(x) \) is a
interpreted as the slope of the line tangent to the graph of \( y = f(x) \) at
+
horizontal line (that is, a line with zero slope) on the interval
\( x=a \). From the figure, we see that the graph of \( y = f(x) \) is a
+
\( 0 \le x \le 3 \). Accordingly, \( f'(1) = f'(2) = 0 \). On the interval
horizontal line (that is, a line with zero slope) on the interval
+
\( 3 \le x \le 5 \), the graph of \( y = f(x) \) is a line of slope
\( 0 \le x \le 3 \). Accordingly, \( f'(1) = f'(2) = 0 \). On the interval
+
\( $slope \); thus, \( f'(4) = $slope \). Finally, the line tangent to the
\( 3 \le x \le 5 \), the graph of \( y = f(x) \) is a line of slope
+
graph of \( y = f(x) \) at \( x=7 \) is horizontal, so \( f'(7) = 0 \).
\( $slope \); thus, \( f'(4) = $slope \). Finally, the line tangent to the
+
END_SOLUTION
graph of \( y = f(x) \) at \( x=7 \) is horizontal, so \( f'(7) = 0 \).
+
END_SOLUTION
+
# This finishes everything up. It should always be the last executable line in
+
# the file.
# This finishes everything up. It should always be the last executable line in
+
[[Category:Authors]]
# the file.
 
</nowiki>
 

Latest revision as of 18:17, 7 April 2021

# PG problems are essentially Perl source files, with one exception: Perl
# backslashes (\) are replaced by double-tildes (~~) since TeX uses
# backslashes. For more about the format of PG files, consult the Translator.pm
# documentation at:
# <http://webwork.maa.org/pod/pg/lib/WeBWorK/PG/Translator.html>

# The first section in this file is a list of tags for the database problem
# library project. For more about the tagging format, look at:
# <http://hobbes.la.asu.edu/webwork-stuff/Tagging.html>

##DESCRIPTION
## Plots a piecewise function made up of a horizontal line, a diagonal line, and
## a parabola and asks the student to determine the derivative at various
## interesting points.
##ENDDESCRIPTION
## DBsubject('Calculus')
## DBchapter('Limits and Derivatives')
## DBsection('Definition of the Derivative')
## KEYWORDS('calculus', 'derivatives', 'slope')
## TitleText1('Calculus')
## EditionText1('1')
## AuthorText1('Rogawski')
## Section1('3.1')
## Problem1('11')
## Author('Sam Hathaway')
## Institution('W.H.Freeman')

# The DOCUMENT() call sets up initial values for PG internals. It should always
# be the first executable line in the problem.
DOCUMENT();

# loadMacros() calls load macro files (which are Perl source files) into the
# problem environment. These first three files are required by all problems.
# Documentation:
# <https://webwork.maa.org/pod/pg/macros/PG.html>
# <https://webwork.maa.org/pod/pg/macros/PGbasicmacros.html>
# <https://webwork.maa.org/pod/pg/macros/PGanswermacros.html>
loadMacros("PG.pl","PGbasicmacros.pl","PGanswermacros.pl");

# Parser.pl is the main macro file for MathObjects. This file defines macros
# such as Real() and Formula(). You'll load it in pretty much all problems.
# Parser docs are available at:
# <https://webwork.maa.org/pod/pg/doc/MathObjects>
loadMacros("Parser.pl");

# This is our macro file that provides the textbook_ref_exact() and
# textbook_ref_corr() macros. You'll load it in all problems.
loadMacros("freemanMacros.pl");

# This macro file contains the ceil(), floor(), max(), and (min) macros, which
# we use in this problem. If you're not using macros from this package, you do
# not need to load it.
loadMacros("PGauxiliaryFunctions.pl");

# This macro file contains the init_graph() and plot_functions() macros. We need
# these to create the graph for this problem. Don't load this unless you need
# it. Documentation at:
# <https://webwork.maa.org/pod/pg/macros/PGgraphmacros.html>
loadMacros("PGgraphmacros.pl");

# These are the values in the book version of the problem. Note that they are
# commented out.
#$base = 1;
#$rise = 2;
#$vertex_y = -2.25;

# Here are the randomized values. Each student will get a different (but
# persistent) value from each of these calls.
$base = random(1,3,1);
$rise = random(1,2,1);
$vertex_y = random(1,4,0.25)*list_random(-1,1);

# Create a MathObject formula for the initial height of the first horizontal
# line.
$horiz_line = Formula($base);

# Represent the slope of the diagonal line. Set the reduceConstants flag of the
# MathObjects context to 0, so that "$rise/2" is not reduced.
Context()->flags->set(reduceConstants=>0);
$slope = Formula("$rise/2");

# This is the formula for the diagonal line.
$diag_line = Formula("$slope*(x-3)+$base");

# This is the formula for the parabola.
$par = Formula("-($vertex_y/4)(x-5)(x-9)+$base+$rise");

# Get the y-value of the vertex of the porabola. We know that it occurs at x=7,
# so we evaluate the $par formula with at x=7.
$real_vertex = $par->eval(x=>7);

# Now we set some temporary variables that we'll pass into init_graph below:

# Minimum and maximum x and y values to graph.
$xmin = -1;
$ymin = min(-1, ceil($real_vertex)-1);
$xmax = 9;
$ymax = max(5, $base+$rise+1, floor($real_vertex)+1);

# We want grid lines on each integer value, but we have to specify the total
# number of grid lines on each axis, so we just use the x and y range.
$xrange = $xmax-$xmin;
$yrange = $ymax-$ymin;

# Size of the graph in pixels.
$xsize = $xrange*25;
$ysize = $yrange*25;

# init_graph returns a graph object that we can then add functions to.
$graph = init_graph(
    $xmin, $ymin,
    $xmax, $ymax,
    grid => [$xrange,$yrange],
    axes => [0,0],
    size => [$xsize,$ysize],
);

# Add three functions to the graph. The language used in specifying plots is
# described in the PGgraphmacros.pl docs. When a MathObject is used in double-
# quotes, it is stringified into the quasi-TI notation that WeBWorK uses.
plot_functions($graph,
    "$horiz_line for x in [0,3] using color:red and weight:2",
    "$diag_line for x in [3,5] using color:red and weight:2",
    "$par for x in [5,9] using color:red and weight:2",
);

# This changes how MathObjects are stringified. Instead of quasi-TI syntax,
# we switch to TeX stringification.
Context()->texStrings;

# A BEGIN_TEXT...END_TEXT block is replaced by the preprocessor with:
#     TEXT(EV3(<<'END_TEXT'));
#     ...
#     END_TEXT
# The <<'END_TEXT' part is the beginning of a Perl here document. Anyway, this
# is just a convenience function, so you don't have to type that whole thing.
# Basically whenever you see BEGIN_TEXT, you can read it as
#     TEXT(EV3(<<'END_TEXT'));
# 
# TEXT() is the basic macro that outputs (well, accumulates actually) problem
# "text", which can be HTML of TeX depending on the display mode.
# 
# EV3() is a macro that interpretes it's contents according to these rules:
#  * Perl variables are evaluated in double-quoted string context. That is,
# they get stringified.
#  * \{ EXPR \} blocks are replaced by the result of evaluating the perl code
# inside.
#  * \( TEX \) blocks are replaced by equations described by the TEX code
# within. Depending on the display mode, this can be plain text, an image, a
# jsMath block, or raw TeX.
#  * \[ TEX \] blocks are treated similarly to \( TEX \) blocks, except that
# the display math is used instead of inline math.
# 
# In the original version of this problem, there was one BEGIN_TEXT/END_TEXT
# block, but because I have to comment, I'm going to split it up into multiple
# blocks.

# beginproblem() prints the point value of the problem, the beginning of the
# HTML form (in HTML-based display modes), and other header-type stuff.
BEGIN_TEXT
\{ beginproblem() \}
END_TEXT

# We use our textbook_ref_exact() macro to print "From Rogawski ET, section 3.1
# problem 11".
BEGIN_TEXT
\{ textbook_ref_exact("Rogawski ET", "3.1","11") \}
END_TEXT
#  $PAR is a double-line break. It contains <P> in HTML-based modes and \par in
# TeX mode. Note the use of \( ... \) to typeset f(x).
BEGIN_TEXT
$PAR
Let \( f(x) \) be the function whose graph is shown below.
END_TEXT

# We insert the graph that we generated before. insertGraph() actually generates
# the image, and it returns the pathname of the image. image() takes that image
# and actually generates code needed to place the image in the output. These
# macros are in dangerousMacros.pl, which is always loaded. Documentation at:
# <https://webwork.maa.org/pod/pg/macros/dangerousMacros.html>
BEGIN_TEXT
$PAR
\{ image(insertGraph($graph)) \}
END_TEXT

# Now we ask the question.
BEGIN_TEXT
$PAR
Determine \( f'(a) \) for \( a = 1,2,4,7 \).
END_TEXT

# And generate the answer blanks. $BR is a single-line break.
BEGIN_TEXT
$BR
\( f'(1) = \) \{ans_rule()\}
$BR
\( f'(2) = \) \{ans_rule()\}
$BR
\( f'(4) = \) \{ans_rule()\}
$BR
\( f'(7) = \) \{ans_rule()\}
END_TEXT

# Switch back to normal strings now that we're done with the text block.
Context()->normalStrings;

# The ANS() macro takes an "answer evaluator" as its argument. An answer
# evaluator is a perl function that gets passed the student's answer and
# determines if it is correct or not. We don't have to write them ourselves,
# because MathObjects know how to generate them, using the ->cmp method. These
# ANS() calls must be in the same order as the ans_rule() calls above.
ANS(Real(0)->cmp);
ANS(Real(0)->cmp);
ANS($slope->cmp);
ANS(Real(0)->cmp);

# Switch back to TeX stringification.
Context()->texStrings;

# SOLUTION() works like TEXT() except that it's only shown if the "show
# solutions" flag is given. $SOL evaluates to "Solution: " in bold. Note the
# MathObjects embedded in math expressions in the solution. Remember that they
# are stringifying to their TeX representations.
SOLUTION(EV3(<<'END_SOLUTION'));
$PAR
$SOL
Remember that the value of the derivative of \( f \) at \( x=a \) can be
interpreted as the slope of the line tangent to the graph of \( y = f(x) \) at
\( x=a \).  From the figure, we see that the graph of \( y = f(x) \) is a 
horizontal line (that is, a line with zero slope) on the interval 
\( 0 \le x \le 3 \).  Accordingly, \( f'(1) = f'(2) = 0 \).  On the interval 
\( 3 \le x \le 5 \), the graph of \( y = f(x) \) is a line of slope 
\( $slope \); thus, \( f'(4) = $slope \).  Finally, the line tangent to the 
graph of \( y = f(x) \) at \( x=7 \) is horizontal, so \( f'(7) = 0 \).
END_SOLUTION

# This finishes everything up. It should always be the last executable line in
# the file.