diff --git a/sample-problems/Algebra/AlgebraicFractionAnswer.html b/sample-problems/Algebra/AlgebraicFractionAnswer.html index 687ea53..c56889a 100644 --- a/sample-problems/Algebra/AlgebraicFractionAnswer.html +++ b/sample-problems/Algebra/AlgebraicFractionAnswer.html @@ -51,8 +51,9 @@

POD for Macro Files

type="button" data-code="DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', - 'parserMultiAnswer.pl', 'PGcourse.pl' + 'PGstandard.pl', 'PGML.pl', + 'niceTables.pl', 'parserMultiAnswer.pl', + 'PGcourse.pl' ); " aria-label="copy to clipboard"> POD for Macro Files
DOCUMENT();
 
 loadMacros(
-    'PGstandard.pl',  'PGML.pl', 'niceTables.pl',
-    'parserMultiAnswer.pl', 'PGcourse.pl'
+    'PGstandard.pl', 'PGML.pl',
+    'niceTables.pl', 'parserMultiAnswer.pl',
+    'PGcourse.pl'
 );
 
@@ -83,7 +85,7 @@

POD for Macro Files

$a = random(2, 8, 2); $b = random(3, 9, 2); $c = random(1, 9, 1); -} until ($a*$c != $b); +} until ($a * $c != $b); $num = Formula("$a y - $b"); $den = Formula("y - $c"); @@ -124,18 +126,15 @@

POD for Macro Files

); $frac = LayoutTable( - [[ + [ [ "\(\displaystyle\frac{$a y}{y-$c} + \frac{$b}{$c - y}=\)", LayoutTable( - [ - [[ans_rule(4), bottom => 1]], - [ans_rule(4)], - ], - padding => [0.5, 0], + [ [ [ ans_rule(4), bottom => 1 ] ], [ ans_rule(4) ], ], + padding => [ 0.5, 0 ], ) - ]], - padding => [0, 0.5], - valign => 'middle', + ] ], + padding => [ 0, 0.5 ], + valign => 'middle', ); " aria-label="copy to clipboard"> POD for Macro Files $a = random(2, 8, 2); $b = random(3, 9, 2); $c = random(1, 9, 1); -} until ($a*$c != $b); +} until ($a * $c != $b); $num = Formula("$a y - $b"); $den = Formula("y - $c"); @@ -191,18 +190,15 @@

POD for Macro Files

); $frac = LayoutTable( - [[ + [ [ "\(\displaystyle\frac{$a y}{y-$c} + \frac{$b}{$c - y}=\)", LayoutTable( - [ - [[ans_rule(4), bottom => 1]], - [ans_rule(4)], - ], - padding => [0.5, 0], + [ [ [ ans_rule(4), bottom => 1 ] ], [ ans_rule(4) ], ], + padding => [ 0.5, 0 ], ) - ]], - padding => [0, 0.5], - valign => 'middle', + ] ], + padding => [ 0, 0.5 ], + valign => 'middle', ); @@ -290,7 +286,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/AlgebraicFractionAnswer.pg b/sample-problems/Algebra/AlgebraicFractionAnswer.pg index d62f193..831c736 100644 --- a/sample-problems/Algebra/AlgebraicFractionAnswer.pg +++ b/sample-problems/Algebra/AlgebraicFractionAnswer.pg @@ -1,8 +1,9 @@ DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', - 'parserMultiAnswer.pl', 'PGcourse.pl' + 'PGstandard.pl', 'PGML.pl', + 'niceTables.pl', 'parserMultiAnswer.pl', + 'PGcourse.pl' ); Context()->variables->are(y => 'Real'); @@ -12,7 +13,7 @@ do { $a = random(2, 8, 2); $b = random(3, 9, 2); $c = random(1, 9, 1); -} until ($a*$c != $b); +} until ($a * $c != $b); $num = Formula("$a y - $b"); $den = Formula("y - $c"); @@ -53,18 +54,15 @@ $multians = MultiAnswer($num, $den)->with( ); $frac = LayoutTable( - [[ + [ [ "\(\displaystyle\frac{$a y}{y-$c} + \frac{$b}{$c - y}=\)", LayoutTable( - [ - [[ans_rule(4), bottom => 1]], - [ans_rule(4)], - ], - padding => [0.5, 0], + [ [ [ ans_rule(4), bottom => 1 ] ], [ ans_rule(4) ], ], + padding => [ 0.5, 0 ], ) - ]], - padding => [0, 0.5], - valign => 'middle', + ] ], + padding => [ 0, 0.5 ], + valign => 'middle', ); BEGIN_PGML diff --git a/sample-problems/Algebra/AnswerBlankInExponent.html b/sample-problems/Algebra/AnswerBlankInExponent.html index ff014f2..ff8a1aa 100644 --- a/sample-problems/Algebra/AnswerBlankInExponent.html +++ b/sample-problems/Algebra/AnswerBlankInExponent.html @@ -33,12 +33,6 @@

Complete Code

Download file: AnswerBlankInExponent.pg

-
-

POD for Macro Files

- -

PG problem file

@@ -49,7 +43,7 @@

POD for Macro Files

DOCUMENT();
 
-loadMacros('PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'PGcourse.pl');
+loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl');
 

Preamble

-

The macro niceTables.pl provides a way to format the problem.

+ These standard macros need to be loaded.
@@ -81,30 +75,16 @@

POD for Macro Files

$exponent = Formula("$n"); # Display exponents nicely -# Context()->texStrings; - -$tab = LayoutTable([[ - ["\(\displaystyle $expression= \Big(\)" . ans_rule(4) . "\(\Big)\)", cellcss => { padding => '20pt 0pt 0pt 4pt'}], - [ ans_rule(4), cellcss => {padding => '0pt 0pt 20pt 0pt'}] -]]); - -# if ($displayMode eq 'TeX') { -# $showpower = -# "\( \displaystyle $expression = (" -# . ans_rule(4) . ")^{" -# . ans_rule(4) . "}\)"; -# } else { -# $showpower = ColumnTable( -# "\( \displaystyle $expression = \Big( \)" -# . ans_rule(4) -# . "\( \Big) \)", -# ans_rule(4) . $BR . $BR, -# indent => 0, -# separation => 0, -# valign => 'BOTTOM' -# ); -# } -# Context()->normalStrings; +$exp = MODES( + HTML => "<span>\(\displaystyle $expression= \Big(\)" + . ans_rule(4) + . '\(\Big)\)</span><span style="vertical-align: 12pt;">' + . ans_rule(4) + . '</span>', + TeX => "\( \displaystyle $expression = (" + . ans_rule(4) . ")^{" + . ans_rule(4) . "}\)" +); " aria-label="copy to clipboard"> @@ -123,36 +103,22 @@

POD for Macro Files

$exponent = Formula("$n"); # Display exponents nicely -# Context()->texStrings; - -$tab = LayoutTable([[ - ["\(\displaystyle $expression= \Big(\)" . ans_rule(4) . "\(\Big)\)", cellcss => { padding => '20pt 0pt 0pt 4pt'}], - [ ans_rule(4), cellcss => {padding => '0pt 0pt 20pt 0pt'}] -]]); - -# if ($displayMode eq 'TeX') { -# $showpower = -# "\( \displaystyle $expression = (" -# . ans_rule(4) . ")^{" -# . ans_rule(4) . "}\)"; -# } else { -# $showpower = ColumnTable( -# "\( \displaystyle $expression = \Big( \)" -# . ans_rule(4) -# . "\( \Big) \)", -# ans_rule(4) . $BR . $BR, -# indent => 0, -# separation => 0, -# valign => 'BOTTOM' -# ); -# } -# Context()->normalStrings; +$exp = MODES( + HTML => "<span>\(\displaystyle $expression= \Big(\)" + . ans_rule(4) + . '\(\Big)\)</span><span style="vertical-align: 12pt;">' + . ans_rule(4) + . '</span>', + TeX => "\( \displaystyle $expression = (" + . ans_rule(4) . ")^{" + . ans_rule(4) . "}\)" +);

Setup

We want the only variables to be a and b and choose a random power.

-

The exponential layout is made with a table with padding on the top of the left cell and on the bottom of the right cell.

+

The exponential layout is in HTML using a pair of adjacent span elements with the right one shifted up using the CSS style vertical-align. In hardcopy mode, we use the LaTeX exponent.

@@ -161,7 +127,7 @@

POD for Macro Files

type="button" data-code="BEGIN_PGML Rewrite the following using a single exponent. -[$tab]*** +[$exp]* END_PGML " aria-label="copy to clipboard"> POD for Macro Files
BEGIN_PGML
 Rewrite the following using a single exponent.
 
-[$tab]***
+[$exp]*
 END_PGML
 

Statement

-

We insert the nicely formatted answer blanks using $showpower.

+

We insert exponential stored as $exp.

@@ -233,7 +199,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/AnswerBlankInExponent.pg b/sample-problems/Algebra/AnswerBlankInExponent.pg index c091544..fe4cabb 100644 --- a/sample-problems/Algebra/AnswerBlankInExponent.pg +++ b/sample-problems/Algebra/AnswerBlankInExponent.pg @@ -1,6 +1,6 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'PGcourse.pl'); +loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); Context()->variables->are(a => 'Real', b => 'Real'); @@ -14,35 +14,21 @@ $base = Formula("a*b"); $exponent = Formula("$n"); # Display exponents nicely -# Context()->texStrings; - -$tab = LayoutTable([[ - ["\(\displaystyle $expression= \Big(\)" . ans_rule(4) . "\(\Big)\)", cellcss => { padding => '20pt 0pt 0pt 4pt'}], - [ ans_rule(4), cellcss => {padding => '0pt 0pt 20pt 0pt'}] -]]); - -# if ($displayMode eq 'TeX') { -# $showpower = -# "\( \displaystyle $expression = (" -# . ans_rule(4) . ")^{" -# . ans_rule(4) . "}\)"; -# } else { -# $showpower = ColumnTable( -# "\( \displaystyle $expression = \Big( \)" -# . ans_rule(4) -# . "\( \Big) \)", -# ans_rule(4) . $BR . $BR, -# indent => 0, -# separation => 0, -# valign => 'BOTTOM' -# ); -# } -# Context()->normalStrings; +$exp = MODES( + HTML => "\(\displaystyle $expression= \Big(\)" + . ans_rule(4) + . '\(\Big)\)' + . ans_rule(4) + . '', + TeX => "\( \displaystyle $expression = (" + . ans_rule(4) . ")^{" + . ans_rule(4) . "}\)" +); BEGIN_PGML Rewrite the following using a single exponent. -[$tab]*** +[$exp]* END_PGML ANS($base->cmp()); diff --git a/sample-problems/Algebra/AnswerUpToMultiplication.html b/sample-problems/Algebra/AnswerUpToMultiplication.html index 1820edc..deb8ce7 100644 --- a/sample-problems/Algebra/AnswerUpToMultiplication.html +++ b/sample-problems/Algebra/AnswerUpToMultiplication.html @@ -164,7 +164,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/DomainRange.html b/sample-problems/Algebra/DomainRange.html index c21641f..6299999 100644 --- a/sample-problems/Algebra/DomainRange.html +++ b/sample-problems/Algebra/DomainRange.html @@ -199,7 +199,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/DynamicGraph.html b/sample-problems/Algebra/DynamicGraph.html index e49c181..3ce2f87 100644 --- a/sample-problems/Algebra/DynamicGraph.html +++ b/sample-problems/Algebra/DynamicGraph.html @@ -69,16 +69,12 @@

POD for Macro Files

-
$a = random(2, 3, 1);    # negative of left x-intercept
-$b = random(2, 4, 2);    # right x-intercept
-$c = random(3, 6, 1);    # y-intercept
+					
$a = random(1, 4);    # negative of left x-intercept
+$b = random(2, 4);    # right x-intercept
+$c = random(2, 6);    # y-intercept
 
 $k = -$c / ($a * $b);
 
-$A = $k;
-$B = $k * ($a - $b);
-$C = -$k * $a * $b;
-
 $graph = createTikZImage();
 $graph->tikzLibraries('arrows.meta');
 $graph->BEGIN_TIKZ
@@ -129,13 +121,21 @@ 

POD for Macro Files

\draw[->,thick] (0,-1) -- (0,7) node[below right,outer sep=3pt] {\(y\)}; \foreach \y in {1,...,6} \draw (5pt,\y) -- (-5pt,\y) node[left] {\(\y\)}; -\draw[blue,ultra thick] plot[domain=-6:6,smooth] (\x,{$A*\x*\x+$B*\x+$C}); +\draw[blue,ultra thick] plot[domain=-6:6,smooth] (\x,{$k*(\x+$a)*(\x-$b)}); END_TIKZ

Setup

The code between $graph->BEGIN_TIKZ and END_TIKZ are tikz commands. Information on tikz can be found at the homepage for tikz and details on using tikz within pg problems can be found in PGtikz.pl.

+

This problem creates a parabola with random intercepts.

+

Some notes about the command in the TIKZ block:

+
    +
  • The first \filldraw command produces a frame around the plotting region
  • +
  • The first two \draw commands draw the axes as well as the axis labels. The -> gives the lines arrows in that direction and the thick makes the lines a bit thicker.
  • +
  • The two \foreach commands produce the tick marks and labels.
  • +
  • The last \draw command produces the graph of the function. The domain option gives the plotting domain and the smooth attempts to make the resulting graph smooth. Lastly, the function itself needs to be in {} in order for the function to be computed correctly.
  • +
@@ -208,7 +208,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/DynamicGraph.pg b/sample-problems/Algebra/DynamicGraph.pg index ace457e..1acf4d5 100644 --- a/sample-problems/Algebra/DynamicGraph.pg +++ b/sample-problems/Algebra/DynamicGraph.pg @@ -2,16 +2,12 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'PGcourse.pl'); -$a = random(2, 3, 1); # negative of left x-intercept -$b = random(2, 4, 2); # right x-intercept -$c = random(3, 6, 1); # y-intercept +$a = random(1, 4); # negative of left x-intercept +$b = random(2, 4); # right x-intercept +$c = random(2, 6); # y-intercept $k = -$c / ($a * $b); -$A = $k; -$B = $k * ($a - $b); -$C = -$k * $a * $b; - $graph = createTikZImage(); $graph->tikzLibraries('arrows.meta'); $graph->BEGIN_TIKZ @@ -28,7 +24,7 @@ $graph->BEGIN_TIKZ \draw[->,thick] (0,-1) -- (0,7) node[below right,outer sep=3pt] {\(y\)}; \foreach \y in {1,...,6} \draw (5pt,\y) -- (-5pt,\y) node[left] {\(\y\)}; -\draw[blue,ultra thick] plot[domain=-6:6,smooth] (\x,{$A*\x*\x+$B*\x+$C}); +\draw[blue,ultra thick] plot[domain=-6:6,smooth] (\x,{$k*(\x+$a)*(\x-$b)}); END_TIKZ BEGIN_PGML diff --git a/sample-problems/Algebra/EquationDefiningFunction.html b/sample-problems/Algebra/EquationDefiningFunction.html index c63f19f..97605b6 100644 --- a/sample-problems/Algebra/EquationDefiningFunction.html +++ b/sample-problems/Algebra/EquationDefiningFunction.html @@ -152,7 +152,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/EquationImplicitFunction.html b/sample-problems/Algebra/EquationImplicitFunction.html index 2104935..fbe0eff 100644 --- a/sample-problems/Algebra/EquationImplicitFunction.html +++ b/sample-problems/Algebra/EquationImplicitFunction.html @@ -199,7 +199,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/ExpandedPolynomial.html b/sample-problems/Algebra/ExpandedPolynomial.html index 112cee5..dae5a8c 100644 --- a/sample-problems/Algebra/ExpandedPolynomial.html +++ b/sample-problems/Algebra/ExpandedPolynomial.html @@ -173,7 +173,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/FactoredPolynomial.html b/sample-problems/Algebra/FactoredPolynomial.html index 58e729a..0d2c846 100644 --- a/sample-problems/Algebra/FactoredPolynomial.html +++ b/sample-problems/Algebra/FactoredPolynomial.html @@ -175,7 +175,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/FractionAnswer.html b/sample-problems/Algebra/FractionAnswer.html index fa2cc74..a05fd04 100644 --- a/sample-problems/Algebra/FractionAnswer.html +++ b/sample-problems/Algebra/FractionAnswer.html @@ -159,7 +159,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/FunctionDecomposition.html b/sample-problems/Algebra/FunctionDecomposition.html index aaec341..4db551d 100644 --- a/sample-problems/Algebra/FunctionDecomposition.html +++ b/sample-problems/Algebra/FunctionDecomposition.html @@ -176,7 +176,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/GraphToolCircle.html b/sample-problems/Algebra/GraphToolCircle.html index 776b265..5ab77b2 100644 --- a/sample-problems/Algebra/GraphToolCircle.html +++ b/sample-problems/Algebra/GraphToolCircle.html @@ -194,7 +194,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/GraphToolCubic.html b/sample-problems/Algebra/GraphToolCubic.html index 679d7d3..f3da3bc 100644 --- a/sample-problems/Algebra/GraphToolCubic.html +++ b/sample-problems/Algebra/GraphToolCubic.html @@ -210,7 +210,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/GraphToolCustomChecker.html b/sample-problems/Algebra/GraphToolCustomChecker.html index 3b25035..4f008fa 100644 --- a/sample-problems/Algebra/GraphToolCustomChecker.html +++ b/sample-problems/Algebra/GraphToolCustomChecker.html @@ -315,7 +315,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/GraphToolLine.html b/sample-problems/Algebra/GraphToolLine.html index 77913ef..e60906f 100644 --- a/sample-problems/Algebra/GraphToolLine.html +++ b/sample-problems/Algebra/GraphToolLine.html @@ -203,7 +203,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/GraphToolNumberLine.html b/sample-problems/Algebra/GraphToolNumberLine.html index f8cee1b..a41d2d2 100644 --- a/sample-problems/Algebra/GraphToolNumberLine.html +++ b/sample-problems/Algebra/GraphToolNumberLine.html @@ -72,7 +72,8 @@

POD for Macro Files

type="button" data-code="$x1 = random(1, 5); $gt1 = GraphTool("{interval, (-$x1,$x1]}")->with( - availableTools => [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], + availableTools => + [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], numberLine => 1, bBox => [ -6, 6 ], ticksDistanceX => 1, @@ -83,7 +84,8 @@

POD for Macro Files

$x2 = random(-5, 5); $gt2 = GraphTool("{interval, (-inf,$x2)}")->with( - availableTools => [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], + availableTools => + [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], numberLine => 1, bBox => [ -6, 6 ], ticksDistanceX => 1, @@ -99,7 +101,8 @@

POD for Macro Files

$x1 = random(1, 5);
 
 $gt1 = GraphTool("{interval, (-$x1,$x1]}")->with(
-    availableTools => [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ],
+    availableTools =>
+        [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ],
     numberLine     => 1,
     bBox           => [ -6, 6 ],
     ticksDistanceX => 1,
@@ -110,7 +113,8 @@ 

POD for Macro Files

$x2 = random(-5, 5); $gt2 = GraphTool("{interval, (-inf,$x2)}")->with( - availableTools => [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], + availableTools => + [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], numberLine => 1, bBox => [ -6, 6 ], ticksDistanceX => 1, @@ -178,7 +182,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/GraphToolNumberLine.pg b/sample-problems/Algebra/GraphToolNumberLine.pg index 4aee141..1cde515 100644 --- a/sample-problems/Algebra/GraphToolNumberLine.pg +++ b/sample-problems/Algebra/GraphToolNumberLine.pg @@ -5,7 +5,8 @@ loadMacros('PGstandard.pl', 'PGML.pl', 'parserGraphTool.pl', 'PGcourse.pl'); $x1 = random(1, 5); $gt1 = GraphTool("{interval, (-$x1,$x1]}")->with( - availableTools => [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], + availableTools => + [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], numberLine => 1, bBox => [ -6, 6 ], ticksDistanceX => 1, @@ -16,7 +17,8 @@ $gt1 = GraphTool("{interval, (-$x1,$x1]}")->with( $x2 = random(-5, 5); $gt2 = GraphTool("{interval, (-inf,$x2)}")->with( - availableTools => [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], + availableTools => + [ 'PointTool', 'IntervalTool', 'IncludeExcludePointTool' ], numberLine => 1, bBox => [ -6, 6 ], ticksDistanceX => 1, diff --git a/sample-problems/Algebra/GraphToolPoints.html b/sample-problems/Algebra/GraphToolPoints.html index e8062b8..09be3c2 100644 --- a/sample-problems/Algebra/GraphToolPoints.html +++ b/sample-problems/Algebra/GraphToolPoints.html @@ -185,7 +185,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/InequalityAnswer.html b/sample-problems/Algebra/InequalityAnswer.html index 2b26337..8ff2594 100644 --- a/sample-problems/Algebra/InequalityAnswer.html +++ b/sample-problems/Algebra/InequalityAnswer.html @@ -72,7 +72,7 @@

POD for Macro Files

type="button" data-code="Context('Inequalities-Only'); Context()->flags->set(formatStudentAnswer => 'parsed'); -$a = random(3, 9); +$a = random(3, 9); $ans = Compute("x >= -10 / $a"); " aria-label="copy to clipboard"> POD for Macro Files
Context('Inequalities-Only');
 Context()->flags->set(formatStudentAnswer => 'parsed');
 
-$a = random(3, 9);
+$a   = random(3, 9);
 $ans = Compute("x >= -10 / $a");
 
@@ -157,7 +157,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/InequalityAnswer.pg b/sample-problems/Algebra/InequalityAnswer.pg index 9280059..df57152 100644 --- a/sample-problems/Algebra/InequalityAnswer.pg +++ b/sample-problems/Algebra/InequalityAnswer.pg @@ -5,7 +5,7 @@ loadMacros('PGstandard.pl', 'PGML.pl', 'contextInequalities.pl', 'PGcourse.pl'); Context('Inequalities-Only'); Context()->flags->set(formatStudentAnswer => 'parsed'); -$a = random(3, 9); +$a = random(3, 9); $ans = Compute("x >= -10 / $a"); BEGIN_PGML diff --git a/sample-problems/Algebra/LinearInequality.html b/sample-problems/Algebra/LinearInequality.html index 6f09077..b2539c4 100644 --- a/sample-problems/Algebra/LinearInequality.html +++ b/sample-problems/Algebra/LinearInequality.html @@ -49,9 +49,8 @@

POD for Macro Files

DOCUMENT();
 
-loadMacros(
-    'PGstandard.pl',  'PGML.pl', 'parserLinearRelation.pl', 'PGcourse.pl'
-);
+loadMacros('PGstandard.pl', 'PGML.pl', 'parserLinearRelation.pl',
+    'PGcourse.pl');
 
@@ -76,10 +74,10 @@

POD for Macro Files

type="button" data-code="Context("LinearRelation"); do { - $a = random(2,6); - $b = random(2,6); + $a = random(2, 6); + $b = random(2, 6); } until ($a != $b); -$ab = $a*$b; +$ab = $a * $b; $lr = LinearRelation("$a x + $b y < $ab")->reduce; " aria-label="copy to clipboard"> @@ -91,10 +89,10 @@

POD for Macro Files

Context("LinearRelation");
 
 do {
-  $a = random(2,6);
-  $b = random(2,6);
+    $a = random(2, 6);
+    $b = random(2, 6);
 } until ($a != $b);
-$ab = $a*$b;
+$ab = $a * $b;
 
 $lr = LinearRelation("$a x + $b y < $ab")->reduce;
 
@@ -170,7 +168,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/LinearInequality.pg b/sample-problems/Algebra/LinearInequality.pg index 8c84c2f..9b09640 100644 --- a/sample-problems/Algebra/LinearInequality.pg +++ b/sample-problems/Algebra/LinearInequality.pg @@ -1,16 +1,15 @@ DOCUMENT(); -loadMacros( - 'PGstandard.pl', 'PGML.pl', 'parserLinearRelation.pl', 'PGcourse.pl' -); +loadMacros('PGstandard.pl', 'PGML.pl', 'parserLinearRelation.pl', + 'PGcourse.pl'); Context("LinearRelation"); do { - $a = random(2,6); - $b = random(2,6); + $a = random(2, 6); + $b = random(2, 6); } until ($a != $b); -$ab = $a*$b; +$ab = $a * $b; $lr = LinearRelation("$a x + $b y < $ab")->reduce; diff --git a/sample-problems/Algebra/Logarithms.html b/sample-problems/Algebra/Logarithms.html index b13f40b..7b2ba77 100644 --- a/sample-problems/Algebra/Logarithms.html +++ b/sample-problems/Algebra/Logarithms.html @@ -172,7 +172,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/PointAnswers.html b/sample-problems/Algebra/PointAnswers.html index 6891637..c2df85c 100644 --- a/sample-problems/Algebra/PointAnswers.html +++ b/sample-problems/Algebra/PointAnswers.html @@ -164,7 +164,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/ScalingTranslating.html b/sample-problems/Algebra/ScalingTranslating.html index 73b28b6..1f78ff9 100644 --- a/sample-problems/Algebra/ScalingTranslating.html +++ b/sample-problems/Algebra/ScalingTranslating.html @@ -148,7 +148,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/SimpleFactoring.html b/sample-problems/Algebra/SimpleFactoring.html new file mode 100644 index 0000000..46a5fdb --- /dev/null +++ b/sample-problems/Algebra/SimpleFactoring.html @@ -0,0 +1,195 @@ + + + + + + + SimpleFactoring.pg + + + + + + + + + + +
+
+
+

Simple factoring

+

Factored polynomial

+
+ +
+
+
+

Complete Code

+

+ Download file: SimpleFactoring.pg +

+
+ +
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl');
+
+
+

Preamble

+ These standard macros need to be loaded. +
+
+
+
+ +
($x0, $x1) = (non_zero_random(-6, 6), non_zero_random(-6, 6));
+$factor1 = Compute("x-$x0")->reduce;
+$factor2 = Compute("x-$x1")->reduce;
+$f       = Compute("x^2-($x0+$x1)x+$x0*$x1")->reduce;
+$factors = List($factor1, $factor2);
+$roots   = List($x0,      $x1);
+
+# If there were only one solution
+# $roots = List(4);
+
+# If there were no solutions
+# $roots = List("NONE");
+
+
+
+

Setup

+

First, we create two random roots and then create the factors. Note: the ->reduce will help make x-(-3) into x+3. In addition, we create the expanded form of the quadratic.

+

Note that the argument of the List call are the objects in the list, which can be any MathObjects. Here we create a list of Formulas and a list of Reals (the numbers that we use in the second list will be promoted to Real MathObjects when the List is created).

+

If, for example, there were no real roots, we should set $roots = List("NONE"); so that students who enter a list of roots will not receive an error message about entering the wrong type of answer. If we were to use $roots = String("NONE"); instead, students who enter anything other than a string (e.g., a list of numbers) will receive an error message.

+

Similarly, if there were only one root at x=4, we would use $roots = List(4); instead of $roots = Real(4); to avoid sending error messages to students who enter multiple answers or NONE.

+
+
+
+
+ +
BEGIN_PGML
+a) What are the factors of [`[$f]`]?
+
+    Factors = [__]{$factors}
+
+
+b) What are the roots of this equation?
+
+    Roots = [__]{$roots}
+
+_(Enter both answers as a comma-separated list.)_
+
+END_PGML
+
+
+
+

Statement

+ This is the problem statement in PGML. +
+
+
+
+ +
BEGIN_PGML_SOLUTION
+Solution explanation goes here.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Algebra/SimpleFactoring.pg b/sample-problems/Algebra/SimpleFactoring.pg new file mode 100644 index 0000000..1324e74 --- /dev/null +++ b/sample-problems/Algebra/SimpleFactoring.pg @@ -0,0 +1,35 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); +($x0, $x1) = (non_zero_random(-6, 6), non_zero_random(-6, 6)); +$factor1 = Compute("x-$x0")->reduce; +$factor2 = Compute("x-$x1")->reduce; +$f = Compute("x^2-($x0+$x1)x+$x0*$x1")->reduce; +$factors = List($factor1, $factor2); +$roots = List($x0, $x1); + +# If there were only one solution +# $roots = List(4); + +# If there were no solutions +# $roots = List("NONE"); + +BEGIN_PGML +a) What are the factors of [`[$f]`]? + + Factors = [__]{$factors} + + +b) What are the roots of this equation? + + Roots = [__]{$roots} + +_(Enter both answers as a comma-separated list.)_ + +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Algebra/SolutionForEquation.html b/sample-problems/Algebra/SolutionForEquation.html index 4f0745f..9c9092e 100644 --- a/sample-problems/Algebra/SolutionForEquation.html +++ b/sample-problems/Algebra/SolutionForEquation.html @@ -148,7 +148,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/StringOrOtherType.html b/sample-problems/Algebra/StringOrOtherType.html index 73f3f0a..f4938ab 100644 --- a/sample-problems/Algebra/StringOrOtherType.html +++ b/sample-problems/Algebra/StringOrOtherType.html @@ -158,7 +158,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/TableOfValues.html b/sample-problems/Algebra/TableOfValues.html index 57351ad..b8bd40d 100644 --- a/sample-problems/Algebra/TableOfValues.html +++ b/sample-problems/Algebra/TableOfValues.html @@ -197,7 +197,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Algebra/UnorderedAnswers.html b/sample-problems/Algebra/UnorderedAnswers.html index 6545445..50b4742 100644 --- a/sample-problems/Algebra/UnorderedAnswers.html +++ b/sample-problems/Algebra/UnorderedAnswers.html @@ -178,7 +178,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Complex/ComplexOperations.html b/sample-problems/Complex/ComplexOperations.html index caf2640..6f8fdb3 100644 --- a/sample-problems/Complex/ComplexOperations.html +++ b/sample-problems/Complex/ComplexOperations.html @@ -65,14 +65,14 @@

Complete Code

Context('Complex');
 
-$z0 = Complex(non_zero_random(-5,4), non_zero_random(-5,5));
-$z1 = Complex([-1,4]);
+$z0 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5));
+$z1 = Complex([ -1, 4 ]);
 $z2 = Complex("2-4i");
-$z3 = 3-4*i;
+$z3 = 3 - 4 * i;
 
-$ans1 = $z0+$z1;
-$a0 = non_zero_random(-4,4);
-$a1 = random(1,5);
+$ans1 = $z0 + $z1;
+$a0   = non_zero_random(-4, 4);
+$a1   = random(1, 5);
 $ans2 = Compute("$a0*$z1-$a1*$z2");
 
@@ -148,7 +148,6 @@

Complete Code

Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT();" aria-label="copy to clipboard"> @@ -159,7 +158,6 @@

Complete Code

Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT();
@@ -175,7 +173,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Complex/ComplexOperations.pg b/sample-problems/Complex/ComplexOperations.pg index 6c9dd91..647b9a0 100644 --- a/sample-problems/Complex/ComplexOperations.pg +++ b/sample-problems/Complex/ComplexOperations.pg @@ -4,14 +4,14 @@ loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); Context('Complex'); -$z0 = Complex(non_zero_random(-5,4), non_zero_random(-5,5)); -$z1 = Complex([-1,4]); +$z0 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5)); +$z1 = Complex([ -1, 4 ]); $z2 = Complex("2-4i"); -$z3 = 3-4*i; +$z3 = 3 - 4 * i; -$ans1 = $z0+$z1; -$a0 = non_zero_random(-4,4); -$a1 = random(1,5); +$ans1 = $z0 + $z1; +$a0 = non_zero_random(-4, 4); +$a1 = random(1, 5); $ans2 = Compute("$a0*$z1-$a1*$z2"); BEGIN_PGML @@ -32,5 +32,4 @@ BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Complex/LimitedComplex.html b/sample-problems/Complex/LimitedComplex.html index 4c338bf..6e972f2 100644 --- a/sample-problems/Complex/LimitedComplex.html +++ b/sample-problems/Complex/LimitedComplex.html @@ -49,7 +49,10 @@

POD for Macro Files

DOCUMENT();
 
-loadMacros('PGstandard.pl', 'PGML.pl', 'contextLimitedComplex.pl', 'PGcourse.pl');
+loadMacros(
+    'PGstandard.pl',            'PGML.pl',
+    'contextLimitedComplex.pl', 'PGcourse.pl'
+);
 
@@ -71,23 +77,23 @@

POD for Macro Files

Context('LimitedComplex');
 
-$x0 = non_zero_random(-5,5);
-$y0 = non_zero_random(-5,5);
-$x1 = non_zero_random(-5,5);
-$y1 = non_zero_random(-5,5);
+$x0 = non_zero_random(-5, 5);
+$y0 = non_zero_random(-5, 5);
+$x1 = non_zero_random(-5, 5);
+$y1 = non_zero_random(-5, 5);
 
-$z0 = Complex($x0,$y0);
-$z1 = Complex($x1,$y1);
+$z0 = Complex($x0, $y0);
+$z1 = Complex($x1, $y1);
 
-$ans1 = $z0+$z1;
-$ans2 = $z0*$z1;
+$ans1 = $z0 + $z1;
+$ans2 = $z0 * $z1;
 
 # Determine the polar form of the answer to give a hint.  Since in
 # LimitedComplex, most functions are diasbled, so we work on the components.
-$arg0 = atan($y0/$x0) + ($x0 > 0 ? ($y0>0 ? 0 : 2*pi): pi);
-$arg1 = atan($y1/$x1) + ($x1 > 0 ? ($y1>0 ? 0 : 2*pi): pi);
-$abs0 = sqrt($x0**2+$y0**2);
-$abs1 = sqrt($x1**2+$y1**2);
+$arg0 = atan($y0 / $x0) + ($x0 > 0 ? ($y0 > 0 ? 0 : 2 * pi) : pi);
+$arg1 = atan($y1 / $x1) + ($x1 > 0 ? ($y1 > 0 ? 0 : 2 * pi) : pi);
+$abs0 = sqrt($x0**2 + $y0**2);
+$abs1 = sqrt($x1**2 + $y1**2);
 
@@ -167,7 +173,6 @@

POD for Macro Files

Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT();" aria-label="copy to clipboard"> @@ -178,7 +183,6 @@

POD for Macro Files

Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT();
@@ -194,7 +198,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Complex/LimitedComplex.pg b/sample-problems/Complex/LimitedComplex.pg index 07e461a..a178adb 100644 --- a/sample-problems/Complex/LimitedComplex.pg +++ b/sample-problems/Complex/LimitedComplex.pg @@ -1,26 +1,29 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'contextLimitedComplex.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'contextLimitedComplex.pl', 'PGcourse.pl' +); Context('LimitedComplex'); -$x0 = non_zero_random(-5,5); -$y0 = non_zero_random(-5,5); -$x1 = non_zero_random(-5,5); -$y1 = non_zero_random(-5,5); +$x0 = non_zero_random(-5, 5); +$y0 = non_zero_random(-5, 5); +$x1 = non_zero_random(-5, 5); +$y1 = non_zero_random(-5, 5); -$z0 = Complex($x0,$y0); -$z1 = Complex($x1,$y1); +$z0 = Complex($x0, $y0); +$z1 = Complex($x1, $y1); -$ans1 = $z0+$z1; -$ans2 = $z0*$z1; +$ans1 = $z0 + $z1; +$ans2 = $z0 * $z1; # Determine the polar form of the answer to give a hint. Since in # LimitedComplex, most functions are diasbled, so we work on the components. -$arg0 = atan($y0/$x0) + ($x0 > 0 ? ($y0>0 ? 0 : 2*pi): pi); -$arg1 = atan($y1/$x1) + ($x1 > 0 ? ($y1>0 ? 0 : 2*pi): pi); -$abs0 = sqrt($x0**2+$y0**2); -$abs1 = sqrt($x1**2+$y1**2); +$arg0 = atan($y0 / $x0) + ($x0 > 0 ? ($y0 > 0 ? 0 : 2 * pi) : pi); +$arg1 = atan($y1 / $x1) + ($x1 > 0 ? ($y1 > 0 ? 0 : 2 * pi) : pi); +$abs0 = sqrt($x0**2 + $y0**2); +$abs1 = sqrt($x1**2 + $y1**2); BEGIN_PGML Let [`z_0=[$z0]`] and [`z_1=[$z1]`]. Find @@ -38,5 +41,4 @@ BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Complex/OtherOperations.html b/sample-problems/Complex/OtherOperations.html index a08ec52..61c703a 100644 --- a/sample-problems/Complex/OtherOperations.html +++ b/sample-problems/Complex/OtherOperations.html @@ -72,9 +72,9 @@

See Also

Context('Complex');
 
-$z0 = Complex(non_zero_random(-5,4), non_zero_random(-5,5));
-$z1 = Complex(non_zero_random(-5,4), non_zero_random(-5,5));
-$z2 = Complex(non_zero_random(-5,4), non_zero_random(-5,5));
+$z0 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5));
+$z1 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5));
+$z2 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5));
 
@@ -145,7 +145,6 @@

See Also

Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT();" aria-label="copy to clipboard"> @@ -156,7 +155,6 @@

See Also

Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT();
@@ -172,7 +170,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Complex/OtherOperations.pg b/sample-problems/Complex/OtherOperations.pg index d19adef..be4d3aa 100644 --- a/sample-problems/Complex/OtherOperations.pg +++ b/sample-problems/Complex/OtherOperations.pg @@ -4,9 +4,9 @@ loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); Context('Complex'); -$z0 = Complex(non_zero_random(-5,4), non_zero_random(-5,5)); -$z1 = Complex(non_zero_random(-5,4), non_zero_random(-5,5)); -$z2 = Complex(non_zero_random(-5,4), non_zero_random(-5,5)); +$z0 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5)); +$z1 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5)); +$z2 = Complex(non_zero_random(-5, 4), non_zero_random(-5, 5)); BEGIN_PGML Let [`z_0=[$z0]`], [`z_1=[$z1]`], and [`z_2=[$z2]`]. Find @@ -27,5 +27,4 @@ BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION - ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/DiffCalc/AnswerWithUnits.html b/sample-problems/DiffCalc/AnswerWithUnits.html index 02ac21f..0f32a85 100644 --- a/sample-problems/DiffCalc/AnswerWithUnits.html +++ b/sample-problems/DiffCalc/AnswerWithUnits.html @@ -197,7 +197,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffCalc/DifferenceQuotient.html b/sample-problems/DiffCalc/DifferenceQuotient.html index 73a88f9..72cba92 100644 --- a/sample-problems/DiffCalc/DifferenceQuotient.html +++ b/sample-problems/DiffCalc/DifferenceQuotient.html @@ -160,7 +160,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffCalc/DifferentiateFunction.html b/sample-problems/DiffCalc/DifferentiateFunction.html index 7eb3abf..efc722e 100644 --- a/sample-problems/DiffCalc/DifferentiateFunction.html +++ b/sample-problems/DiffCalc/DifferentiateFunction.html @@ -190,7 +190,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffCalc/LinearApprox.html b/sample-problems/DiffCalc/LinearApprox.html index 67fcc07..b9cac3a 100644 --- a/sample-problems/DiffCalc/LinearApprox.html +++ b/sample-problems/DiffCalc/LinearApprox.html @@ -186,7 +186,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffCalcMV/ContourPlot.html b/sample-problems/DiffCalcMV/ContourPlot.html index 85899ad..70b36ae 100644 --- a/sample-problems/DiffCalcMV/ContourPlot.html +++ b/sample-problems/DiffCalcMV/ContourPlot.html @@ -50,7 +50,10 @@

POD for Macro Files

DOCUMENT();
 
-loadMacros('PGstandard.pl', 'PGML.pl', 'parserPopUp.pl', 'PGtikz.pl', 'PGcourse.pl');
+loadMacros(
+    'PGstandard.pl', 'PGML.pl', 'parserPopUp.pl', 'PGtikz.pl',
+    'PGcourse.pl'
+);
 
 $showPartialCorrectAnswers = 0;
 
@@ -201,7 +207,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffCalcMV/ContourPlot.pg b/sample-problems/DiffCalcMV/ContourPlot.pg index 125c012..3fa1ae3 100644 --- a/sample-problems/DiffCalcMV/ContourPlot.pg +++ b/sample-problems/DiffCalcMV/ContourPlot.pg @@ -1,6 +1,9 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'parserPopUp.pl', 'PGtikz.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', 'parserPopUp.pl', 'PGtikz.pl', + 'PGcourse.pl' +); $showPartialCorrectAnswers = 0; diff --git a/sample-problems/DiffCalcMV/ImplicitPlane.html b/sample-problems/DiffCalcMV/ImplicitPlane.html index 79525e8..a3d6be5 100644 --- a/sample-problems/DiffCalcMV/ImplicitPlane.html +++ b/sample-problems/DiffCalcMV/ImplicitPlane.html @@ -193,7 +193,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffEq/GeneralSolutionODE.html b/sample-problems/DiffEq/GeneralSolutionODE.html index cf2102a..f0c48ca 100644 --- a/sample-problems/DiffEq/GeneralSolutionODE.html +++ b/sample-problems/DiffEq/GeneralSolutionODE.html @@ -50,9 +50,7 @@

POD for Macro Files

DOCUMENT();
 
-loadMacros(
-    'PGstandard.pl', 'PGML.pl', 'parserAssignment.pl', 'PGcourse.pl'
-);
+loadMacros('PGstandard.pl', 'PGML.pl', 'parserAssignment.pl', 'PGcourse.pl');
 
@@ -108,9 +104,12 @@

POD for Macro Files

# Linear independence (Wronskian) my $x = Real(1.43); - my $a11 = $stu->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); - my $a12 = $stu->eval('c1' => 0, 'c2' => 1, 'c3' => 0, x => $x, y => 0); - my $a13 = $stu->eval('c1' => 0, 'c2' => 0, 'c3' => 1, x => $x, y => 0); + my $a11 = + $stu->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); + my $a12 = + $stu->eval('c1' => 0, 'c2' => 1, 'c3' => 0, x => $x, y => 0); + my $a13 = + $stu->eval('c1' => 0, 'c2' => 0, 'c3' => 1, x => $x, y => 0); my $a21 = $stu->D('x') ->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); @@ -184,9 +183,12 @@

POD for Macro Files

# Linear independence (Wronskian) my $x = Real(1.43); - my $a11 = $stu->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); - my $a12 = $stu->eval('c1' => 0, 'c2' => 1, 'c3' => 0, x => $x, y => 0); - my $a13 = $stu->eval('c1' => 0, 'c2' => 0, 'c3' => 1, x => $x, y => 0); + my $a11 = + $stu->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); + my $a12 = + $stu->eval('c1' => 0, 'c2' => 1, 'c3' => 0, x => $x, y => 0); + my $a13 = + $stu->eval('c1' => 0, 'c2' => 0, 'c3' => 1, x => $x, y => 0); my $a21 = $stu->D('x') ->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); @@ -300,7 +302,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffEq/GeneralSolutionODE.pg b/sample-problems/DiffEq/GeneralSolutionODE.pg index b394748..0571755 100644 --- a/sample-problems/DiffEq/GeneralSolutionODE.pg +++ b/sample-problems/DiffEq/GeneralSolutionODE.pg @@ -1,8 +1,6 @@ DOCUMENT(); -loadMacros( - 'PGstandard.pl', 'PGML.pl', 'parserAssignment.pl', 'PGcourse.pl' -); +loadMacros('PGstandard.pl', 'PGML.pl', 'parserAssignment.pl', 'PGcourse.pl'); Context()->variables->add( c1 => 'Real', @@ -38,9 +36,12 @@ $cmp = $answer->cmp( # Linear independence (Wronskian) my $x = Real(1.43); - my $a11 = $stu->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); - my $a12 = $stu->eval('c1' => 0, 'c2' => 1, 'c3' => 0, x => $x, y => 0); - my $a13 = $stu->eval('c1' => 0, 'c2' => 0, 'c3' => 1, x => $x, y => 0); + my $a11 = + $stu->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); + my $a12 = + $stu->eval('c1' => 0, 'c2' => 1, 'c3' => 0, x => $x, y => 0); + my $a13 = + $stu->eval('c1' => 0, 'c2' => 0, 'c3' => 1, x => $x, y => 0); my $a21 = $stu->D('x') ->eval('c1' => 1, 'c2' => 0, 'c3' => 0, x => $x, y => 0); diff --git a/sample-problems/DiffEq/HeavisideStep.html b/sample-problems/DiffEq/HeavisideStep.html index 7f151ed..2d80406 100644 --- a/sample-problems/DiffEq/HeavisideStep.html +++ b/sample-problems/DiffEq/HeavisideStep.html @@ -87,8 +87,10 @@

POD for Macro Files

List($f->eval(t => $a - 1), $f->eval(t => $a), $f->eval(t => $a + 1)); $answer2 = $f->with( - limits => [ $a - 5, $a + 5 ], - test_at => [ [ $a - 1 ], [ $a - 0.0000001 ], [$a], [ $a + 0.0000001 ], [ $a + 1 ] ], + limits => [ $a - 5, $a + 5 ], + test_at => [ + [ $a - 1 ], [ $a - 0.0000001 ], [$a], [ $a + 0.0000001 ], [ $a + 1 ] + ], num_points => 10, ); " aria-label="copy to clipboard"> @@ -115,8 +117,10 @@

POD for Macro Files

List($f->eval(t => $a - 1), $f->eval(t => $a), $f->eval(t => $a + 1)); $answer2 = $f->with( - limits => [ $a - 5, $a + 5 ], - test_at => [ [ $a - 1 ], [ $a - 0.0000001 ], [$a], [ $a + 0.0000001 ], [ $a + 1 ] ], + limits => [ $a - 5, $a + 5 ], + test_at => [ + [ $a - 1 ], [ $a - 0.0000001 ], [$a], [ $a + 0.0000001 ], [ $a + 1 ] + ], num_points => 10, ); @@ -220,7 +224,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/DiffEq/HeavisideStep.pg b/sample-problems/DiffEq/HeavisideStep.pg index f6cfbb6..6645642 100644 --- a/sample-problems/DiffEq/HeavisideStep.pg +++ b/sample-problems/DiffEq/HeavisideStep.pg @@ -20,8 +20,10 @@ $answer1 = List($f->eval(t => $a - 1), $f->eval(t => $a), $f->eval(t => $a + 1)); $answer2 = $f->with( - limits => [ $a - 5, $a + 5 ], - test_at => [ [ $a - 1 ], [ $a - 0.0000001 ], [$a], [ $a + 0.0000001 ], [ $a + 1 ] ], + limits => [ $a - 5, $a + 5 ], + test_at => [ + [ $a - 1 ], [ $a - 0.0000001 ], [$a], [ $a + 0.0000001 ], [ $a + 1 ] + ], num_points => 10, ); diff --git a/sample-problems/DiffEq/PrimesInFormulas.html b/sample-problems/DiffEq/PrimesInFormulas.html index d6447c6..c4cf12e 100644 --- a/sample-problems/DiffEq/PrimesInFormulas.html +++ b/sample-problems/DiffEq/PrimesInFormulas.html @@ -176,7 +176,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/DoubleIntegral.html b/sample-problems/IntegralCalc/DoubleIntegral.html index 22f8945..0f8f5f0 100644 --- a/sample-problems/IntegralCalc/DoubleIntegral.html +++ b/sample-problems/IntegralCalc/DoubleIntegral.html @@ -417,7 +417,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/GraphShading.html b/sample-problems/IntegralCalc/GraphShading.html index 6729426..3f6b088 100644 --- a/sample-problems/IntegralCalc/GraphShading.html +++ b/sample-problems/IntegralCalc/GraphShading.html @@ -216,7 +216,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/IndefiniteIntegrals.html b/sample-problems/IntegralCalc/IndefiniteIntegrals.html index 272d434..ad5fcc8 100644 --- a/sample-problems/IntegralCalc/IndefiniteIntegrals.html +++ b/sample-problems/IntegralCalc/IndefiniteIntegrals.html @@ -167,7 +167,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/LimitsOfIntegration.html b/sample-problems/IntegralCalc/LimitsOfIntegration.html index 7fe89d9..e9f64a1 100644 --- a/sample-problems/IntegralCalc/LimitsOfIntegration.html +++ b/sample-problems/IntegralCalc/LimitsOfIntegration.html @@ -51,7 +51,7 @@

POD for Macro Files

type="button" data-code="DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'answerHints.pl', + 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'answerHints.pl', 'PGcourse.pl' ); " aria-label="copy to clipboard"> @@ -63,7 +63,7 @@

POD for Macro Files

DOCUMENT();
 
 loadMacros(
-    'PGstandard.pl',  'PGML.pl', 'niceTables.pl', 'answerHints.pl',
+    'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'answerHints.pl',
     'PGcourse.pl'
 );
 
@@ -83,12 +83,18 @@

POD for Macro Files

dt => 'Real' ); -$integral = LayoutTable([ - [ ' ',ans_rule(4)], - ['\(f(x)= \)' . ans_rule(10) . '\(+\)','\(\displaystyle \int \;\;\)' . ans_rule(10)], - [ ' ',ans_rule(4)], -], - align => 'rl', allcellcss => {padding => '3pt'}); +$integral = LayoutTable( + [ + [ ' ', ans_rule(4) ], + [ + '\(f(x)= \)' . ans_rule(10) . '\(+\)', + '\(\displaystyle \int \;\;\)' . ans_rule(10) + ], + [ ' ', ans_rule(4) ], + ], + align => 'rl', + allcellcss => { padding => '3pt' } +); " aria-label="copy to clipboard"> @@ -102,12 +108,18 @@

POD for Macro Files

dt => 'Real' ); -$integral = LayoutTable([ - [ ' ',ans_rule(4)], - ['\(f(x)= \)' . ans_rule(10) . '\(+\)','\(\displaystyle \int \;\;\)' . ans_rule(10)], - [ ' ',ans_rule(4)], -], - align => 'rl', allcellcss => {padding => '3pt'}); +$integral = LayoutTable( + [ + [ ' ', ans_rule(4) ], + [ + '\(f(x)= \)' . ans_rule(10) . '\(+\)', + '\(\displaystyle \int \;\;\)' . ans_rule(10) + ], + [ ' ', ans_rule(4) ], + ], + align => 'rl', + allcellcss => { padding => '3pt' } +);
@@ -150,7 +162,6 @@

POD for Macro Files

type="button" data-code="$fpx = Formula("sin(x)"); $fpt = Formula("sin(t)"); - ANS(Compute('x')->cmp()); ANS(Compute('5')->cmp()); ANS( @@ -170,7 +181,6 @@

POD for Macro Files

$fpx = Formula("sin(x)");
 $fpt = Formula("sin(t)");
 
-
 ANS(Compute('x')->cmp());
 ANS(Compute('5')->cmp());
 ANS(
@@ -220,7 +230,8 @@ 

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/LimitsOfIntegration.pg b/sample-problems/IntegralCalc/LimitsOfIntegration.pg index 901411f..d74da67 100644 --- a/sample-problems/IntegralCalc/LimitsOfIntegration.pg +++ b/sample-problems/IntegralCalc/LimitsOfIntegration.pg @@ -1,7 +1,7 @@ DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'answerHints.pl', + 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'answerHints.pl', 'PGcourse.pl' ); @@ -12,12 +12,18 @@ Context()->variables->are( dt => 'Real' ); -$integral = LayoutTable([ - [ ' ',ans_rule(4)], - ['\(f(x)= \)' . ans_rule(10) . '\(+\)','\(\displaystyle \int \;\;\)' . ans_rule(10)], - [ ' ',ans_rule(4)], -], - align => 'rl', allcellcss => {padding => '3pt'}); +$integral = LayoutTable( + [ + [ ' ', ans_rule(4) ], + [ + '\(f(x)= \)' . ans_rule(10) . '\(+\)', + '\(\displaystyle \int \;\;\)' . ans_rule(10) + ], + [ ' ', ans_rule(4) ], + ], + align => 'rl', + allcellcss => { padding => '3pt' } +); BEGIN_PGML Find a formula for the function [`f(x)`] such that [`f '(x) = [$fpx]`] and @@ -29,7 +35,6 @@ END_PGML $fpx = Formula("sin(x)"); $fpt = Formula("sin(t)"); - ANS(Compute('x')->cmp()); ANS(Compute('5')->cmp()); ANS( diff --git a/sample-problems/IntegralCalc/RiemannSums.html b/sample-problems/IntegralCalc/RiemannSums.html index 5959df3..5072459 100644 --- a/sample-problems/IntegralCalc/RiemannSums.html +++ b/sample-problems/IntegralCalc/RiemannSums.html @@ -410,7 +410,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/VolumeOfRevolution.html b/sample-problems/IntegralCalc/VolumeOfRevolution.html index 1385148..dd26881 100644 --- a/sample-problems/IntegralCalc/VolumeOfRevolution.html +++ b/sample-problems/IntegralCalc/VolumeOfRevolution.html @@ -53,7 +53,7 @@

POD for Macro Files

loadMacros( 'PGstandard.pl', 'PGML.pl', - 'niceTables.pl', 'answerHints.pl', + 'niceTables.pl', 'answerHints.pl', 'weightedGrader.pl', 'PGcourse.pl' ); @@ -68,7 +68,7 @@

POD for Macro Files

loadMacros( 'PGstandard.pl', 'PGML.pl', - 'niceTables.pl', 'answerHints.pl', + 'niceTables.pl', 'answerHints.pl', 'weightedGrader.pl', 'PGcourse.pl' ); @@ -91,13 +91,22 @@

POD for Macro Files

$int = Compute('(pi x^2 - pi x^4) dx'); $vol = Compute('2pi/15'); -$integral = LayoutTable([ - [ ' ', NAMED_ANS_RULE('upperlimit', 4)], - ['\(V= \)','\(\displaystyle \int \;\;\)' . NAMED_ANS_RULE('integrand', 10) - . '\(\;=\; \)' . NAMED_ANS_RULE('volume', 4)], - [ ' ',NAMED_ANS_RULE('lowerlimit', 4)], -], - align => 'rl', valign => 'middle', allcellcss => {padding => '3pt'}); +$integral = LayoutTable( + [ + [ ' ', NAMED_ANS_RULE('upperlimit', 4) ], + [ + '\(V= \)', + '\(\displaystyle \int \;\;\)' + . NAMED_ANS_RULE('integrand', 10) + . '\(\;=\; \)' + . NAMED_ANS_RULE('volume', 4) + ], + [ ' ', NAMED_ANS_RULE('lowerlimit', 4) ], + ], + align => 'rl', + valign => 'middle', + allcellcss => { padding => '3pt' } +); @weights = (5, 5, 40, 50);" aria-label="copy to clipboard"> POD for Macro Files $int = Compute('(pi x^2 - pi x^4) dx'); $vol = Compute('2pi/15'); -$integral = LayoutTable([ - [ ' ', NAMED_ANS_RULE('upperlimit', 4)], - ['\(V= \)','\(\displaystyle \int \;\;\)' . NAMED_ANS_RULE('integrand', 10) - . '\(\;=\; \)' . NAMED_ANS_RULE('volume', 4)], - [ ' ',NAMED_ANS_RULE('lowerlimit', 4)], -], - align => 'rl', valign => 'middle', allcellcss => {padding => '3pt'}); +$integral = LayoutTable( + [ + [ ' ', NAMED_ANS_RULE('upperlimit', 4) ], + [ + '\(V= \)', + '\(\displaystyle \int \;\;\)' + . NAMED_ANS_RULE('integrand', 10) + . '\(\;=\; \)' + . NAMED_ANS_RULE('volume', 4) + ], + [ ' ', NAMED_ANS_RULE('lowerlimit', 4) ], + ], + align => 'rl', + valign => 'middle', + allcellcss => { padding => '3pt' } +); @weights = (5, 5, 40, 50);
@@ -269,7 +287,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/IntegralCalc/VolumeOfRevolution.pg b/sample-problems/IntegralCalc/VolumeOfRevolution.pg index 99eb1a3..8b91e47 100644 --- a/sample-problems/IntegralCalc/VolumeOfRevolution.pg +++ b/sample-problems/IntegralCalc/VolumeOfRevolution.pg @@ -2,7 +2,7 @@ DOCUMENT(); loadMacros( 'PGstandard.pl', 'PGML.pl', - 'niceTables.pl', 'answerHints.pl', + 'niceTables.pl', 'answerHints.pl', 'weightedGrader.pl', 'PGcourse.pl' ); @@ -15,13 +15,22 @@ $lower = Real('0'); $int = Compute('(pi x^2 - pi x^4) dx'); $vol = Compute('2pi/15'); -$integral = LayoutTable([ - [ ' ', NAMED_ANS_RULE('upperlimit', 4)], - ['\(V= \)','\(\displaystyle \int \;\;\)' . NAMED_ANS_RULE('integrand', 10) - . '\(\;=\; \)' . NAMED_ANS_RULE('volume', 4)], - [ ' ',NAMED_ANS_RULE('lowerlimit', 4)], -], - align => 'rl', valign => 'middle', allcellcss => {padding => '3pt'}); +$integral = LayoutTable( + [ + [ ' ', NAMED_ANS_RULE('upperlimit', 4) ], + [ + '\(V= \)', + '\(\displaystyle \int \;\;\)' + . NAMED_ANS_RULE('integrand', 10) + . '\(\;=\; \)' + . NAMED_ANS_RULE('volume', 4) + ], + [ ' ', NAMED_ANS_RULE('lowerlimit', 4) ], + ], + align => 'rl', + valign => 'middle', + allcellcss => { padding => '3pt' } +); @weights = (5, 5, 40, 50); BEGIN_PGML diff --git a/sample-problems/LinearAlgebra/MatrixAnswer1.html b/sample-problems/LinearAlgebra/MatrixAnswer1.html index f059dc8..0243308 100644 --- a/sample-problems/LinearAlgebra/MatrixAnswer1.html +++ b/sample-problems/LinearAlgebra/MatrixAnswer1.html @@ -168,7 +168,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/LinearAlgebra/MatrixAnswer2.html b/sample-problems/LinearAlgebra/MatrixAnswer2.html index 4c087be..f65bfa4 100644 --- a/sample-problems/LinearAlgebra/MatrixAnswer2.html +++ b/sample-problems/LinearAlgebra/MatrixAnswer2.html @@ -250,7 +250,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/LinearAlgebra/MatrixCustomAnswerChecker.html b/sample-problems/LinearAlgebra/MatrixCustomAnswerChecker.html index 938ca0f..3ee4acc 100644 --- a/sample-problems/LinearAlgebra/MatrixCustomAnswerChecker.html +++ b/sample-problems/LinearAlgebra/MatrixCustomAnswerChecker.html @@ -182,7 +182,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/LinearAlgebra/MatrixOperations.html b/sample-problems/LinearAlgebra/MatrixOperations.html index 9ae3571..2e3b73e 100644 --- a/sample-problems/LinearAlgebra/MatrixOperations.html +++ b/sample-problems/LinearAlgebra/MatrixOperations.html @@ -242,7 +242,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/LinearAlgebra/RowOperations.html b/sample-problems/LinearAlgebra/RowOperations.html index b0b5cbe..626407b 100644 --- a/sample-problems/LinearAlgebra/RowOperations.html +++ b/sample-problems/LinearAlgebra/RowOperations.html @@ -145,7 +145,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/ChemicalReaction.html b/sample-problems/Misc/ChemicalReaction.html index 854c62e..3c4dd96 100644 --- a/sample-problems/Misc/ChemicalReaction.html +++ b/sample-problems/Misc/ChemicalReaction.html @@ -176,7 +176,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/DraggableProof.html b/sample-problems/Misc/DraggableProof.html index f414658..af19dec 100644 --- a/sample-problems/Misc/DraggableProof.html +++ b/sample-problems/Misc/DraggableProof.html @@ -180,7 +180,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/DynamicGraphPolygon.html b/sample-problems/Misc/DynamicGraphPolygon.html new file mode 100644 index 0000000..9bff4e2 --- /dev/null +++ b/sample-problems/Misc/DynamicGraphPolygon.html @@ -0,0 +1,286 @@ + + + + + + + DynamicGraphPolygon.pg + + + + + + + + + + +
+
+
+

Shaded Polygon Graph

+

Dynamically generated graph of a function

+
+ +
+
+
+

Complete Code

+

+ Download file: DynamicGraphPolygon.pg +

+
+
+

POD for Macro Files

+ +
+
+

See Also

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros('PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'PGcourse.pl');
+
+
+
+

Preamble

+

The dynamic graphs are generated with PGtikz.pl, so this is needed.

+
+
+
+
+ +
# The setup for each plot is the same, so we'll use a perl block for this.
+$plot_setup = qq/
+\tikzset{>={Stealth[scale=1.5]}}
+\filldraw[
+    draw=LightBlue,
+    fill=white,
+    rounded corners=10pt,
+    thick,use as bounding box
+] (-5,5) rectangle (5,-5);
+\draw[lightgray, dashed] (-5,-5) grid (5,5);
+\draw (-5,0) -- (5,0) node [below left] {\(x\)};
+\foreach \x in {-4,...,-1,1,2,...,4} \draw(\x,-4.5) node {\(\x\)};
+\draw (0,-5) -- (0,5) node [below right] {\(y\)};
+\foreach \y in {-4,...,-1,1,2,...,4} \draw(-4.5,\y) node {\(\y\)};
+/;
+
+# The vertices of the triangle chosen randomly will be ($x0,$y0), ($x1,$y0)
+# and ($x0,$y1).
+$x0 = random(-3, -1);
+$x1 = random(1,  3);
+$y0 = random(-3, -1);
+$y1 = random(1,  3);
+
+$graph1 = createTikZImage();
+$graph1->tikzLibraries('arrows.meta');
+$graph1->BEGIN_TIKZ
+$plot_setup;
+\filldraw[very thick, fill=LightGreen, draw=DarkGreen, opacity=0.5] ($x0,$y0)
+    -- ($x1,$y0) -- ($x0,$y1) -- cycle;
+END_TIKZ
+
+# A plot of 1+sqrt(x) and shade underneath the graph.
+
+$graph2 = createTikZImage();
+$graph2->tikzLibraries('arrows.meta');
+$graph2->BEGIN_TIKZ
+$plot_setup;
+
+\filldraw[fill=LightBlue, opacity=0.5, draw=blue] (1,1)
+    -- plot[domain=1:4, smooth] (\x,{1+sqrt(\x)})
+    -- (4,0) -- (1,0) -- cycle;
+\draw[very thick, DarkBlue] plot [domain=0:5, smooth] (\x,{1+sqrt(\x)});
+END_TIKZ
+
+# A circle with center ($x0,$y0)
+$x = random(-2, 2);
+$y = random(-2, 2);
+
+$graph3 = createTikZImage();
+$graph3->tikzLibraries('arrows.meta');
+$graph3->BEGIN_TIKZ
+$plot_setup;
+
+\filldraw[very thick, fill=LightSalmon, opacity=0.5, draw=DarkOrange]
+    circle[radius=3] ($x,$y);
+END_TIKZ
+
+
+
+

Setup

+

See Dynamic Graph for basics of using tikz.

+

Since we make three plots with the same setup, all of the commands that are common to the graphs are defined in the same perl string.

+

Each of the plots uses the \filldraw command. Options for this are

+
    +
  • fill: the color of the fill region
  • +
  • draw: the color of the boundary.
  • +
  • very thick: the thickness of the boundary
  • +
  • opacity: the opacity (between 0 and 1) of the fill region.
  • +
+

In the polygon and region under the curve, the draw method uses the verticies (or the plot command which uses the curve itself) and ends with cycle indicated that the region is closed.

+

The colors are defined in the LaTeX xcolor package

+
+
+
+
+ +
BEGIN_PGML
+
+[@ image($graph1, width => 400) @]*
+
+[@ image($graph2, width => 400) @]*
+
+[@ image($graph3, width => 400) @]*
+
+END_PGML
+
+
+
+

Statement

+

Note that the tikz graph in $graph1, $graph2 and $graph3 to be shown is placed in the image function and since this is a function, it must go in a [@ ... @]* block.

+
+
+
+
+ +
BEGIN_PGML_SOLUTION
+Solution explanation goes here.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Misc/DynamicGraphPolygon.pg b/sample-problems/Misc/DynamicGraphPolygon.pg new file mode 100644 index 0000000..cc0475c --- /dev/null +++ b/sample-problems/Misc/DynamicGraphPolygon.pg @@ -0,0 +1,76 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'PGcourse.pl'); + +# The setup for each plot is the same, so we'll use a perl block for this. +$plot_setup = qq/ +\tikzset{>={Stealth[scale=1.5]}} +\filldraw[ + draw=LightBlue, + fill=white, + rounded corners=10pt, + thick,use as bounding box +] (-5,5) rectangle (5,-5); +\draw[lightgray, dashed] (-5,-5) grid (5,5); +\draw (-5,0) -- (5,0) node [below left] {\(x\)}; +\foreach \x in {-4,...,-1,1,2,...,4} \draw(\x,-4.5) node {\(\x\)}; +\draw (0,-5) -- (0,5) node [below right] {\(y\)}; +\foreach \y in {-4,...,-1,1,2,...,4} \draw(-4.5,\y) node {\(\y\)}; +/; + +# The vertices of the triangle chosen randomly will be ($x0,$y0), ($x1,$y0) +# and ($x0,$y1). +$x0 = random(-3, -1); +$x1 = random(1, 3); +$y0 = random(-3, -1); +$y1 = random(1, 3); + +$graph1 = createTikZImage(); +$graph1->tikzLibraries('arrows.meta'); +$graph1->BEGIN_TIKZ +$plot_setup; +\filldraw[very thick, fill=LightGreen, draw=DarkGreen, opacity=0.5] ($x0,$y0) + -- ($x1,$y0) -- ($x0,$y1) -- cycle; +END_TIKZ + +# A plot of 1+sqrt(x) and shade underneath the graph. + +$graph2 = createTikZImage(); +$graph2->tikzLibraries('arrows.meta'); +$graph2->BEGIN_TIKZ +$plot_setup; + +\filldraw[fill=LightBlue, opacity=0.5, draw=blue] (1,1) + -- plot[domain=1:4, smooth] (\x,{1+sqrt(\x)}) + -- (4,0) -- (1,0) -- cycle; +\draw[very thick, DarkBlue] plot [domain=0:5, smooth] (\x,{1+sqrt(\x)}); +END_TIKZ + +# A circle with center ($x0,$y0) +$x = random(-2, 2); +$y = random(-2, 2); + +$graph3 = createTikZImage(); +$graph3->tikzLibraries('arrows.meta'); +$graph3->BEGIN_TIKZ +$plot_setup; + +\filldraw[very thick, fill=LightSalmon, opacity=0.5, draw=DarkOrange] + circle[radius=3] ($x,$y); +END_TIKZ + +BEGIN_PGML + +[@ image($graph1, width => 400) @]* + +[@ image($graph2, width => 400) @]* + +[@ image($graph3, width => 400) @]* + +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Misc/EssayAnswer.html b/sample-problems/Misc/EssayAnswer.html index 0ffb9b3..36010dc 100644 --- a/sample-problems/Misc/EssayAnswer.html +++ b/sample-problems/Misc/EssayAnswer.html @@ -159,7 +159,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/FormulaAnswer.html b/sample-problems/Misc/FormulaAnswer.html index 6ee316f..33ba4a4 100644 --- a/sample-problems/Misc/FormulaAnswer.html +++ b/sample-problems/Misc/FormulaAnswer.html @@ -146,7 +146,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/FormulaDomain.html b/sample-problems/Misc/FormulaDomain.html index 27c1b8f..1ae4caa 100644 --- a/sample-problems/Misc/FormulaDomain.html +++ b/sample-problems/Misc/FormulaDomain.html @@ -158,7 +158,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/FormulaTestPoints.html b/sample-problems/Misc/FormulaTestPoints.html index 2da87bf..ebe9b90 100644 --- a/sample-problems/Misc/FormulaTestPoints.html +++ b/sample-problems/Misc/FormulaTestPoints.html @@ -70,10 +70,10 @@

See Also

-
Context()->variables->set(x=>{limits=>[-1,1]});
+					
Context()->variables->set(x => { limits => [ -1, 1 ] });
 
 # Alternately
-Context()->flags->set(limits=>[2,5]);
+Context()->flags->set(limits => [ 2, 5 ]);
 
 $f = Compute('sqrt(x+1)');
 
@@ -105,7 +105,7 @@ 

See Also

# $func->{limits} = [2,5]; $g = Compute("sqrt(x^2 - 4)"); -$g->{test_points} = [[-3],[-2],[2],[3],[4]]; +$g->{test_points} = [ [-3], [-2], [2], [3], [4] ];
@@ -174,7 +174,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/FormulaTestPoints.pg b/sample-problems/Misc/FormulaTestPoints.pg index 1baaf22..4cf12ad 100644 --- a/sample-problems/Misc/FormulaTestPoints.pg +++ b/sample-problems/Misc/FormulaTestPoints.pg @@ -2,10 +2,10 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); -Context()->variables->set(x=>{limits=>[-1,1]}); +Context()->variables->set(x => { limits => [ -1, 1 ] }); # Alternately -Context()->flags->set(limits=>[2,5]); +Context()->flags->set(limits => [ 2, 5 ]); $f = Compute('sqrt(x+1)'); @@ -16,7 +16,7 @@ $f = Compute('sqrt(x+1)'); # $func->{limits} = [2,5]; $g = Compute("sqrt(x^2 - 4)"); -$g->{test_points} = [[-3],[-2],[2],[3],[4]]; +$g->{test_points} = [ [-3], [-2], [2], [3], [4] ]; BEGIN_PGML Enter [`[$f]`] [___]{$f} diff --git a/sample-problems/Misc/IframeEmbedding.html b/sample-problems/Misc/IframeEmbedding.html index 95ab435..07e13ec 100644 --- a/sample-problems/Misc/IframeEmbedding.html +++ b/sample-problems/Misc/IframeEmbedding.html @@ -202,7 +202,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/ManyMultipleChoice.html b/sample-problems/Misc/ManyMultipleChoice.html index 79cd744..937d3a3 100644 --- a/sample-problems/Misc/ManyMultipleChoice.html +++ b/sample-problems/Misc/ManyMultipleChoice.html @@ -218,7 +218,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/Matching.html b/sample-problems/Misc/Matching.html index 9d09204..0c8b910 100644 --- a/sample-problems/Misc/Matching.html +++ b/sample-problems/Misc/Matching.html @@ -79,8 +79,7 @@

POD for Macro Files

-
-$showPartialCorrectAnswers = 0;
+					
$showPartialCorrectAnswers = 0;
 
 # Incremental grader
 install_problem_grader(~~&custom_problem_grader_fluid);
@@ -199,7 +197,7 @@ 

POD for Macro Files

This problem uses an incremental grader called the custom_problem_grader_fluid. With this problem grader, the number of correct answers [2, 4, 6] and their corresponding scores [0.3, 0.6, 1] must be specified. The last entry in the grader_numright array must be the total number of questions asked, and the last entry in the grader_scores array must be 1 (otherwise nobody can earn full credit!). The grader message can also be customized by setting the value of grader_message to the desired custom message.

If a grader is desired that awards full credit when all questions are correct and no credit otherwise, use the commented out standard problem grader code instead.

Create a list of 6 questions and answers, 2 extra answers, and a ‘None of the above’ answer that will be made last with makeLast. So the popup list must have 9 entries A through I.

-

For more details, see MatchingProblems from the Problem Techniques documentation.

+

As an alternative, see Matching Problem (Alternate) for another way to write a matching problem.

@@ -284,7 +282,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/Matching.pg b/sample-problems/Misc/Matching.pg index 9f1010b..8c430a2 100644 --- a/sample-problems/Misc/Matching.pg +++ b/sample-problems/Misc/Matching.pg @@ -6,7 +6,6 @@ loadMacros( 'unionTables.pl', 'PGcourse.pl' ); - $showPartialCorrectAnswers = 0; # Incremental grader diff --git a/sample-problems/Misc/MatchingAlt.html b/sample-problems/Misc/MatchingAlt.html index ad4df85..0dd82b9 100644 --- a/sample-problems/Misc/MatchingAlt.html +++ b/sample-problems/Misc/MatchingAlt.html @@ -306,7 +306,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/MatchingGraphs.html b/sample-problems/Misc/MatchingGraphs.html new file mode 100644 index 0000000..2b9bd73 --- /dev/null +++ b/sample-problems/Misc/MatchingGraphs.html @@ -0,0 +1,391 @@ + + + + + + + MatchingGraphs.pg + + + + + + + + + + +
+
+
+

Matching Problem with Graphs

+

Matching problem with graphs

+
+ +
+
+
+

Complete Code

+

+ Download file: MatchingGraphs.pg +

+
+
+

POD for Macro Files

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros(
+    'PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'parserPopUp.pl',
+    'niceTables.pl', 'PGcourse.pl'
+);
+
+
+
+

Preamble

+

The dynamic graph is generated with PGtikz.pl, so this is needed. The matching is done with popups, so parserPopUp.pl is need and lastly a LayoutTable is used from niceTables.pl.

+
+
+
+
+ +
@all_plots = (
+    {
+        f      => 'x^2',
+        form   => '\x*\x',
+        domain => '-3:3',
+        alt    =>
+            'A graph of a curve with a minimum at the origin and opening '
+            . 'upward.'
+    },
+    {
+        f      => 'e^x',
+        form   => 'exp(\x)',
+        domain => '-6:3',
+        alt    => 'A graph of a curve starting near the negative x axis and '
+            . 'rising steeply toward the first quadrant.'
+    },
+    {
+        f      => 'x^3',
+        form   => '\x*\x*\x',
+        domain => '-2:2',
+        alt    => 'A graph of a curve from the third quadrant (where is it '
+            . 'concave down) to the first quadrant (where it is concave up).'
+    },
+    {
+        f      => 'ln(x)',
+        form   => 'ln(\x)',
+        domain => '0.1:6',
+        alt    => 'A graph of a curve that approaches the negative y-axis '
+            . 'and rises to the first quadrant and everywhere it is concave'
+            . 'down.'
+    },
+    {
+        f      => '3x+2',
+        form   => '3*\x+2',
+        domain => '-6:6',
+        alt    =>
+            'The graph of a line from the 3rd quadrant to the first quadrant'
+    },
+    {
+        f      => 'sin(x)',
+        form   => 'sin(\x r)',
+        domain => '-6:6',
+        alt    => 'A graph of a curve that osciallates and passes through the '
+            . 'origin'
+    },
+);
+
+for $i (0 .. $#all_plots) {
+    my $graph = createTikZImage();
+    $graph->tikzLibraries('arrows.meta');
+    $graph->BEGIN_TIKZ
+    \tikzset{>={Stealth[scale=1.5]}}
+    \filldraw[
+        draw=LightBlue,
+        fill=white,
+        rounded corners=10pt,
+        thick,use as bounding box
+    ] (-7,-7) rectangle (7,7);
+    \draw[->,thick] (-6,0) -- (6,0) node[above left,outer sep=3pt] {\(x\)};
+    \foreach \x in {-5,...,-1,1,2,...,5}
+        \draw(\x,5pt) -- (\x,-5pt) node [below] {\(\x\)};
+    \draw[->,thick] (0,-6) -- (0,6) node[below right,outer sep=3pt] {\(y\)};
+    \foreach \y in {-5,...,-1,1,2,...,5}
+        \draw (5pt,\y) -- (-5pt,\y) node[left] {\(\y\)};
+    \draw[blue,ultra thick] plot[domain=$all_plots[$i]->{domain},smooth] (\x,{$all_plots[$i]->{form}});
+END_TIKZ
+    $all_plots[$i]->{graph} = $graph;
+}
+
+@plots = random_subset(4, @all_plots);
+
+# sorted list of possible answers
+$list = [ lex_sort(map {"$_->{f}"} @all_plots) ];
+
+@dropdowns = map { DropDown($list, "$_->{f}") } @plots;
+
+$tab = LayoutTable(
+    [
+        [
+            map {
+                image(
+                    $plots[$_]->{graph},
+                    width           => 300,
+                    tex_size        => 400,
+                    extra_html_tags => "alt = '$plots[$_]->{alt}'"
+                )
+            } (0 .. 1)
+        ],
+        [ map { $dropdowns[$_]->menu } (0 .. 1) ],
+        [
+            map {
+                image(
+                    $plots[$_]->{graph},
+                    width           => 300,
+                    tex_size        => 400,
+                    extra_html_tags => "alt = '$plots[$_]->{alt}'"
+                )
+            } (2 .. 3)
+        ],
+        [ map { $dropdowns[$_]->menu } (2 .. 3) ]
+
+    ],
+    align => 'cc'
+);
+
+$showPartialCorrectAnswers = 0;
+
+
+
+

Setup

+

The array @all_plots contains the display form (f) of the function, the functional form (form) of the function needed in tikz format, the domain of the function and the alterative text.

+

The graphs of all plots and then created by calling commands from PGtikz.pl. See Dynamic Graph for a simpler example using tikz. Note that alternate text is provided to the image command and for accessibility should always be considered and this should be provided.

+

The dropdowns are created in the @dropdown array which pulls all options.

+

The LayoutTable is used to make an accessible table that is nicely laid out.

+

Although this matching problem creates graphs dynamically, these can use static images by changing the call to image to just pass in the image names.

+
+
+
+
+ +
BEGIN_PGML
+Match the graph with the formula for the graph (Click on image for a larger view.)
+
+[$tab]*
+END_PGML
+
+
+
+

Statement

+ This is the problem statement in PGML. +
+
+
+
+ +
ANS($dropdowns[$_]->cmp) for (0 .. 3);
+
+
+
+

Answer

+

Because the dropdowns are created in the older fashion, we use the ANS form to check the answer

+
+
+
+
+ +
BEGIN_PGML_SOLUTION
+Solution explanation goes here.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Misc/MatchingGraphs.pg b/sample-problems/Misc/MatchingGraphs.pg new file mode 100644 index 0000000..ccad48b --- /dev/null +++ b/sample-problems/Misc/MatchingGraphs.pg @@ -0,0 +1,127 @@ +DOCUMENT(); + +loadMacros( + 'PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'parserPopUp.pl', + 'niceTables.pl', 'PGcourse.pl' +); + +@all_plots = ( + { + f => 'x^2', + form => '\x*\x', + domain => '-3:3', + alt => + 'A graph of a curve with a minimum at the origin and opening ' + . 'upward.' + }, + { + f => 'e^x', + form => 'exp(\x)', + domain => '-6:3', + alt => 'A graph of a curve starting near the negative x axis and ' + . 'rising steeply toward the first quadrant.' + }, + { + f => 'x^3', + form => '\x*\x*\x', + domain => '-2:2', + alt => 'A graph of a curve from the third quadrant (where is it ' + . 'concave down) to the first quadrant (where it is concave up).' + }, + { + f => 'ln(x)', + form => 'ln(\x)', + domain => '0.1:6', + alt => 'A graph of a curve that approaches the negative y-axis ' + . 'and rises to the first quadrant and everywhere it is concave' + . 'down.' + }, + { + f => '3x+2', + form => '3*\x+2', + domain => '-6:6', + alt => + 'The graph of a line from the 3rd quadrant to the first quadrant' + }, + { + f => 'sin(x)', + form => 'sin(\x r)', + domain => '-6:6', + alt => 'A graph of a curve that osciallates and passes through the ' + . 'origin' + }, +); + +for $i (0 .. $#all_plots) { + my $graph = createTikZImage(); + $graph->tikzLibraries('arrows.meta'); + $graph->BEGIN_TIKZ + \tikzset{>={Stealth[scale=1.5]}} + \filldraw[ + draw=LightBlue, + fill=white, + rounded corners=10pt, + thick,use as bounding box + ] (-7,-7) rectangle (7,7); + \draw[->,thick] (-6,0) -- (6,0) node[above left,outer sep=3pt] {\(x\)}; + \foreach \x in {-5,...,-1,1,2,...,5} + \draw(\x,5pt) -- (\x,-5pt) node [below] {\(\x\)}; + \draw[->,thick] (0,-6) -- (0,6) node[below right,outer sep=3pt] {\(y\)}; + \foreach \y in {-5,...,-1,1,2,...,5} + \draw (5pt,\y) -- (-5pt,\y) node[left] {\(\y\)}; + \draw[blue,ultra thick] plot[domain=$all_plots[$i]->{domain},smooth] (\x,{$all_plots[$i]->{form}}); +END_TIKZ + $all_plots[$i]->{graph} = $graph; +} + +@plots = random_subset(4, @all_plots); + +# sorted list of possible answers +$list = [ lex_sort(map {"$_->{f}"} @all_plots) ]; + +@dropdowns = map { DropDown($list, "$_->{f}") } @plots; + +$tab = LayoutTable( + [ + [ + map { + image( + $plots[$_]->{graph}, + width => 300, + tex_size => 400, + extra_html_tags => "alt = '$plots[$_]->{alt}'" + ) + } (0 .. 1) + ], + [ map { $dropdowns[$_]->menu } (0 .. 1) ], + [ + map { + image( + $plots[$_]->{graph}, + width => 300, + tex_size => 400, + extra_html_tags => "alt = '$plots[$_]->{alt}'" + ) + } (2 .. 3) + ], + [ map { $dropdowns[$_]->menu } (2 .. 3) ] + + ], + align => 'cc' +); + +$showPartialCorrectAnswers = 0; + +BEGIN_PGML +Match the graph with the formula for the graph (Click on image for a larger view.) + +[$tab]* +END_PGML + +ANS($dropdowns[$_]->cmp) for (0 .. 3); + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Misc/MultipleChoiceCheckbox.html b/sample-problems/Misc/MultipleChoiceCheckbox.html index 8342d16..7f7103e 100644 --- a/sample-problems/Misc/MultipleChoiceCheckbox.html +++ b/sample-problems/Misc/MultipleChoiceCheckbox.html @@ -248,7 +248,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/MultipleChoicePopup.html b/sample-problems/Misc/MultipleChoicePopup.html index de5023c..6910578 100644 --- a/sample-problems/Misc/MultipleChoicePopup.html +++ b/sample-problems/Misc/MultipleChoicePopup.html @@ -185,7 +185,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/MultipleChoiceRadio.html b/sample-problems/Misc/MultipleChoiceRadio.html index 2419cfb..09a8f37 100644 --- a/sample-problems/Misc/MultipleChoiceRadio.html +++ b/sample-problems/Misc/MultipleChoiceRadio.html @@ -183,7 +183,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/RandomPerson.html b/sample-problems/Misc/RandomPerson.html index c74ae0e..d34dbbe 100644 --- a/sample-problems/Misc/RandomPerson.html +++ b/sample-problems/Misc/RandomPerson.html @@ -164,7 +164,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Misc/Scaffolding.html b/sample-problems/Misc/Scaffolding.html index 581c758..8252c9d 100644 --- a/sample-problems/Misc/Scaffolding.html +++ b/sample-problems/Misc/Scaffolding.html @@ -184,7 +184,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/ParametricEquationAnswers.html b/sample-problems/Parametric/ParametricEquationAnswers.html new file mode 100644 index 0000000..3440850 --- /dev/null +++ b/sample-problems/Parametric/ParametricEquationAnswers.html @@ -0,0 +1,249 @@ + + + + + + + ParametricEquationAnswers.pg + + + + + + + + + + +
+
+
+

Parametric Equation Answer Checker

+

Check student answers that are parametric equations

+
+ +
+
+
+

Complete Code

+

+ Download file: ParametricEquationAnswers.pg +

+
+
+

POD for Macro Files

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros('PGstandard.pl', 'PGML.pl', 'parserMultiAnswer.pl', 'PGcourse.pl');
+
+
+
+

Preamble

+

Since there are multiple ways to parameterize, we use the parserMultiAnswer.pl macro.

+
+
+
+
+ +
Context("Numeric")->variables->are(t => "Real");
+Context()->variables->set(t => { limits => [ -5, 5 ] });
+
+$x  = Formula("cos(t)");
+$y  = Formula("sin(t)");
+$t0 = Compute("0");
+$t1 = Compute("pi/3");
+
+($x0, $y0) = (1, 0);
+($x1, $y1) = (1 / 2, sqrt(3) / 2);
+
+$multians = MultiAnswer($x, $y, $t0, $t1)->with(
+    singleResult => 0,
+    checker      => sub {
+        my ($correct, $student, $self) = @_;
+        my ($xstu, $ystu, $t0stu, $t1stu) = @{$student};
+        if ((($xstu**2 + $ystu**2) == 1)
+            && (($xstu->eval(t => $t0stu)) == $x0)
+            && (($ystu->eval(t => $t0stu)) == $y0)
+            && (($xstu->eval(t => $t1stu)) == $x1)
+            && (($ystu->eval(t => $t1stu)) == $y1))
+        {
+            return [ 1, 1, 1, 1 ];
+
+        } elsif ((($xstu**2 + $ystu**2) == 1)
+            && (($xstu->eval(t => $t0stu)) == $x0)
+            && (($ystu->eval(t => $t0stu)) == $y0))
+        {
+            return [ 1, 1, 1, 0 ];
+
+        } elsif ((($xstu**2 + $ystu**2) == 1)
+            && (($xstu->eval(t => $t1stu)) == $x1)
+            && (($ystu->eval(t => $t1stu)) == $y1))
+        {
+            return [ 1, 1, 0, 1 ];
+
+        } elsif ((($xstu**2 + $ystu**2) == 1)) {
+            return [ 1, 1, 0, 0 ];
+
+        } else {
+            return [ 0, 0, 0, 0 ];
+        }
+    }
+);
+
+
+

Setup

+

We use a MultiAnswer() answer checker that will verify that the students answers satisfy the equation for the circle and have the required starting and ending points. This answer checker will allow students to enter any correct parametrization. For example, both x = (t), y = sin(t), 0 ≤ t ≤ pi/3 and x = cos(2t), y = sin(2t), 0 ≤ t ≤ pi/6 will be marked correct.

+

When evaluating student’s answers, it is important not to use quotes. For example, if the code were $xstu->eval(t=>"$t1stu") with quotes, then if a student enters pi the answer checker will interpret it as the string “pi” which will need to be converted to a MathObject Real and numerical error will be introduced in the conversion. The correct code to use is $xstu->eval(t=>$t1stu) without quotes so that the answer is interpreted without a conversion that may introduce error.

+

The first if statement is fully correct, that is the parametric functions are on the unit circle and the initial and final points are correct. The other three ifelse in the answer checker has either the second point, first point or both points wrong.

+
+
+
+
+ +
BEGIN_PGML
+Find a parametrization of the unit circle from the point
+[` \big(1,0\big) `] to [` \big(\frac{1}{2},\frac{\sqrt{3}}{2}\big) `].
+Use [` t `] as the parameter for your answers.
+
+[` x(t) = `] [__]{$multians}
+
+[` y(t) = `] [__]{$multians}
+
+for [__]{$multians} to [__]{$multians}.
+END_PGML
+
+
+
+

Statement

+

Since the correct answer depends on all answer blanks, the MathObject $multians is input into all answer blanks.

+
+
+
+
+ +
BEGIN_PGML_SOLUTION
+Solution explanation goes here.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Parametric/ParametricEquationAnswers.pg b/sample-problems/Parametric/ParametricEquationAnswers.pg new file mode 100644 index 0000000..8813f2c --- /dev/null +++ b/sample-problems/Parametric/ParametricEquationAnswers.pg @@ -0,0 +1,65 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'parserMultiAnswer.pl', 'PGcourse.pl'); + +Context("Numeric")->variables->are(t => "Real"); +Context()->variables->set(t => { limits => [ -5, 5 ] }); + +$x = Formula("cos(t)"); +$y = Formula("sin(t)"); +$t0 = Compute("0"); +$t1 = Compute("pi/3"); + +($x0, $y0) = (1, 0); +($x1, $y1) = (1 / 2, sqrt(3) / 2); + +$multians = MultiAnswer($x, $y, $t0, $t1)->with( + singleResult => 0, + checker => sub { + my ($correct, $student, $self) = @_; + my ($xstu, $ystu, $t0stu, $t1stu) = @{$student}; + if ((($xstu**2 + $ystu**2) == 1) + && (($xstu->eval(t => $t0stu)) == $x0) + && (($ystu->eval(t => $t0stu)) == $y0) + && (($xstu->eval(t => $t1stu)) == $x1) + && (($ystu->eval(t => $t1stu)) == $y1)) + { + return [ 1, 1, 1, 1 ]; + + } elsif ((($xstu**2 + $ystu**2) == 1) + && (($xstu->eval(t => $t0stu)) == $x0) + && (($ystu->eval(t => $t0stu)) == $y0)) + { + return [ 1, 1, 1, 0 ]; + + } elsif ((($xstu**2 + $ystu**2) == 1) + && (($xstu->eval(t => $t1stu)) == $x1) + && (($ystu->eval(t => $t1stu)) == $y1)) + { + return [ 1, 1, 0, 1 ]; + + } elsif ((($xstu**2 + $ystu**2) == 1)) { + return [ 1, 1, 0, 0 ]; + + } else { + return [ 0, 0, 0, 0 ]; + } + } +); +BEGIN_PGML +Find a parametrization of the unit circle from the point +[` \big(1,0\big) `] to [` \big(\frac{1}{2},\frac{\sqrt{3}}{2}\big) `]. +Use [` t `] as the parameter for your answers. + +[` x(t) = `] [__]{$multians} + +[` y(t) = `] [__]{$multians} + +for [__]{$multians} to [__]{$multians}. +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Parametric/ParametricPlot.html b/sample-problems/Parametric/ParametricPlot.html index 4193710..04a5376 100644 --- a/sample-problems/Parametric/ParametricPlot.html +++ b/sample-problems/Parametric/ParametricPlot.html @@ -90,12 +90,12 @@

POD for Macro Files

({2*sin(2*\t r)},{2*sin(3*\t r)}); END_TIKZ -$x = Compute('2sin(2t)'); +$x = Compute('2sin(2t)'); $x0 = $x->eval(t => 'pi/3'); -$y = Compute('2sin(3t)'); +$y = Compute('2sin(3t)'); $y0 = $y->eval(t => 'pi/3'); -$m = $y->D('t')->eval(t => 'pi/3')/$x->D('t')->eval(t => 'pi/3'); +$m = $y->D('t')->eval(t => 'pi/3') / $x->D('t')->eval(t => 'pi/3'); $line = Compute("$m*(x-$x0)+$y0"); " aria-label="copy to clipboard"> POD for Macro Files ({2*sin(2*\t r)},{2*sin(3*\t r)}); END_TIKZ -$x = Compute('2sin(2t)'); +$x = Compute('2sin(2t)'); $x0 = $x->eval(t => 'pi/3'); -$y = Compute('2sin(3t)'); +$y = Compute('2sin(3t)'); $y0 = $y->eval(t => 'pi/3'); -$m = $y->D('t')->eval(t => 'pi/3')/$x->D('t')->eval(t => 'pi/3'); +$m = $y->D('t')->eval(t => 'pi/3') / $x->D('t')->eval(t => 'pi/3'); $line = Compute("$m*(x-$x0)+$y0");
@@ -218,7 +218,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/ParametricPlot.pg b/sample-problems/Parametric/ParametricPlot.pg index 1fd3ef4..a816818 100644 --- a/sample-problems/Parametric/ParametricPlot.pg +++ b/sample-problems/Parametric/ParametricPlot.pg @@ -23,12 +23,12 @@ $graph->BEGIN_TIKZ ({2*sin(2*\t r)},{2*sin(3*\t r)}); END_TIKZ -$x = Compute('2sin(2t)'); +$x = Compute('2sin(2t)'); $x0 = $x->eval(t => 'pi/3'); -$y = Compute('2sin(3t)'); +$y = Compute('2sin(3t)'); $y0 = $y->eval(t => 'pi/3'); -$m = $y->D('t')->eval(t => 'pi/3')/$x->D('t')->eval(t => 'pi/3'); +$m = $y->D('t')->eval(t => 'pi/3') / $x->D('t')->eval(t => 'pi/3'); $line = Compute("$m*(x-$x0)+$y0"); BEGIN_PGML diff --git a/sample-problems/Parametric/PolarGraph.html b/sample-problems/Parametric/PolarGraph.html index 5c3c9b9..18a25a8 100644 --- a/sample-problems/Parametric/PolarGraph.html +++ b/sample-problems/Parametric/PolarGraph.html @@ -178,7 +178,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/SpaceCurveGraph.html b/sample-problems/Parametric/SpaceCurveGraph.html index 680b158..8b17c92 100644 --- a/sample-problems/Parametric/SpaceCurveGraph.html +++ b/sample-problems/Parametric/SpaceCurveGraph.html @@ -129,7 +129,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/Spacecurve.html b/sample-problems/Parametric/Spacecurve.html index 5426796..d9dbeec 100644 --- a/sample-problems/Parametric/Spacecurve.html +++ b/sample-problems/Parametric/Spacecurve.html @@ -19,7 +19,7 @@
-

Polar Graph

+

Space Curve

Parametric equations: parametric curve in space

@@ -191,7 +191,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/SurfaceGraph.html b/sample-problems/Parametric/SurfaceGraph.html index 61fb0ec..f1d86e6 100644 --- a/sample-problems/Parametric/SurfaceGraph.html +++ b/sample-problems/Parametric/SurfaceGraph.html @@ -137,7 +137,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/VectorParametricDerivative.html b/sample-problems/Parametric/VectorParametricDerivative.html index dcff7bf..e296fd6 100644 --- a/sample-problems/Parametric/VectorParametricDerivative.html +++ b/sample-problems/Parametric/VectorParametricDerivative.html @@ -175,7 +175,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/VectorParametricFunction.html b/sample-problems/Parametric/VectorParametricFunction.html index 79a18e1..ff5a221 100644 --- a/sample-problems/Parametric/VectorParametricFunction.html +++ b/sample-problems/Parametric/VectorParametricFunction.html @@ -233,7 +233,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/VectorParametricLines.html b/sample-problems/Parametric/VectorParametricLines.html index f42ccaa..8a1591a 100644 --- a/sample-problems/Parametric/VectorParametricLines.html +++ b/sample-problems/Parametric/VectorParametricLines.html @@ -51,8 +51,9 @@

POD for Macro Files

type="button" data-code="DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'parserVectorUtils.pl', - 'parserParametricLine.pl', 'PGcourse.pl' + 'PGstandard.pl', 'PGML.pl', + 'parserVectorUtils.pl', 'parserParametricLine.pl', + 'PGcourse.pl' ); " aria-label="copy to clipboard"> POD for Macro Files
DOCUMENT();
 
 loadMacros(
-    'PGstandard.pl',           'PGML.pl', 'parserVectorUtils.pl',
-    'parserParametricLine.pl', 'PGcourse.pl'
+    'PGstandard.pl',        'PGML.pl',
+    'parserVectorUtils.pl', 'parserParametricLine.pl',
+    'PGcourse.pl'
 );
 
@@ -185,7 +187,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Parametric/VectorParametricLines.pg b/sample-problems/Parametric/VectorParametricLines.pg index 29f2dc5..a4fd33a 100644 --- a/sample-problems/Parametric/VectorParametricLines.pg +++ b/sample-problems/Parametric/VectorParametricLines.pg @@ -1,8 +1,9 @@ DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'parserVectorUtils.pl', - 'parserParametricLine.pl', 'PGcourse.pl' + 'PGstandard.pl', 'PGML.pl', + 'parserVectorUtils.pl', 'parserParametricLine.pl', + 'PGcourse.pl' ); Context('Vector')->variables->are(t => 'Real'); diff --git a/sample-problems/Sequences/AnswerOrderedList.html b/sample-problems/Sequences/AnswerOrderedList.html index 62f87f8..ba5a0b9 100644 --- a/sample-problems/Sequences/AnswerOrderedList.html +++ b/sample-problems/Sequences/AnswerOrderedList.html @@ -63,7 +63,7 @@

Complete Code

-
@seq    = (1, 1);
+					
@seq = (1, 1);
 for $i (2 .. 6) {
     $seq[$i] = $seq[ $i - 1 ] + $seq[ $i - 2 ];
 }
@@ -151,7 +151,8 @@ 

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Sequences/AnswerOrderedList.pg b/sample-problems/Sequences/AnswerOrderedList.pg index 5929256..c4603fa 100644 --- a/sample-problems/Sequences/AnswerOrderedList.pg +++ b/sample-problems/Sequences/AnswerOrderedList.pg @@ -2,7 +2,7 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); -@seq = (1, 1); +@seq = (1, 1); for $i (2 .. 6) { $seq[$i] = $seq[ $i - 1 ] + $seq[ $i - 2 ]; } diff --git a/sample-problems/Sequences/ExplicitSequence.html b/sample-problems/Sequences/ExplicitSequence.html index 67c3b65..06da3c2 100644 --- a/sample-problems/Sequences/ExplicitSequence.html +++ b/sample-problems/Sequences/ExplicitSequence.html @@ -176,7 +176,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Sequences/RecursiveSequence.html b/sample-problems/Sequences/RecursiveSequence.html index 119cc2c..e135a25 100644 --- a/sample-problems/Sequences/RecursiveSequence.html +++ b/sample-problems/Sequences/RecursiveSequence.html @@ -150,7 +150,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Sequences/SeriesTest.html b/sample-problems/Sequences/SeriesTest.html index bb1d1d4..91c42cd 100644 --- a/sample-problems/Sequences/SeriesTest.html +++ b/sample-problems/Sequences/SeriesTest.html @@ -53,9 +53,9 @@

POD for Macro Files

type="button" data-code="DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', + 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'parserPopUp.pl', - 'PGgraders.pl', 'parserMultiAnswer.pl', + 'PGgraders.pl', 'parserMultiAnswer.pl', 'PGcourse.pl' ); " aria-label="copy to clipboard"> @@ -67,9 +67,9 @@

POD for Macro Files

DOCUMENT();
 
 loadMacros(
-    'PGstandard.pl',  'PGML.pl',
+    'PGstandard.pl', 'PGML.pl',
     'niceTables.pl', 'parserPopUp.pl',
-    'PGgraders.pl',   'parserMultiAnswer.pl',
+    'PGgraders.pl',  'parserMultiAnswer.pl',
     'PGcourse.pl'
 );
 
@@ -134,8 +134,11 @@

POD for Macro Files

PopUp([ 'Choose', 'Converges', 'Diverges', 'Inconclusive' ], 'Converges'); # Display the fraction and answer blanks nicely -$frac = LayoutTable([[[ans_rule(10), rowbottom => 1]],[ans_rule(10)]], - center => 0, allcellcss => {padding => '4pt'}); +$frac = LayoutTable( + [ [ [ ans_rule(10), rowbottom => 1 ] ], [ ans_rule(10) ] ], + center => 0, + allcellcss => { padding => '4pt' } +); " aria-label="copy to clipboard"> @@ -194,8 +197,11 @@

POD for Macro Files

PopUp([ 'Choose', 'Converges', 'Diverges', 'Inconclusive' ], 'Converges'); # Display the fraction and answer blanks nicely -$frac = LayoutTable([[[ans_rule(10), rowbottom => 1]],[ans_rule(10)]], - center => 0, allcellcss => {padding => '4pt'}); +$frac = LayoutTable( + [ [ [ ans_rule(10), rowbottom => 1 ] ], [ ans_rule(10) ] ], + center => 0, + allcellcss => { padding => '4pt' } +);
@@ -316,7 +322,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Sequences/SeriesTest.pg b/sample-problems/Sequences/SeriesTest.pg index c1a3513..158f216 100644 --- a/sample-problems/Sequences/SeriesTest.pg +++ b/sample-problems/Sequences/SeriesTest.pg @@ -1,9 +1,9 @@ DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', + 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'parserPopUp.pl', - 'PGgraders.pl', 'parserMultiAnswer.pl', + 'PGgraders.pl', 'parserMultiAnswer.pl', 'PGcourse.pl' ); @@ -59,8 +59,11 @@ $popup = PopUp([ 'Choose', 'Converges', 'Diverges', 'Inconclusive' ], 'Converges'); # Display the fraction and answer blanks nicely -$frac = LayoutTable([[[ans_rule(10), rowbottom => 1]],[ans_rule(10)]], - center => 0, allcellcss => {padding => '4pt'}); +$frac = LayoutTable( + [ [ [ ans_rule(10), rowbottom => 1 ] ], [ ans_rule(10) ] ], + center => 0, + allcellcss => { padding => '4pt' } +); BEGIN_PGML Use the limit comparison test to determine whether diff --git a/sample-problems/Statistics/linearRegression.html b/sample-problems/Statistics/linearRegression.html new file mode 100644 index 0000000..2f80f20 --- /dev/null +++ b/sample-problems/Statistics/linearRegression.html @@ -0,0 +1,206 @@ + + + + + + + linearRegression.pg + + + + + + + + + + +
+
+
+

Linear Regression

+

Find the mean and standard deviation of a list of numbers.

+
+ +
+
+
+

Complete Code

+

+ Download file: linearRegression.pg +

+
+
+

POD for Macro Files

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros(
+    "PGstandard.pl",         "PGML.pl",
+    'PGstatisticsmacros.pl', 'niceTables.pl',
+    "PGcourse.pl"
+);
+
+
+
+

Preamble

+

Statistics functions mean and standard deviation are used so we load PGstatisticsmacros.pl. We use the DataTable method from the niceTables.pl macro.

+
+
+
+
+ +
+# produce an approximate slope and intercept
+$m = random(0.1, 0.75, 0.05);
+$b = random(0.5, 5,    0.25);
+
+# Create some random data
+for $i (0 .. 9) {
+    $x[$i] = random(2.5, 7.5, 0.5);
+    $y[$i] = $m * $x[$i] + $b;
+}
+
+@rows = ([ '\(x\)', '\(y\)' ]);
+push(@rows, [ $x[$_], $y[$_] ]) for (0 .. $#x);
+
+$corr = sample_correlation(~~@x, ~~@y);
+($m, $b) = sample_correlation(~~@x, ~~@y);
+
+
+
+

Setup

+

First, generate random numbers and then use the methods sample_correlation and linear_regression from the macro PGstatisticsmacros.pl.

+
+
+
+
+ +
BEGIN_PGML
+Consider the following data:
+
+[@ DataTable(\@rows,
+  padding => [0.25, 0.25], horizontalrules => 1, align => '|c|c|' ) @]*
+
+Find the correlation coefficient and the linear regression line:
+
+a) correlation coefficient: [__]{$corr}
+
+b) linear regression line [`\hat{y}=`] [__]{Formula("$m x + $b")}
+
+END_PGML
+
+
+
+

Statement

+ This is the problem statement in PGML. +
+
+
+
+ +
BEGIN_PGML_SOLUTION
+Provide a solution here.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Statistics/linearRegression.pg b/sample-problems/Statistics/linearRegression.pg new file mode 100644 index 0000000..5aa73ae --- /dev/null +++ b/sample-problems/Statistics/linearRegression.pg @@ -0,0 +1,44 @@ +DOCUMENT(); + +loadMacros( + "PGstandard.pl", "PGML.pl", + 'PGstatisticsmacros.pl', 'niceTables.pl', + "PGcourse.pl" +); + + +# produce an approximate slope and intercept +$m = random(0.1, 0.75, 0.05); +$b = random(0.5, 5, 0.25); + +# Create some random data +for $i (0 .. 9) { + $x[$i] = random(2.5, 7.5, 0.5); + $y[$i] = $m * $x[$i] + $b; +} + +@rows = ([ '\(x\)', '\(y\)' ]); +push(@rows, [ $x[$_], $y[$_] ]) for (0 .. $#x); + +$corr = sample_correlation(~~@x, ~~@y); +($m, $b) = sample_correlation(~~@x, ~~@y); + +BEGIN_PGML +Consider the following data: + +[@ DataTable(\@rows, + padding => [0.25, 0.25], horizontalrules => 1, align => '|c|c|' ) @]* + +Find the correlation coefficient and the linear regression line: + +a) correlation coefficient: [__]{$corr} + +b) linear regression line [`\hat{y}=`] [__]{Formula("$m x + $b")} + +END_PGML + +BEGIN_PGML_SOLUTION +Provide a solution here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Statistics/meanStdDev.html b/sample-problems/Statistics/meanStdDev.html new file mode 100644 index 0000000..60a19aa --- /dev/null +++ b/sample-problems/Statistics/meanStdDev.html @@ -0,0 +1,195 @@ + + + + + + + meanStdDev.pg + + + + + + + + + + +
+
+
+

Mean and Standard Deviation

+

Find the mean and standard deviation of a list of numbers.

+
+ +
+
+
+

Complete Code

+

+ Download file: meanStdDev.pg +

+
+
+

POD for Macro Files

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros("PGstandard.pl", "PGML.pl", 'PGstatisticsmacros.pl', "PGcourse.pl");
+
+
+
+

Preamble

+

Statistics functions mean and standard deviation are used so we load PGstatisticsmacros.pl.

+
+
+
+
+ +
for $i (0 .. 7) {
+    $x[$i] = random(1, 10);
+}
+
+$mean = stats_mean(@x);
+$sd   = stats_sd(@x);
+
+
+
+

Setup

+

First, generate random numbers and then calculate the mean and standard deviation using the methods stats_mean and stats_sd from the macro PGstatisticsmacros.pl.

+
+
+
+
+ +
BEGIN_PGML
+Find the mean and standard deviation of the following list of numbers:
+[@ join(', ', @x) @]
+
+a) Mean = [_____]{$mean}
+
+b) Standard Deviation = [___]{$sd}
+END_PGML
+
+
+
+

Statement

+ This is the problem statement in PGML. +
+
+
+
+ +
($sum_x, $sum_sq) = stats_SX_SXX(@x);
+$var = $sum_sq - ($sum_x**2) / 8;
+
+BEGIN_PGML_SOLUTION
+For the mean, use the formula
+
+[``\bar{x} = \frac{1}{n} \sum_{i=1}^n x_i = \frac{[$sum_x]}{8} = [$mean]``]
+
+For the standard deviation, first, find the variance
+
+[``s^2 = \frac{1}{n-1} \left(\sum_{i=1}^n x_i^2 - \frac{1}{n}(\sum_{i=1}^n x_i)^2\right) =
+\frac{1}{7} \left( [$sum_sq] - \frac{1}{8} ([$sum_x])^2\right) = \frac{[$var]}{7}``]
+
+and taking the square root
+
+[``s = [$sd]``]
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+

We use the method stats_SX_SXX of the PGstatisticsmacros.pl which returns the sum and sum of squares which aids in the solution.

+
+
+
+ + + + + diff --git a/sample-problems/Statistics/meanStdDev.pg b/sample-problems/Statistics/meanStdDev.pg new file mode 100644 index 0000000..bcb90f7 --- /dev/null +++ b/sample-problems/Statistics/meanStdDev.pg @@ -0,0 +1,39 @@ +DOCUMENT(); + +loadMacros("PGstandard.pl", "PGML.pl", 'PGstatisticsmacros.pl', "PGcourse.pl"); + +for $i (0 .. 7) { + $x[$i] = random(1, 10); +} + +$mean = stats_mean(@x); +$sd = stats_sd(@x); + +BEGIN_PGML +Find the mean and standard deviation of the following list of numbers: +[@ join(', ', @x) @] + +a) Mean = [_____]{$mean} + +b) Standard Deviation = [___]{$sd} +END_PGML + +($sum_x, $sum_sq) = stats_SX_SXX(@x); +$var = $sum_sq - ($sum_x**2) / 8; + +BEGIN_PGML_SOLUTION +For the mean, use the formula + +[``\bar{x} = \frac{1}{n} \sum_{i=1}^n x_i = \frac{[$sum_x]}{8} = [$mean]``] + +For the standard deviation, first, find the variance + +[``s^2 = \frac{1}{n-1} \left(\sum_{i=1}^n x_i^2 - \frac{1}{n}(\sum_{i=1}^n x_i)^2\right) = +\frac{1}{7} \left( [$sum_sq] - \frac{1}{8} ([$sum_x])^2\right) = \frac{[$var]}{7}``] + +and taking the square root + +[``s = [$sd]``] +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Trig/DisableFunctionsTrig.html b/sample-problems/Trig/DisableFunctionsTrig.html new file mode 100644 index 0000000..d80fdbe --- /dev/null +++ b/sample-problems/Trig/DisableFunctionsTrig.html @@ -0,0 +1,196 @@ + + + + + + + DisableFunctionsTrig.pg + + + + + + + + + + +
+
+
+

Disabling Functions

+

Disable functions and require exact fractions as answers.

+
+ +
+
+
+

Complete Code

+

+ Download file: DisableFunctionsTrig.pg +

+
+
+

POD for Macro Files

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros('PGstandard.pl', 'PGML.pl', 'contextFraction.pl', 'PGcourse.pl');
+
+
+
+

Preamble

+

The contextFraction.pl is loaded since we used the Fraction-NoDecimals context.

+
+
+
+
+ +
Context('Fraction-NoDecimals');
+
+# Prevent pi from becoming 3.1415... and cos(pi) from
+# becoming -1.
+Context()->constants->set(pi => { keepName => 1 });
+
+# The next context changes are not necessary to
+# prevent cos(pi) from becoming -1, but they cannot hurt.
+Context()->flags->set(
+    reduceConstants         => 0,
+    reduceConstantFunctions => 0
+);
+
+$f1 = Formula('cos(pi)');
+$f2 = Formula('sin(pi/3)');
+
+Context()->functions->disable('All');
+Context()->functions->enable('sqrt');
+
+$answer1 = Compute('-1');
+$answer2 = Compute('sqrt(3)/2');
+
+
+
+

Setup

+

We choose a context that requires fractions as answers and does not allow decimals. After constructing the formulas involving trig functions, we disable all functions and re-enable the sqrt() function. This means that students are allowed to type in fractions and square roots, but not much else (e.g., they’ll get an error message if they type in a trig function).

+

Note that $f1 and $f2 are MathObject Formulas, which do not get reduced since pi is set to keep its name. If $f1 and $f2 used Compute instead, then the results would be -1 and 0.866… instead of cos() and sin(/3) as desired.

+
+
+
+
+ +
BEGIN_PGML
+Enter your answers as simplified fractions.
+
++ [`[$f1] =`] [_]{$answer1}{15}
+
++ [`[$f2] =`] [_]{$answer2}{15}
+END_PGML
+
+
+
+

Statement

+ This is the problem statement in PGML. +
+
+
+
+ +
BEGIN_PGML_SOLUTION
+The cosine of an angle is zero when the angle is an integer multiple of [`\pi`].
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Trig/DisableFunctionsTrig.pg b/sample-problems/Trig/DisableFunctionsTrig.pg new file mode 100644 index 0000000..12196ba --- /dev/null +++ b/sample-problems/Trig/DisableFunctionsTrig.pg @@ -0,0 +1,39 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'contextFraction.pl', 'PGcourse.pl'); + +Context('Fraction-NoDecimals'); + +# Prevent pi from becoming 3.1415... and cos(pi) from +# becoming -1. +Context()->constants->set(pi => { keepName => 1 }); + +# The next context changes are not necessary to +# prevent cos(pi) from becoming -1, but they cannot hurt. +Context()->flags->set( + reduceConstants => 0, + reduceConstantFunctions => 0 +); + +$f1 = Formula('cos(pi)'); +$f2 = Formula('sin(pi/3)'); + +Context()->functions->disable('All'); +Context()->functions->enable('sqrt'); + +$answer1 = Compute('-1'); +$answer2 = Compute('sqrt(3)/2'); + +BEGIN_PGML +Enter your answers as simplified fractions. + ++ [`[$f1] =`] [_]{$answer1}{15} + ++ [`[$f2] =`] [_]{$answer2}{15} +END_PGML + +BEGIN_PGML_SOLUTION +The cosine of an angle is zero when the angle is an integer multiple of [`\pi`]. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Trig/DraggableIdentity.html b/sample-problems/Trig/DraggableIdentity.html index 44eb802..2cde209 100644 --- a/sample-problems/Trig/DraggableIdentity.html +++ b/sample-problems/Trig/DraggableIdentity.html @@ -175,7 +175,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Trig/PeriodicAnswers.html b/sample-problems/Trig/PeriodicAnswers.html index d4dea8e..d6006fd 100644 --- a/sample-problems/Trig/PeriodicAnswers.html +++ b/sample-problems/Trig/PeriodicAnswers.html @@ -138,7 +138,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Trig/ProvingTrigIdentities.html b/sample-problems/Trig/ProvingTrigIdentities.html index 952d04c..d211551 100644 --- a/sample-problems/Trig/ProvingTrigIdentities.html +++ b/sample-problems/Trig/ProvingTrigIdentities.html @@ -242,7 +242,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Trig/SpecialTrigValues.html b/sample-problems/Trig/SpecialTrigValues.html new file mode 100644 index 0000000..9615994 --- /dev/null +++ b/sample-problems/Trig/SpecialTrigValues.html @@ -0,0 +1,188 @@ + + + + + + + SpecialTrigValues.pg + + + + + + + + + + +
+
+
+

Using Special Trig Values on the Unit Circle

+

Displays values of trig functions on the unit circle

+
+ +
+
+
+

Complete Code

+

+ Download file: SpecialTrigValues.pg +

+
+
+

POD for Macro Files

+ +
+
+
+

PG problem file

+

Explanation

+
+
+
+ +
DOCUMENT();
+
+loadMacros('PGstandard.pl', 'PGML.pl', 'specialTrigValues.pl', 'PGcourse.pl');
+
+
+
+

Preamble

+

We load the specialTrigValues.pl macro to use exact values on the unit circle.

+
+
+
+
+ +
($d, $n) = random_coprime([ 2, 3, 4, 6 ], [ 1 .. 12 ]);
+
+$r = random(2, 3);
+
+$c = specialRadical("$r cos($n pi/$d)");
+$s = specialRadical("$r sin($n pi/$d)");
+
+$x = list_random(sqrt(3) / 2, sqrt(2) / 2, 1 / 2);
+$a = specialAngle(arcsin($x));
+
+Context("Complex");
+$z = specialRadical("$r exp($n pi i/$d)");
+
+
+
+

Setup

+

The random_coprime function selects two random numbers that are coprime from the list. This will give fractions with denominators of 2,3,4 or 6.

+

The specialRadical function returns a MathObject in the form a sqrt(b)/c were b, c come from a list of integers (defaults to [1,2,3]).

+

It is noted that specialRadical has a complex form as well.

+

The specialAngle function returns a MathObject in the form a pi/c where a in an integer and c comes from a list (defaults to [1,2,3,4,6]).

+
+
+
+
+ +
BEGIN_PGML
+Evaluate the following:
+
+a) [`[$r] \cos([$n] \pi/[$d])=`] [_]{$c}
+
+b) [`[$r] \sin([$n] \pi/[$d])=`] [_]{$s}
+
+c) [`[$r] \exp([$n] \pi/[$d])=`] [_]{$z}
+
+d) [`\arcsin([$x])=`] [_]{$a}
+END_PGML
+
+
+
+

Statement

+ This is the problem statement in PGML. +
+
+
+
+ +
BEGIN_PGML_SOLUTION
+Solution explanation goes here.
+END_PGML_SOLUTION
+
+ENDDOCUMENT();
+
+
+

Solution

+ A solution should be provided here. +
+
+
+ + + + + diff --git a/sample-problems/Trig/SpecialTrigValues.pg b/sample-problems/Trig/SpecialTrigValues.pg new file mode 100644 index 0000000..dfab85c --- /dev/null +++ b/sample-problems/Trig/SpecialTrigValues.pg @@ -0,0 +1,34 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'specialTrigValues.pl', 'PGcourse.pl'); + +($d, $n) = random_coprime([ 2, 3, 4, 6 ], [ 1 .. 12 ]); + +$r = random(2, 3); + +$c = specialRadical("$r cos($n pi/$d)"); +$s = specialRadical("$r sin($n pi/$d)"); + +$x = list_random(sqrt(3) / 2, sqrt(2) / 2, 1 / 2); +$a = specialAngle(arcsin($x)); + +Context("Complex"); +$z = specialRadical("$r exp($n pi i/$d)"); + +BEGIN_PGML +Evaluate the following: + +a) [`[$r] \cos([$n] \pi/[$d])=`] [_]{$c} + +b) [`[$r] \sin([$n] \pi/[$d])=`] [_]{$s} + +c) [`[$r] \exp([$n] \pi/[$d])=`] [_]{$z} + +d) [`\arcsin([$x])=`] [_]{$a} +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/Trig/TrigDegrees.html b/sample-problems/Trig/TrigDegrees.html index c0a5765..b7d7241 100644 --- a/sample-problems/Trig/TrigDegrees.html +++ b/sample-problems/Trig/TrigDegrees.html @@ -155,7 +155,8 @@

POD for Macro Files

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Trig/TrigIdentities.html b/sample-problems/Trig/TrigIdentities.html index 595d493..ef19ec8 100644 --- a/sample-problems/Trig/TrigIdentities.html +++ b/sample-problems/Trig/TrigIdentities.html @@ -63,26 +63,30 @@

Complete Code

-
$ans = Compute('sin(x)')->cmp( checker => sub {
-    my ($correct, $student, $ansHash) = @_;
-    my $stu_ans = $student->reduce;
-    Value->Error('There is a simpler answer')
-        if $stu_ans->string eq 'cos(x)*tan(x)';
-    return $student == $correct;
-});
+					
$ans = Compute('sin(x)')->cmp(
+    checker => sub {
+        my ($correct, $student, $ansHash) = @_;
+        my $stu_ans = $student->reduce;
+        Value->Error('There is a simpler answer')
+            if $stu_ans->string eq 'cos(x)*tan(x)';
+        return $student == $correct;
+    }
+);
 
@@ -157,7 +161,8 @@

Complete Code

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/Trig/TrigIdentities.pg b/sample-problems/Trig/TrigIdentities.pg index 8c0f188..708305d 100644 --- a/sample-problems/Trig/TrigIdentities.pg +++ b/sample-problems/Trig/TrigIdentities.pg @@ -2,13 +2,15 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); -$ans = Compute('sin(x)')->cmp( checker => sub { - my ($correct, $student, $ansHash) = @_; - my $stu_ans = $student->reduce; - Value->Error('There is a simpler answer') - if $stu_ans->string eq 'cos(x)*tan(x)'; - return $student == $correct; -}); +$ans = Compute('sin(x)')->cmp( + checker => sub { + my ($correct, $student, $ansHash) = @_; + my $stu_ans = $student->reduce; + Value->Error('There is a simpler answer') + if $stu_ans->string eq 'cos(x)*tan(x)'; + return $student == $correct; + } +); BEGIN_PGML Simplify the expression as much as possible. diff --git a/sample-problems/VectorCalc/CylindricalGraph3D.html b/sample-problems/VectorCalc/CylindricalGraph3D.html index ba40a07..a7702b0 100644 --- a/sample-problems/VectorCalc/CylindricalGraph3D.html +++ b/sample-problems/VectorCalc/CylindricalGraph3D.html @@ -59,7 +59,6 @@

See Also

type="button" data-code="DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl'); - " aria-label="copy to clipboard"> @@ -69,7 +68,6 @@

See Also

DOCUMENT();
 
 loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl');
-
 
@@ -80,21 +78,21 @@

See Also

-
$a = random(2,5);
+					
$a = random(2, 5);
 
 $gr1 = Graph3D();
 $gr1->addSurface(
-                ['u*cos(v)', 'u*sin(v)', "$a*cos(u^2/4)"],
-                [0, 6, 30],
-                [0, 2*pi, 30]
-        );
+    [ 'u*cos(v)', 'u*sin(v)', "$a*cos(u^2/4)" ],
+    [ 0,          6,          30 ],
+    [ 0,          2 * pi,     30 ]
+);
 
 $gr2 = Graph3D();
 $gr2->addSurface(
-    ['r*cos(t)', 'r*sin(t)', 'r*sin(t)^2'],
-    [0, 6, 30],
-    [0, 2*pi, 30],
-    variables => ['r','t']
+    [ 'r*cos(t)', 'r*sin(t)', 'r*sin(t)^2' ],
+    [ 0,          6,          30 ],
+    [ 0,          2 * pi,     30 ],
+    variables => [ 'r', 't' ]
 );
 
@@ -187,7 +185,8 @@

See Also

} for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/VectorCalc/CylindricalGraph3D.pg b/sample-problems/VectorCalc/CylindricalGraph3D.pg index bd3c1bc..fc87112 100644 --- a/sample-problems/VectorCalc/CylindricalGraph3D.pg +++ b/sample-problems/VectorCalc/CylindricalGraph3D.pg @@ -2,22 +2,21 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl'); - -$a = random(2,5); +$a = random(2, 5); $gr1 = Graph3D(); $gr1->addSurface( - ['u*cos(v)', 'u*sin(v)', "$a*cos(u^2/4)"], - [0, 6, 30], - [0, 2*pi, 30] - ); + [ 'u*cos(v)', 'u*sin(v)', "$a*cos(u^2/4)" ], + [ 0, 6, 30 ], + [ 0, 2 * pi, 30 ] +); $gr2 = Graph3D(); $gr2->addSurface( - ['r*cos(t)', 'r*sin(t)', 'r*sin(t)^2'], - [0, 6, 30], - [0, 2*pi, 30], - variables => ['r','t'] + [ 'r*cos(t)', 'r*sin(t)', 'r*sin(t)^2' ], + [ 0, 6, 30 ], + [ 0, 2 * pi, 30 ], + variables => [ 'r', 't' ] ); BEGIN_PGML diff --git a/sample-problems/VectorCalc/DirectionField.html b/sample-problems/VectorCalc/DirectionField.html index e481dd1..0fc549f 100644 --- a/sample-problems/VectorCalc/DirectionField.html +++ b/sample-problems/VectorCalc/DirectionField.html @@ -39,6 +39,13 @@

POD for Macro Files

  • PGtikz.pl
  • +
    +

    See Also

    + +

    PG problem file

    @@ -125,6 +132,7 @@

    POD for Macro Files

    Setup

    A direction field is a vector field where the length of the vectors are constant. We use the same technique as Two-D Vector Field.

    The vector field <y,-x> is used and then when the vector is drawn is scaled by its length or sqrt(x^2+y^2). Since this is not defined at the origin, we don’t draw the vector there and use the ifthen package to load the \ifthenelse latex command.

    +

    If you want a slope field, where only the slope is draw with no arrow delete the -> in the option of the \draw command inside the \foreach loops.

    @@ -189,7 +197,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/VectorCalc/RectangularGraph3D.html b/sample-problems/VectorCalc/RectangularGraph3D.html index a02222c..5e12ea3 100644 --- a/sample-problems/VectorCalc/RectangularGraph3D.html +++ b/sample-problems/VectorCalc/RectangularGraph3D.html @@ -61,7 +61,6 @@

    See Also

    type="button" data-code="DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl'); - " aria-label="copy to clipboard"> @@ -71,7 +70,6 @@

    See Also

    DOCUMENT();
     
     loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl');
    -
     
    @@ -85,10 +83,10 @@

    See Also

    type="button" data-code=" $gr = Graph3D(); $gr->addSurface( - ['x', 'y', 'x^2+y^2'], - [-3, 3, 30], - [-3, 3, 30], - variables => ['x','y'] + [ 'x', 'y', 'x^2+y^2' ], + [ -3, 3, 30 ], + [ -3, 3, 30 ], + variables => [ 'x', 'y' ] ); " aria-label="copy to clipboard"> See Also
     $gr = Graph3D();
     $gr->addSurface(
    -    ['x', 'y', 'x^2+y^2'],
    -    [-3, 3, 30],
    -    [-3, 3, 30],
    -    variables => ['x','y']
    +    [ 'x', 'y', 'x^2+y^2' ],
    +    [ -3,  3,   30 ],
    +    [ -3,  3,   30 ],
    +    variables => [ 'x', 'y' ]
     );
     
    @@ -171,7 +169,8 @@

    See Also

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/VectorCalc/RectangularGraph3D.pg b/sample-problems/VectorCalc/RectangularGraph3D.pg index 8a7ac54..6f1a97b 100644 --- a/sample-problems/VectorCalc/RectangularGraph3D.pg +++ b/sample-problems/VectorCalc/RectangularGraph3D.pg @@ -3,13 +3,12 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl'); - $gr = Graph3D(); $gr->addSurface( - ['x', 'y', 'x^2+y^2'], - [-3, 3, 30], - [-3, 3, 30], - variables => ['x','y'] + [ 'x', 'y', 'x^2+y^2' ], + [ -3, 3, 30 ], + [ -3, 3, 30 ], + variables => [ 'x', 'y' ] ); BEGIN_PGML diff --git a/sample-problems/VectorCalc/VectorFieldGraph2D.html b/sample-problems/VectorCalc/VectorFieldGraph2D.html index 0012ab4..9a931fe 100644 --- a/sample-problems/VectorCalc/VectorFieldGraph2D.html +++ b/sample-problems/VectorCalc/VectorFieldGraph2D.html @@ -39,6 +39,13 @@

    POD for Macro Files

  • PGtikz.pl
  • +
    +

    See Also

    + +

    PG problem file

    @@ -191,7 +198,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.html b/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.html index f631835..c72d358 100644 --- a/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.html +++ b/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.html @@ -48,7 +48,10 @@

    POD for Macro Files

    DOCUMENT();
    -loadMacros('PGstandard.pl', 'PGML.pl', 'LiveGraphicsVectorField3D.pl', 'PGcourse.pl');
    +loadMacros(
    +    'PGstandard.pl',                'PGML.pl',
    +    'LiveGraphicsVectorField3D.pl', 'PGcourse.pl'
    +);
     
    @@ -67,32 +73,32 @@

    POD for Macro Files

    -
    Context()->variables->are(x=>'Real',y=>'Real',z=>'Real');
    +					
    Context()->variables->are(x => 'Real', y => 'Real', z => 'Real');
     
     $plot = VectorField3D(
    -    Fx => Formula('x'),
    -    Fy => Formula('y'),
    -    Fz => Formula('z'),
    -    xvar => 'x',
    -    yvar => 'y',
    -    zvar => 'z',
    -    xmin => -1,
    -    xmax =>  1,
    -    ymin => -1,
    -    ymax =>  1,
    -    zmin => -1,
    -    zmax =>  1,
    -    xsamples => 4,
    -    ysamples => 4,
    -    zsamples => 4,
    -    axesframed => 1,
    -    xaxislabel => 'X',
    -    yaxislabel => 'Y',
    -    zaxislabel => 'Z',
    -    vectorcolor => "RGBColor[0.0,0.0,1.0]",
    -    vectorscale => 0.2,
    +    Fx              => Formula('x'),
    +    Fy              => Formula('y'),
    +    Fz              => Formula('z'),
    +    xvar            => 'x',
    +    yvar            => 'y',
    +    zvar            => 'z',
    +    xmin            => -1,
    +    xmax            => 1,
    +    ymin            => -1,
    +    ymax            => 1,
    +    zmin            => -1,
    +    zmax            => 1,
    +    xsamples        => 4,
    +    ysamples        => 4,
    +    zsamples        => 4,
    +    axesframed      => 1,
    +    xaxislabel      => 'X',
    +    yaxislabel      => 'Y',
    +    zaxislabel      => 'Z',
    +    vectorcolor     => "RGBColor[0.0,0.0,1.0]",
    +    vectorscale     => 0.2,
         vectorthickness => 0.01,
    -    outputtype => 4,
    +    outputtype      => 4,
     );
     
    @@ -213,7 +219,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.pg b/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.pg index b354ef7..a7d1f4c 100644 --- a/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.pg +++ b/sample-problems/VectorCalc/VectorFieldGraph3D/VectorFieldGraph3D1.pg @@ -1,32 +1,35 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'LiveGraphicsVectorField3D.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'LiveGraphicsVectorField3D.pl', 'PGcourse.pl' +); -Context()->variables->are(x=>'Real',y=>'Real',z=>'Real'); +Context()->variables->are(x => 'Real', y => 'Real', z => 'Real'); $plot = VectorField3D( - Fx => Formula('x'), - Fy => Formula('y'), - Fz => Formula('z'), - xvar => 'x', - yvar => 'y', - zvar => 'z', - xmin => -1, - xmax => 1, - ymin => -1, - ymax => 1, - zmin => -1, - zmax => 1, - xsamples => 4, - ysamples => 4, - zsamples => 4, - axesframed => 1, - xaxislabel => 'X', - yaxislabel => 'Y', - zaxislabel => 'Z', - vectorcolor => "RGBColor[0.0,0.0,1.0]", - vectorscale => 0.2, + Fx => Formula('x'), + Fy => Formula('y'), + Fz => Formula('z'), + xvar => 'x', + yvar => 'y', + zvar => 'z', + xmin => -1, + xmax => 1, + ymin => -1, + ymax => 1, + zmin => -1, + zmax => 1, + xsamples => 4, + ysamples => 4, + zsamples => 4, + axesframed => 1, + xaxislabel => 'X', + yaxislabel => 'Y', + zaxislabel => 'Z', + vectorcolor => "RGBColor[0.0,0.0,1.0]", + vectorscale => 0.2, vectorthickness => 0.01, - outputtype => 4, + outputtype => 4, ); BEGIN_PGML diff --git a/sample-problems/VectorCalc/VectorLineSegment1.html b/sample-problems/VectorCalc/VectorLineSegment1.html new file mode 100644 index 0000000..dca0ef8 --- /dev/null +++ b/sample-problems/VectorCalc/VectorLineSegment1.html @@ -0,0 +1,254 @@ + + + + + + + VectorLineSegment1.pg + + + + + + + + + + +
    +
    +
    +

    Vector-valued Parametric Line Segment--General

    +

    A Vector-value parametric line segment with a general paramterization

    +
    + +
    +
    +
    +

    Complete Code

    +

    + Download file: VectorLineSegment1.pg +

    +
    +
    +

    POD for Macro Files

    + +
    +
    +
    +

    PG problem file

    +

    Explanation

    +
    +
    +
    + +
    DOCUMENT();
    +loadMacros(
    +    'PGstandard.pl',           'PGML.pl',
    +    'parserParametricLine.pl', 'parserMultiAnswer.pl',
    +    'PGcourse.pl'
    +);
    +
    +
    +
    +

    Preamble

    +

    The macro parseParametricLine.pl provides the ParametricLine function which will be the answer. The parserMultiAnswer.pl is needed since the answer blanks are interdependent.

    +
    +
    +
    +
    + +
    Context("Vector");
    +Context()->variables->are(t => "Real");
    +
    +$P = Point(4, 0);
    +$Q = Point(0, 2);
    +$V = Vector(-4, 2);
    +
    +$t    = Formula("t");
    +$line = Vector("$P + $t * $V");
    +
    +$multians = MultiAnswer($line, Real("0"), Real("1"))->with(
    +    singleResult => 0,
    +    checker      => sub {
    +        my ($correct, $student, $ansHash) = @_;
    +        my ($linestu, $astu,    $bstu)    = @{$student};
    +        my ($linecor, $acor,    $bcor)    = @{$correct};
    +
    +        if ((ParametricLine("$line") == $linestu)
    +            && ($linestu->eval(t => $astu) == $line->eval(t => "0"))
    +            && ($linestu->eval(t => $bstu) == $line->eval(t => "1")))
    +        {
    +            return [ 1, 1, 1 ];
    +
    +        } elsif ((ParametricLine("$line") == $linestu)
    +            && ($linestu->eval(t => $astu) == $line->eval(t => "0")))
    +        {
    +            return [ 1, 1, 0 ];
    +
    +        } elsif ((ParametricLine("$line") == $linestu)
    +            && ($linestu->eval(t => $bstu) == $line->eval(t => "1")))
    +        {
    +            return [ 1, 0, 1 ];
    +
    +        } elsif ((ParametricLine("$line") == $linestu)) {
    +            return [ 1, 0, 0 ];
    +
    +        } else {
    +            return [ 0, 0, 0 ];
    +        }
    +
    +    }
    +);
    +
    +
    +
    +

    Setup

    +

    We create a MutiAnswer answer checker that will evaluate the students vector parametric equation at the starting and ending times provided by the student. For example, both of the student answers (4,0) + t<-4,2> for t between 0 and 1, and (4,0) + t<-2,1> for t between 0 and 2 will be marked correct.

    +
    +
    +
    +
    + +
    BEGIN_PGML
    +Find a vector parametric equation for the line
    +segment from the point [`P = [$P]`]
    +to [`Q = [$Q]`].
    +
    +[` \vec{r}(t) = `] [__]{$multians}
    +
    +for
    +[__]{$multians}
    +[` \leq t \leq `]
    +[__]{$multians}
    +END_PGML
    +
    +
    +
    +

    Statement

    +

    Since the three answer blanks depend on each other, we use $multians for each answer blank.

    +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/VectorCalc/VectorLineSegment1.pg b/sample-problems/VectorCalc/VectorLineSegment1.pg new file mode 100644 index 0000000..085dae9 --- /dev/null +++ b/sample-problems/VectorCalc/VectorLineSegment1.pg @@ -0,0 +1,68 @@ +DOCUMENT(); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'parserParametricLine.pl', 'parserMultiAnswer.pl', + 'PGcourse.pl' +); + +Context("Vector"); +Context()->variables->are(t => "Real"); + +$P = Point(4, 0); +$Q = Point(0, 2); +$V = Vector(-4, 2); + +$t = Formula("t"); +$line = Vector("$P + $t * $V"); + +$multians = MultiAnswer($line, Real("0"), Real("1"))->with( + singleResult => 0, + checker => sub { + my ($correct, $student, $ansHash) = @_; + my ($linestu, $astu, $bstu) = @{$student}; + my ($linecor, $acor, $bcor) = @{$correct}; + + if ((ParametricLine("$line") == $linestu) + && ($linestu->eval(t => $astu) == $line->eval(t => "0")) + && ($linestu->eval(t => $bstu) == $line->eval(t => "1"))) + { + return [ 1, 1, 1 ]; + + } elsif ((ParametricLine("$line") == $linestu) + && ($linestu->eval(t => $astu) == $line->eval(t => "0"))) + { + return [ 1, 1, 0 ]; + + } elsif ((ParametricLine("$line") == $linestu) + && ($linestu->eval(t => $bstu) == $line->eval(t => "1"))) + { + return [ 1, 0, 1 ]; + + } elsif ((ParametricLine("$line") == $linestu)) { + return [ 1, 0, 0 ]; + + } else { + return [ 0, 0, 0 ]; + } + + } +); + +BEGIN_PGML +Find a vector parametric equation for the line +segment from the point [`P = [$P]`] +to [`Q = [$Q]`]. + +[` \vec{r}(t) = `] [__]{$multians} + +for +[__]{$multians} +[` \leq t \leq `] +[__]{$multians} +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/VectorCalc/VectorLineSegment2.html b/sample-problems/VectorCalc/VectorLineSegment2.html new file mode 100644 index 0000000..3f2b224 --- /dev/null +++ b/sample-problems/VectorCalc/VectorLineSegment2.html @@ -0,0 +1,175 @@ + + + + + + + VectorLineSegment2.pg + + + + + + + + + + +
    +
    +
    +

    Vector-valued Parametric Line Segment--Specific

    +

    A Vector-value parametric line segment for a specific values of the parameter.

    +
    + +
    +
    +
    +

    Complete Code

    +

    + Download file: VectorLineSegment2.pg +

    +
    +
    +

    POD for Macro Files

    + +
    +
    +
    +

    PG problem file

    +

    Explanation

    +
    +
    +
    + +
    DOCUMENT();
    +loadMacros('PGstandard.pl', 'PGML.pl', 'parserVectorUtils.pl', 'PGcourse.pl');
    +
    +
    +
    +

    Preamble

    +

    The macro parseVectorUtils.pl provides random points and vectors.

    +
    +
    +
    +
    + +
    Context("Vector");
    +Context()->variables->are(t => "Real");
    +
    +$P     = non_zero_point3D();
    +$disp  = non_zero_vector3D();
    +$Q     = Point($P + $disp);
    +$speed = random(3, 9, 1);
    +
    +$ans = Compute("$P + $speed *t * $disp/norm($disp)");
    +
    +
    +
    +

    Setup

    +

    In this case, there is only a single answer, so we can just enter the correct expression for the vector-valued function.

    +
    +
    +
    +
    + +
    BEGIN_PGML
    +A particle starts at the point [` P = [$P] `]
    +when [` t = 0 `] and moves along a straight line
    +toward [` Q = [$Q] `] at a speed of [` [$speed] `]
    +cm/sec.  Assume that [`x, y,`] and [`z`] are measured
    +in cm.  Do not enter units with your answers.
    +
    +Find the vector parametric equation for the position of the object.
    +[` \vec{r}(t) = `] [____]{$ans}
    +END_PGML
    +
    +
    +
    +

    Statement

    + This is the problem statement in PGML. +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/VectorCalc/VectorLineSegment2.pg b/sample-problems/VectorCalc/VectorLineSegment2.pg new file mode 100644 index 0000000..087dd2c --- /dev/null +++ b/sample-problems/VectorCalc/VectorLineSegment2.pg @@ -0,0 +1,29 @@ +DOCUMENT(); +loadMacros('PGstandard.pl', 'PGML.pl', 'parserVectorUtils.pl', 'PGcourse.pl'); + +Context("Vector"); +Context()->variables->are(t => "Real"); + +$P = non_zero_point3D(); +$disp = non_zero_vector3D(); +$Q = Point($P + $disp); +$speed = random(3, 9, 1); + +$ans = Compute("$P + $speed *t * $disp/norm($disp)"); + +BEGIN_PGML +A particle starts at the point [` P = [$P] `] +when [` t = 0 `] and moves along a straight line +toward [` Q = [$Q] `] at a speed of [` [$speed] `] +cm/sec. Assume that [`x, y,`] and [`z`] are measured +in cm. Do not enter units with your answers. + +Find the vector parametric equation for the position of the object. +[` \vec{r}(t) = `] [____]{$ans} +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/VectorCalc/VectorOperations.html b/sample-problems/VectorCalc/VectorOperations.html index 188723c..2840423 100644 --- a/sample-problems/VectorCalc/VectorOperations.html +++ b/sample-problems/VectorCalc/VectorOperations.html @@ -71,25 +71,24 @@

    POD for Macro Files

    +
    DOCUMENT();
    +loadMacros(
    +    'PGstandard.pl',        'PGML.pl',
    +    'parserVectorUtils.pl', 'parserParametricLine.pl',
    +    'PGcourse.pl'
    +);
    +
    +
    +
    +

    Preamble

    +

    The macro parseVectorUtils.pl provides random points. The macro parseParametricLine.pl provides the ParametricLine function which will be the answer.

    +
    +
    +
    +
    + +
    Context('Vector');
    +Context()->variables->are(t => 'Real');
    +
    +$P    = non_zero_point3D();
    +$disp = non_zero_vector3D();
    +$Q    = Point($P + $disp);
    +$line = ParametricLine("$P+t *$disp");
    +
    +
    +
    +

    Setup

    +

    We randomize two points in three-dimensional space, P and Q, a displacement vector between them, and a speed to travel between them.

    +
    +
    +
    +
    + +
    BEGIN_PGML
    +Find a vector parametric equation for the
    +line through points [` P = [$P] `] and [` Q = [$Q] `].
    +
    +[` \vec{r}(t) = `] [___]{$line}
    +
    +A vector should be entered like  <x(t),y(t),z(t)>.
    +END_PGML
    +
    +
    +
    +

    Statement

    + This is the problem statement in PGML. +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/VectorCalc/VectorParametricLine.pg b/sample-problems/VectorCalc/VectorParametricLine.pg new file mode 100644 index 0000000..ed93b5e --- /dev/null +++ b/sample-problems/VectorCalc/VectorParametricLine.pg @@ -0,0 +1,29 @@ +DOCUMENT(); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'parserVectorUtils.pl', 'parserParametricLine.pl', + 'PGcourse.pl' +); + +Context('Vector'); +Context()->variables->are(t => 'Real'); + +$P = non_zero_point3D(); +$disp = non_zero_vector3D(); +$Q = Point($P + $disp); +$line = ParametricLine("$P+t *$disp"); + +BEGIN_PGML +Find a vector parametric equation for the +line through points [` P = [$P] `] and [` Q = [$Q] `]. + +[` \vec{r}(t) = `] [___]{$line} + +A vector should be entered like . +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/VectorCalc/Vectors.html b/sample-problems/VectorCalc/Vectors.html index d645f76..2e28738 100644 --- a/sample-problems/VectorCalc/Vectors.html +++ b/sample-problems/VectorCalc/Vectors.html @@ -75,19 +75,19 @@

    Complete Code

    $v1 = Vector("<1,3>"); $v2 = Compute("<-3,1>"); -$v3 = 3*i + 2*j - 4*k; -$v4 = Vector(1,1,0); +$v3 = 3 * i + 2 * j - 4 * k; +$v4 = Vector(1, 1, 0); # create an array of the components of $v3 @v3comp = $v3->value; -$a = 3*i + j; +$a = 3 * i + j; # $b = $a + $v1; # this results in an error -$c = norm($v3); # vector length -$v5 = unit($v3); # unit vector in same direction -$d = $v1 . $v2; # dot product -$v6 = $v3 x $v4; # cross product -$v3->isParallel($v4); # returns 1 if parallel, 0 if skew +$c = norm($v3); # vector length +$v5 = unit($v3); # unit vector in same direction +$d = $v1 . $v2; # dot product +$v6 = $v3 x $v4; # cross product +$v3->isParallel($v4); # returns 1 if parallel, 0 if skew BEGIN_PGML [`\vec{v}_1=[$v1]`] @@ -117,7 +117,6 @@

    Complete Code

    The third element of [`\vec{v}_4`] is [@ $v4->extract(3) @] END_PGML - " aria-label="copy to clipboard"> @@ -138,19 +137,19 @@

    Complete Code

    $v1 = Vector("<1,3>"); $v2 = Compute("<-3,1>"); -$v3 = 3*i + 2*j - 4*k; -$v4 = Vector(1,1,0); +$v3 = 3 * i + 2 * j - 4 * k; +$v4 = Vector(1, 1, 0); # create an array of the components of $v3 @v3comp = $v3->value; -$a = 3*i + j; +$a = 3 * i + j; # $b = $a + $v1; # this results in an error -$c = norm($v3); # vector length -$v5 = unit($v3); # unit vector in same direction -$d = $v1 . $v2; # dot product -$v6 = $v3 x $v4; # cross product -$v3->isParallel($v4); # returns 1 if parallel, 0 if skew +$c = norm($v3); # vector length +$v5 = unit($v3); # unit vector in same direction +$d = $v1 . $v2; # dot product +$v6 = $v3 x $v4; # cross product +$v3->isParallel($v4); # returns 1 if parallel, 0 if skew BEGIN_PGML [`\vec{v}_1=[$v1]`] @@ -180,7 +179,6 @@

    Complete Code

    The third element of [`\vec{v}_4`] is [@ $v4->extract(3) @] END_PGML -
    @@ -225,7 +223,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/VectorCalc/Vectors.pg b/sample-problems/VectorCalc/Vectors.pg index 7ffffe9..f7318d2 100644 --- a/sample-problems/VectorCalc/Vectors.pg +++ b/sample-problems/VectorCalc/Vectors.pg @@ -15,19 +15,19 @@ Context('Vector'); $v1 = Vector("<1,3>"); $v2 = Compute("<-3,1>"); -$v3 = 3*i + 2*j - 4*k; -$v4 = Vector(1,1,0); +$v3 = 3 * i + 2 * j - 4 * k; +$v4 = Vector(1, 1, 0); # create an array of the components of $v3 @v3comp = $v3->value; -$a = 3*i + j; +$a = 3 * i + j; # $b = $a + $v1; # this results in an error -$c = norm($v3); # vector length -$v5 = unit($v3); # unit vector in same direction -$d = $v1 . $v2; # dot product -$v6 = $v3 x $v4; # cross product -$v3->isParallel($v4); # returns 1 if parallel, 0 if skew +$c = norm($v3); # vector length +$v5 = unit($v3); # unit vector in same direction +$d = $v1 . $v2; # dot product +$v6 = $v3 x $v4; # cross product +$v3->isParallel($v4); # returns 1 if parallel, 0 if skew BEGIN_PGML [`\vec{v}_1=[$v1]`] @@ -58,7 +58,6 @@ The first element of [`\vec{v}_3`] is [@ $v3->extract(1) @] The third element of [`\vec{v}_4`] is [@ $v4->extract(3) @] END_PGML - BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION diff --git a/sample-problems/categories.html b/sample-problems/categories.html index 50ab510..3c48775 100644 --- a/sample-problems/categories.html +++ b/sample-problems/categories.html @@ -83,13 +83,818 @@

    Categories

    - +
    +

    Sample Problems for Catetory: Riemann sums

    + +
    +
    +

    Sample Problems for Catetory: adaptive parameters

    + +
    +
    +

    Sample Problems for Catetory: algebra

    + +
    + + +
    +

    Sample Problems for Catetory: antiderivatives

    + +
    +
    +

    Sample Problems for Catetory: chemistry

    + +
    +
    +

    Sample Problems for Catetory: composition

    + +
    +
    +

    Sample Problems for Catetory: constant

    + +
    +
    +

    Sample Problems for Catetory: context

    + +
    + +
    +

    Sample Problems for Catetory: custom error

    + +
    +
    +

    Sample Problems for Catetory: degrees

    + +
    +
    +

    Sample Problems for Catetory: derivative

    + +
    +
    +

    Sample Problems for Catetory: difference quotient

    + +
    +
    +

    Sample Problems for Catetory: differential equations

    + +
    +
    +

    Sample Problems for Catetory: disk method

    + +
    +
    +

    Sample Problems for Catetory: domain

    + +
    +
    +

    Sample Problems for Catetory: double integral

    + +
    +
    +

    Sample Problems for Catetory: draggable

    + +
    +
    +

    Sample Problems for Catetory: equation

    + +
    +
    +

    Sample Problems for Catetory: essay

    + +
    +
    +

    Sample Problems for Catetory: expanding

    + +
    +
    +

    Sample Problems for Catetory: exponent

    + +
    +
    +

    Sample Problems for Catetory: factoring

    + +
    +
    +

    Sample Problems for Catetory: formatting decimals

    + +
    +
    +

    Sample Problems for Catetory: formula

    + +
    +
    +

    Sample Problems for Catetory: fraction

    + +
    +
    +

    Sample Problems for Catetory: function

    + +
    +
    +

    Sample Problems for Catetory: grader

    + +
    + +
    +

    Sample Problems for Catetory: heaviside-step

    + +
    +
    +

    Sample Problems for Catetory: implicit

    + +
    +
    +

    Sample Problems for Catetory: implicit function

    + +
    +
    +

    Sample Problems for Catetory: inequality

    + +
    +
    +

    Sample Problems for Catetory: interval

    + +
    +
    +

    Sample Problems for Catetory: knowls

    + +
    +
    +

    Sample Problems for Catetory: linear approximation

    + +
    +
    +

    Sample Problems for Catetory: list

    + +
    +
    +

    Sample Problems for Catetory: logarithm

    + +
    + + +
    +

    Sample Problems for Catetory: multianswer

    + +
    + +
    +

    Sample Problems for Catetory: numbers

    + +
    +
    +

    Sample Problems for Catetory: parametric

    + +
    +
    +

    Sample Problems for Catetory: plots

    + +
    + +
    +

    Sample Problems for Catetory: polynomial

    + +
    +
    +

    Sample Problems for Catetory: polynomials

    + +
    +
    +

    Sample Problems for Catetory: proof

    + +
    +
    +

    Sample Problems for Catetory: row operation

    + +
    +
    +

    Sample Problems for Catetory: sequences

    + +
    +
    +

    Sample Problems for Catetory: series

    + +
    +
    +

    Sample Problems for Catetory: solid of revolution

    + +
    +
    +

    Sample Problems for Catetory: strings

    + +
    +
    +

    Sample Problems for Catetory: table

    + +
    + +
    +

    Sample Problems for Catetory: transformation

    + +
    + +
    +

    Sample Problems for Catetory: units

    + +
    +
    +

    Sample Problems for Catetory: variables

    + +
    + +
    +

    Sample Problems for Catetory: video

    + +
    +
    +

    Sample Problems for Catetory: volume

    + +
    +
    diff --git a/sample-problems/problem-techniques/AddingFunctions.html b/sample-problems/problem-techniques/AddingFunctions.html index 5b37105..91ea1db 100644 --- a/sample-problems/problem-techniques/AddingFunctions.html +++ b/sample-problems/problem-techniques/AddingFunctions.html @@ -149,7 +149,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/AnswerHints.html b/sample-problems/problem-techniques/AnswerHints.html index 85b4683..d65869b 100644 --- a/sample-problems/problem-techniques/AnswerHints.html +++ b/sample-problems/problem-techniques/AnswerHints.html @@ -170,7 +170,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/AnswerInExponent.html b/sample-problems/problem-techniques/AnswerInExponent.html index 1154697..f31f9cb 100644 --- a/sample-problems/problem-techniques/AnswerInExponent.html +++ b/sample-problems/problem-techniques/AnswerInExponent.html @@ -176,7 +176,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/AnswerIsSolutionToEquation.html b/sample-problems/problem-techniques/AnswerIsSolutionToEquation.html index da5c7ae..062a512 100644 --- a/sample-problems/problem-techniques/AnswerIsSolutionToEquation.html +++ b/sample-problems/problem-techniques/AnswerIsSolutionToEquation.html @@ -146,7 +146,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/AnyAnswerMarkedCorrect.html b/sample-problems/problem-techniques/AnyAnswerMarkedCorrect.html index e2dba93..f743817 100644 --- a/sample-problems/problem-techniques/AnyAnswerMarkedCorrect.html +++ b/sample-problems/problem-techniques/AnyAnswerMarkedCorrect.html @@ -135,7 +135,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/CalculatingWithPoints.html b/sample-problems/problem-techniques/CalculatingWithPoints.html index 0c01827..0848b28 100644 --- a/sample-problems/problem-techniques/CalculatingWithPoints.html +++ b/sample-problems/problem-techniques/CalculatingWithPoints.html @@ -62,7 +62,10 @@

    Complete Code

    $draggable = DraggableSubsets(
         [
    -        'mouse',  'ebola bacteria', 'flu virus',    'krill',    'house cat',  'emu',
    -        'coyote', 'tapir',          'hippopotamus', 'elephant', 'blue whale', 'eagle'
    +        'mouse',        'ebola bacteria',
    +        'flu virus',    'krill',
    +        'house cat',    'emu',
    +        'coyote',       'tapir',
    +        'hippopotamus', 'elephant',
    +        'blue whale',   'eagle'
         ],
         [ [], [ 0, 4, 6, 7, 8, 9, 10 ], [ 5, 11 ], [ 1, 2, 3 ] ],
         # ['mouse','house cat','coyote','tapir','hippopatamus','elephant']
    @@ -101,7 +110,8 @@ 

    POD for Macro Files

    { label => 'Birds', indices => [] }, { label => 'Other', indices => [] } ], - AllowNewBuckets => 0 + AllowNewBuckets => 0, + OrderedSubsets => 1 );
    @@ -113,7 +123,7 @@

    POD for Macro Files

    $answer_sets, %options );
    -

    where $full_set is the set of all labelled boxes. The $answer_sets is a nested array reference of distribution of the correct subsets. There are many options. The example here shows the use of DefaultSubsets which shows how to label and initialize the buckets. The AllowNewBuckets option allows the student in add a new bucket (1) or not (0).

    +

    where $full_set is the set of all labelled boxes. The $answer_sets is a nested array reference of distribution of the correct subsets. There are many options. The example here shows the use of DefaultSubsets which shows how to label and initialize the buckets. The AllowNewBuckets option allows the student in add a new bucket (1) or not (0). The OrderedSubsets option requires that the subsets in the student answer be the same as in the correct answer.

    See the DraggableProofs for an example of how to create drag and drop proof problems.

    @@ -175,7 +185,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/DraggableSubsets.pg b/sample-problems/problem-techniques/DraggableSubsets.pg index 834848f..20d2759 100644 --- a/sample-problems/problem-techniques/DraggableSubsets.pg +++ b/sample-problems/problem-techniques/DraggableSubsets.pg @@ -3,8 +3,12 @@ loadMacros('PGstandard.pl', 'PGML.pl', 'draggableSubsets.pl', 'PGcourse.pl'); $draggable = DraggableSubsets( [ - 'mouse', 'ebola bacteria', 'flu virus', 'krill', 'house cat', 'emu', - 'coyote', 'tapir', 'hippopotamus', 'elephant', 'blue whale', 'eagle' + 'mouse', 'ebola bacteria', + 'flu virus', 'krill', + 'house cat', 'emu', + 'coyote', 'tapir', + 'hippopotamus', 'elephant', + 'blue whale', 'eagle' ], [ [], [ 0, 4, 6, 7, 8, 9, 10 ], [ 5, 11 ], [ 1, 2, 3 ] ], # ['mouse','house cat','coyote','tapir','hippopatamus','elephant'] @@ -14,7 +18,8 @@ $draggable = DraggableSubsets( { label => 'Birds', indices => [] }, { label => 'Other', indices => [] } ], - AllowNewBuckets => 0 + AllowNewBuckets => 0, + OrderedSubsets => 1 ); BEGIN_PGML diff --git a/sample-problems/problem-techniques/EquationEvaluators.html b/sample-problems/problem-techniques/EquationEvaluators.html index 66db2ef..1ed2153 100644 --- a/sample-problems/problem-techniques/EquationEvaluators.html +++ b/sample-problems/problem-techniques/EquationEvaluators.html @@ -48,7 +48,10 @@

    POD for Macro Files

    DOCUMENT();
    -loadMacros('PGstandard.pl', 'PGML.pl', 'parserImplicitEquation.pl', 'PGcourse.pl');
    +loadMacros(
    +    'PGstandard.pl',             'PGML.pl',
    +    'parserImplicitEquation.pl', 'PGcourse.pl'
    +);
     
    @@ -173,7 +179,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/EquationEvaluators.pg b/sample-problems/problem-techniques/EquationEvaluators.pg index 2255c63..a414864 100644 --- a/sample-problems/problem-techniques/EquationEvaluators.pg +++ b/sample-problems/problem-techniques/EquationEvaluators.pg @@ -1,5 +1,8 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'parserImplicitEquation.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'parserImplicitEquation.pl', 'PGcourse.pl' +); Context("ImplicitEquation"); Context()->variables->set( diff --git a/sample-problems/problem-techniques/EquationsDefiningFunctions.html b/sample-problems/problem-techniques/EquationsDefiningFunctions.html index 7b68b0f..b56c9c5 100644 --- a/sample-problems/problem-techniques/EquationsDefiningFunctions.html +++ b/sample-problems/problem-techniques/EquationsDefiningFunctions.html @@ -155,7 +155,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/ErrorMessageCustomization.html b/sample-problems/problem-techniques/ErrorMessageCustomization.html index 406e69a..d680427 100644 --- a/sample-problems/problem-techniques/ErrorMessageCustomization.html +++ b/sample-problems/problem-techniques/ErrorMessageCustomization.html @@ -143,7 +143,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/EvalVersusSubstitute.html b/sample-problems/problem-techniques/EvalVersusSubstitute.html index 4784d35..f0e5ed9 100644 --- a/sample-problems/problem-techniques/EvalVersusSubstitute.html +++ b/sample-problems/problem-techniques/EvalVersusSubstitute.html @@ -190,7 +190,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/ExtractingCoordinatesFromPoint.html b/sample-problems/problem-techniques/ExtractingCoordinatesFromPoint.html index bb572e2..1cc0548 100644 --- a/sample-problems/problem-techniques/ExtractingCoordinatesFromPoint.html +++ b/sample-problems/problem-techniques/ExtractingCoordinatesFromPoint.html @@ -63,17 +63,16 @@

    Complete Code

    DOCUMENT();
     
    -loadMacros('PGstandard.pl', 'PGML.pl', 'parserFormulaUpToConstant.pl', 'PGcourse.pl');
    +loadMacros(
    +    'PGstandard.pl',                'PGML.pl',
    +    'parserFormulaUpToConstant.pl', 'PGcourse.pl'
    +);
     
    @@ -123,7 +129,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/FormulasToConstants.pg b/sample-problems/problem-techniques/FormulasToConstants.pg index c277180..d03f5c1 100644 --- a/sample-problems/problem-techniques/FormulasToConstants.pg +++ b/sample-problems/problem-techniques/FormulasToConstants.pg @@ -1,6 +1,9 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'parserFormulaUpToConstant.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'parserFormulaUpToConstant.pl', 'PGcourse.pl' +); $func = Formula('sin(x)'); $gfunc = FormulaUpToConstant('sin(x) + C'); diff --git a/sample-problems/problem-techniques/GraphsInTables.html b/sample-problems/problem-techniques/GraphsInTables.html index 0d9c51f..2235657 100644 --- a/sample-problems/problem-techniques/GraphsInTables.html +++ b/sample-problems/problem-techniques/GraphsInTables.html @@ -53,8 +53,10 @@

    POD for Macro Files

    type="button" data-code="DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'parserPopUp.pl', - 'niceTables.pl', 'PGchoicemacros.pl', 'PGcourse.pl' + 'PGstandard.pl', 'PGML.pl', + 'PGtikz.pl', 'parserPopUp.pl', + 'niceTables.pl', 'PGchoicemacros.pl', + 'PGcourse.pl' ); " aria-label="copy to clipboard"> POD for Macro Files
    DOCUMENT();
     
     loadMacros(
    -    'PGstandard.pl', 'PGML.pl',           'PGtikz.pl', 'parserPopUp.pl',
    -    'niceTables.pl', 'PGchoicemacros.pl', 'PGcourse.pl'
    +    'PGstandard.pl', 'PGML.pl',
    +    'PGtikz.pl',     'parserPopUp.pl',
    +    'niceTables.pl', 'PGchoicemacros.pl',
    +    'PGcourse.pl'
     );
     
    @@ -82,7 +86,12 @@

    POD for Macro Files

    @eqn_plot = ('-exp(\x)', 'exp(-\x)', '-exp(-\x)', 'exp(\x)'); # The tex form of the functions. -@eqn = ("\( y = -e^{x} \)", "\( y = e^{-x} \)", "\( y = -e^{-x} \)", "\( y = e^{x} \)"); +@eqn = ( + "\( y = -e^{x} \)", + "\( y = e^{-x} \)", + "\( y = -e^{-x} \)", + "\( y = e^{x} \)" +); # Alternate text for each image. @alt_text = ( @@ -126,7 +135,15 @@

    POD for Macro Files

    $popup = PopUp([ "?", "A", "B", "C", "D" ], $letter[ $inv[$k] ]); -$tab = LayoutTable([ [ 'A', 'B' ], [ $fig[0], $fig[1] ], [ 'C', 'D' ], [ $fig[2], $fig[3] ], ], texalignment => 'cc'); +$tab = LayoutTable( + [ + [ 'A', 'B' ], + [ $fig[0], $fig[1] ], + [ 'C', 'D' ], + [ $fig[2], $fig[3] ], + ], + texalignment => 'cc' +); " aria-label="copy to clipboard"> @@ -137,7 +154,12 @@

    POD for Macro Files

    @eqn_plot = ('-exp(\x)', 'exp(-\x)', '-exp(-\x)', 'exp(\x)'); # The tex form of the functions. -@eqn = ("\( y = -e^{x} \)", "\( y = e^{-x} \)", "\( y = -e^{-x} \)", "\( y = e^{x} \)"); +@eqn = ( + "\( y = -e^{x} \)", + "\( y = e^{-x} \)", + "\( y = -e^{-x} \)", + "\( y = e^{x} \)" +); # Alternate text for each image. @alt_text = ( @@ -181,7 +203,15 @@

    POD for Macro Files

    $popup = PopUp([ "?", "A", "B", "C", "D" ], $letter[ $inv[$k] ]); -$tab = LayoutTable([ [ 'A', 'B' ], [ $fig[0], $fig[1] ], [ 'C', 'D' ], [ $fig[2], $fig[3] ], ], texalignment => 'cc'); +$tab = LayoutTable( + [ + [ 'A', 'B' ], + [ $fig[0], $fig[1] ], + [ 'C', 'D' ], + [ $fig[2], $fig[3] ], + ], + texalignment => 'cc' +);
    @@ -271,7 +301,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/GraphsInTables.pg b/sample-problems/problem-techniques/GraphsInTables.pg index 8c45d9a..aed900d 100644 --- a/sample-problems/problem-techniques/GraphsInTables.pg +++ b/sample-problems/problem-techniques/GraphsInTables.pg @@ -1,15 +1,22 @@ DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'parserPopUp.pl', - 'niceTables.pl', 'PGchoicemacros.pl', 'PGcourse.pl' + 'PGstandard.pl', 'PGML.pl', + 'PGtikz.pl', 'parserPopUp.pl', + 'niceTables.pl', 'PGchoicemacros.pl', + 'PGcourse.pl' ); # The form of the functions for the tikz plotting. @eqn_plot = ('-exp(\x)', 'exp(-\x)', '-exp(-\x)', 'exp(\x)'); # The tex form of the functions. -@eqn = ("\( y = -e^{x} \)", "\( y = e^{-x} \)", "\( y = -e^{-x} \)", "\( y = e^{x} \)"); +@eqn = ( + "\( y = -e^{x} \)", + "\( y = e^{-x} \)", + "\( y = -e^{-x} \)", + "\( y = e^{x} \)" +); # Alternate text for each image. @alt_text = ( @@ -53,7 +60,15 @@ $k = random(0, 3); $popup = PopUp([ "?", "A", "B", "C", "D" ], $letter[ $inv[$k] ]); -$tab = LayoutTable([ [ 'A', 'B' ], [ $fig[0], $fig[1] ], [ 'C', 'D' ], [ $fig[2], $fig[3] ], ], texalignment => 'cc'); +$tab = LayoutTable( + [ + [ 'A', 'B' ], + [ $fig[0], $fig[1] ], + [ 'C', 'D' ], + [ $fig[2], $fig[3] ], + ], + texalignment => 'cc' +); BEGIN_PGML Consider the exponential equation [$eqn[$k]]. diff --git a/sample-problems/problem-techniques/HtmlLinks.html b/sample-problems/problem-techniques/HtmlLinks.html index ae72e80..32d06f7 100644 --- a/sample-problems/problem-techniques/HtmlLinks.html +++ b/sample-problems/problem-techniques/HtmlLinks.html @@ -48,7 +48,10 @@

    POD for Macro Files

    DOCUMENT();
    -loadMacros('PGstandard.pl', 'PGML.pl', 'parserNumberWithUnits.pl', 'PGcourse.pl');
    +loadMacros(
    +    'PGstandard.pl',            'PGML.pl',
    +    'parserNumberWithUnits.pl', 'PGcourse.pl'
    +);
     
    @@ -144,7 +150,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/HtmlLinks.pg b/sample-problems/problem-techniques/HtmlLinks.pg index b7a8988..95e4a4b 100644 --- a/sample-problems/problem-techniques/HtmlLinks.pg +++ b/sample-problems/problem-techniques/HtmlLinks.pg @@ -1,5 +1,8 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'parserNumberWithUnits.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'parserNumberWithUnits.pl', 'PGcourse.pl' +); $ans = NumberWithUnits('4', 'ft'); diff --git a/sample-problems/problem-techniques/Images.html b/sample-problems/problem-techniques/Images.html index 3f11a8d..9c13500 100644 --- a/sample-problems/problem-techniques/Images.html +++ b/sample-problems/problem-techniques/Images.html @@ -52,8 +52,12 @@

    POD for Macro Files

    DOCUMENT();
     
    -loadMacros('PGstandard.pl', 'PGML.pl', 'PGgraphmacros.pl', 'PGtikz.pl',
    -  'PGlateximage.pl', 'parserGraphTool.pl', 'PGcourse.pl');
    +loadMacros(
    +    'PGstandard.pl',    'PGML.pl',
    +    'PGgraphmacros.pl', 'PGtikz.pl',
    +    'PGlateximage.pl',  'parserGraphTool.pl',
    +    'PGcourse.pl'
    +);
     
    @@ -74,7 +82,7 @@

    POD for Macro Files

    -
    $WWPlot = init_graph(-1,-1,4,4);
    +					
    $WWPlot = init_graph(-1, -1, 4, 4);
     add_functions($WWPlot, "x^2/4 for x in <-1,4> using color:blue and weight:2");
     
     $TikZ = createTikZImage();
    @@ -105,7 +113,7 @@ 

    POD for Macro Files

    END_TIKZ $LaTeXImage = createLaTeXImage(); -$LaTeXImage->texPackages([['xy','all']]); +$LaTeXImage->texPackages([ [ 'xy', 'all' ] ]); $LaTeXImage->BEGIN_LATEX_IMAGE \xymatrix{ A \ar[r] & B \ar[d] \\\\ D \ar[u] & C \ar[l] } @@ -139,7 +147,6 @@

    POD for Macro Files

    END_PGML - ENDDOCUMENT();" aria-label="copy to clipboard"> @@ -163,7 +170,6 @@

    POD for Macro Files

    END_PGML - ENDDOCUMENT();
    @@ -187,7 +193,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/Images.pg b/sample-problems/problem-techniques/Images.pg index e61e6a2..e1af2dc 100644 --- a/sample-problems/problem-techniques/Images.pg +++ b/sample-problems/problem-techniques/Images.pg @@ -1,9 +1,13 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'PGgraphmacros.pl', 'PGtikz.pl', - 'PGlateximage.pl', 'parserGraphTool.pl', 'PGcourse.pl'); - -$WWPlot = init_graph(-1,-1,4,4); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'PGgraphmacros.pl', 'PGtikz.pl', + 'PGlateximage.pl', 'parserGraphTool.pl', + 'PGcourse.pl' +); + +$WWPlot = init_graph(-1, -1, 4, 4); add_functions($WWPlot, "x^2/4 for x in <-1,4> using color:blue and weight:2"); $TikZ = createTikZImage(); @@ -12,7 +16,7 @@ $TikZ->BEGIN_TIKZ END_TIKZ $LaTeXImage = createLaTeXImage(); -$LaTeXImage->texPackages([['xy','all']]); +$LaTeXImage->texPackages([ [ 'xy', 'all' ] ]); $LaTeXImage->BEGIN_LATEX_IMAGE \xymatrix{ A \ar[r] & B \ar[d] \\\\ D \ar[u] & C \ar[l] } @@ -37,5 +41,4 @@ BEGIN_PGML END_PGML - ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/problem-techniques/InequalityEvaluators.html b/sample-problems/problem-techniques/InequalityEvaluators.html index 36ffcd8..c43fc9b 100644 --- a/sample-problems/problem-techniques/InequalityEvaluators.html +++ b/sample-problems/problem-techniques/InequalityEvaluators.html @@ -179,7 +179,8 @@

    See Also

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/IntervalEvaluators.html b/sample-problems/problem-techniques/IntervalEvaluators.html index bed0ace..5b6787a 100644 --- a/sample-problems/problem-techniques/IntervalEvaluators.html +++ b/sample-problems/problem-techniques/IntervalEvaluators.html @@ -156,7 +156,8 @@

    See Also

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/Knowls.html b/sample-problems/problem-techniques/Knowls.html index 93fae92..25c9f3c 100644 --- a/sample-problems/problem-techniques/Knowls.html +++ b/sample-problems/problem-techniques/Knowls.html @@ -113,7 +113,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/LayoutTable.html b/sample-problems/problem-techniques/LayoutTable.html index e66cd19..f9347fd 100644 --- a/sample-problems/problem-techniques/LayoutTable.html +++ b/sample-problems/problem-techniques/LayoutTable.html @@ -56,7 +56,10 @@

    See Also

    DOCUMENT();
    -loadMacros('PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'PGtikz.pl', 'PGcourse.pl');
    +loadMacros(
    +    'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'PGtikz.pl',
    +    'PGcourse.pl'
    +);
     
    @@ -166,14 +172,20 @@

    See Also

    -
    TEXT(LayoutTable([ [ $left, image($graph, width => 400, tex_size => 600) ] ], align => 'lc'));
    +					
    TEXT(LayoutTable(
    +    [ [ $left, image($graph, width => 400, tex_size => 600) ] ],
    +    align => 'lc'
    +));
     
    @@ -231,7 +243,8 @@

    See Also

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/LayoutTable.pg b/sample-problems/problem-techniques/LayoutTable.pg index 62c4292..ca87fea 100644 --- a/sample-problems/problem-techniques/LayoutTable.pg +++ b/sample-problems/problem-techniques/LayoutTable.pg @@ -1,5 +1,8 @@ DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'PGtikz.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', 'niceTables.pl', 'PGtikz.pl', + 'PGcourse.pl' +); $a = random(0, 3); $ans = Compute("x^2+$a")->reduce; @@ -34,7 +37,10 @@ $graph->BEGIN_TIKZ \draw[blue,ultra thick] plot[domain=-2.5:2.5,smooth] (\x,{\x*\x+$a}); END_TIKZ -TEXT(LayoutTable([ [ $left, image($graph, width => 400, tex_size => 600) ] ], align => 'lc')); +TEXT(LayoutTable( + [ [ $left, image($graph, width => 400, tex_size => 600) ] ], + align => 'lc' +)); ANS($ans->cmp); diff --git a/sample-problems/problem-techniques/Multianswer.html b/sample-problems/problem-techniques/Multianswer.html new file mode 100644 index 0000000..6fc407e --- /dev/null +++ b/sample-problems/problem-techniques/Multianswer.html @@ -0,0 +1,197 @@ + + + + + + + Multianswer.pg + + + + + + + + + + +
    +
    +
    +

    Multianswer Problem

    +

    A simple multianswer problem.

    +
    + +
    +
    +
    +

    Complete Code

    +

    + Download file: Multianswer.pg +

    +
    +
    +

    POD for Macro Files

    + +
    +
    +
    +

    PG problem file

    +

    Explanation

    +
    +
    +
    + +
    DOCUMENT();
    +loadMacros('PGstandard.pl', 'PGML.pl', 'parserMultiAnswer.pl', 'PGcourse.pl');
    +
    +
    +
    +

    Preamble

    +

    Since we are using the Multianswer technique, parserMultianswer.pl must be loaded.

    +
    +
    +
    +
    + +
    $fac1 = Formula("(1 - x)");
    +$fac2 = Formula("(1 + x)");
    +
    +$multians = MultiAnswer($fac1, $fac2)->with(
    +    singleResult => 0,
    +    checker      => sub {
    +        my ($correct, $student, $self) = @_;
    +        my ($f1stu, $f2stu) = @{$student};
    +        my ($f1,    $f2)    = @{$correct};
    +        if (($f1 == $f1stu && $f2 == $f2stu)
    +            || ($f1 == $f2stu && $f2 == $f1stu))
    +        {
    +            return [ 1, 1 ];
    +        } else {
    +            if ($f1 == $f1stu || $f2 == $f1stu) {
    +                return [ 1, 0 ];
    +            } elsif ($f1 == $f2stu || $f2 == $f2stu) {
    +                return [ 0, 1 ];
    +            } else {
    +                return [ 0, 0 ];
    +            }
    +        }
    +    }
    +);
    +
    +BEGIN_PGML
    +Factor: [`1-x^2 = \big(`] [___]{$multians}
    +[`\big)\big(`] [___]{$multians} [`\big)`]
    +END_PGML
    +
    +
    +
    +

    Setup

    +

    This problem is shown as an example of using parserMultiAnswer.pl. A better solution for this type of problem is shown in Factored Polynomial.

    +

    In the setup section of the file we define a MultiAnswer object that knows how to deal with the problem. Here we define an object that will take two answers and check that they are correct (in either order).

    +

    First, the singleResult=>0 line indicates that the different answers in the problem will be evaluated as separate answers, rather than as a single unit. Other useful flags include allowBlankAnswers, checkTypes, separator and tex_separator. These are noted below.

    +

    Then, the checker=> section defines a subroutine to evaluate the problem. It will always have as input a reference to an array of correct answers, a reference to an array of student answers, and a reference to the object itself. (There is a fourth input, too, an answer hash, but we don’t need that here.)

    +

    The checker routine then returns a reference to a list of results for the problem. In this case there are two answer blanks, so there are two return values. All return values should be 0 or 1, according to whether the answer for that answer blank is correct or not. Note that if we made this an “all or nothing” problem (that is, we set singleResult=>1), then there is only one return value needed, so that we could just return 0 or return 1.

    +

    It is possible to set an answer message that will be displayed when the problem is checked, too. For example, if we wanted to set a message when one of the parts was wrong, we could replace the section of the checker code that deals with incorrect answers with:

    +
     if ($f1 == $f1stu || $f2 == $f1stu) {
    +   $self->setMessage(1,"This is correct.");
    +   $self->setMessage(2,"Check your answer " .
    +       "by using FOIL.");
    +   return [1,0];
    + } elsif ($f1 == $f1stu || $f2 == $f2stu) {
    +   $self->setMessage(1,"Check your answer " .
    +       "by using FOIL.");
    +   $self->setMessage(2,"This is correct.");
    +   return [0,1];
    + } else {
    +   return [0,0];
    + }
    +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/problem-techniques/Multianswer.pg b/sample-problems/problem-techniques/Multianswer.pg new file mode 100644 index 0000000..6d3fa1b --- /dev/null +++ b/sample-problems/problem-techniques/Multianswer.pg @@ -0,0 +1,38 @@ +DOCUMENT(); +loadMacros('PGstandard.pl', 'PGML.pl', 'parserMultiAnswer.pl', 'PGcourse.pl'); + +$fac1 = Formula("(1 - x)"); +$fac2 = Formula("(1 + x)"); + +$multians = MultiAnswer($fac1, $fac2)->with( + singleResult => 0, + checker => sub { + my ($correct, $student, $self) = @_; + my ($f1stu, $f2stu) = @{$student}; + my ($f1, $f2) = @{$correct}; + if (($f1 == $f1stu && $f2 == $f2stu) + || ($f1 == $f2stu && $f2 == $f1stu)) + { + return [ 1, 1 ]; + } else { + if ($f1 == $f1stu || $f2 == $f1stu) { + return [ 1, 0 ]; + } elsif ($f1 == $f2stu || $f2 == $f2stu) { + return [ 0, 1 ]; + } else { + return [ 0, 0 ]; + } + } + } +); + +BEGIN_PGML +Factor: [`1-x^2 = \big(`] [___]{$multians} +[`\big)\big(`] [___]{$multians} [`\big)`] +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/problem-techniques/NumericalTolerance.html b/sample-problems/problem-techniques/NumericalTolerance.html index 8513b47..997517d 100644 --- a/sample-problems/problem-techniques/NumericalTolerance.html +++ b/sample-problems/problem-techniques/NumericalTolerance.html @@ -185,7 +185,8 @@

    See Also

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/OtherVariables.html b/sample-problems/problem-techniques/OtherVariables.html index b70c546..2eeed8b 100644 --- a/sample-problems/problem-techniques/OtherVariables.html +++ b/sample-problems/problem-techniques/OtherVariables.html @@ -151,7 +151,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/Percent.html b/sample-problems/problem-techniques/Percent.html index e8a43c8..51df0df 100644 --- a/sample-problems/problem-techniques/Percent.html +++ b/sample-problems/problem-techniques/Percent.html @@ -140,7 +140,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/RandomFunction.html b/sample-problems/problem-techniques/RandomFunction.html index 9e38317..4fbcae9 100644 --- a/sample-problems/problem-techniques/RandomFunction.html +++ b/sample-problems/problem-techniques/RandomFunction.html @@ -66,7 +66,13 @@

    Complete Code

    $b = random(1, 8); $n = random(2, 4); -@funs = ("1 + $a*x + $b x^2", "$a / (1 + $b x)", "$a x^3 + $b", "($a - x) / ($b + x^2)", "cos($n*x)"); +@funs = ( + "1 + $a*x + $b x^2", + "$a / (1 + $b x)", + "$a x^3 + $b", + "($a - x) / ($b + x^2)", + "cos($n*x)" +); # This select one of the functions at random. $f = Formula($funs[ random(0, $#funs) ])->reduce; @@ -81,7 +87,13 @@

    Complete Code

    $b = random(1, 8); $n = random(2, 4); -@funs = ("1 + $a*x + $b x^2", "$a / (1 + $b x)", "$a x^3 + $b", "($a - x) / ($b + x^2)", "cos($n*x)"); +@funs = ( + "1 + $a*x + $b x^2", + "$a / (1 + $b x)", + "$a x^3 + $b", + "($a - x) / ($b + x^2)", + "cos($n*x)" +); # This select one of the functions at random. $f = Formula($funs[ random(0, $#funs) ])->reduce; @@ -146,7 +158,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/RandomFunction.pg b/sample-problems/problem-techniques/RandomFunction.pg index 375754f..c05fce5 100644 --- a/sample-problems/problem-techniques/RandomFunction.pg +++ b/sample-problems/problem-techniques/RandomFunction.pg @@ -6,7 +6,13 @@ $a = non_zero_random(-8, 8); $b = random(1, 8); $n = random(2, 4); -@funs = ("1 + $a*x + $b x^2", "$a / (1 + $b x)", "$a x^3 + $b", "($a - x) / ($b + x^2)", "cos($n*x)"); +@funs = ( + "1 + $a*x + $b x^2", + "$a / (1 + $b x)", + "$a x^3 + $b", + "($a - x) / ($b + x^2)", + "cos($n*x)" +); # This select one of the functions at random. $f = Formula($funs[ random(0, $#funs) ])->reduce; diff --git a/sample-problems/problem-techniques/RestrictAnswerToFraction.html b/sample-problems/problem-techniques/RestrictAnswerToFraction.html new file mode 100644 index 0000000..6ca15ca --- /dev/null +++ b/sample-problems/problem-techniques/RestrictAnswerToFraction.html @@ -0,0 +1,192 @@ + + + + + + + RestrictAnswerToFraction.pg + + + + + + + + + + +
    +
    +
    +

    Restrict Answers to a Fraction

    +

    Restricting answers that should reduce to a fraction.

    +
    + +
    +
    +
    +

    Complete Code

    +

    + Download file: RestrictAnswerToFraction.pg +

    +
    +
    +

    POD for Macro Files

    + +
    + +
    +
    +

    PG problem file

    +

    Explanation

    +
    +
    +
    + +
    DOCUMENT();
    +
    +loadMacros('PGstandard.pl', 'PGML.pl', 'contextFraction.pl', 'PGcourse.pl');
    +
    +
    +
    +

    Preamble

    + These standard macros need to be loaded. +
    +
    +
    +
    + +
    Context("Fraction-NoDecimals");
    +Context()->operators->undefine('+', '-', '*', '*', '**', '^');
    +
    +$a    = random(2, 4);
    +$b    = random(1, 9);
    +$c    = random(1, 9);
    +$den  = $c + $a * $a;
    +$frac = Compute("$b/$den");
    +$ans  = $frac->cmp(
    +    studentsMustReduceFractions => 1,
    +    strictFractions             => 1,
    +    strictMinus                 => 1,
    +    strictMultiplication        => 1
    +);
    +
    +
    +

    Setup

    +

    Here we specify that we are using the Fractions-NoDecimals Context, which requires that answers be fractions and not decimals. To ensure that students do the simplification rather than typing the answer without expanding it, we undefine operators other than division (see Restricting Functions and Operators).

    +

    Note that because we’ve undefined these operators for all MathObjects, we can’t define the answer as $frac=Compute("$b/($c + $a^2)");. The operators + and ^ are undefined, so we don’t have them available. In this case we do the calculation of the denominator using Perl first, and then use the MathObject to create the answer.

    +

    Also note that by default a Fraction will be reduced to lowest terms.

    +
    +
    +
    +
    + +
    BEGIN_PGML
    +Find and simplify completely the value of
    +[`f([$a])`] if [`` f(x) = \frac{[$b]}{[$c] + x^2}. ``]
    +
    +[`f([$a]) = `] [__]{$ans}
    +
    +_(Simplify your answer as much as possible, and enter a fraction instead of
    +a decimal.)_
    +END_PGML
    +
    +
    +
    +

    Statement

    + This is the problem statement in PGML. +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/problem-techniques/RestrictAnswerToFraction.pg b/sample-problems/problem-techniques/RestrictAnswerToFraction.pg new file mode 100644 index 0000000..7a2984a --- /dev/null +++ b/sample-problems/problem-techniques/RestrictAnswerToFraction.pg @@ -0,0 +1,33 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'contextFraction.pl', 'PGcourse.pl'); + +Context("Fraction-NoDecimals"); +Context()->operators->undefine('+', '-', '*', '*', '**', '^'); + +$a = random(2, 4); +$b = random(1, 9); +$c = random(1, 9); +$den = $c + $a * $a; +$frac = Compute("$b/$den"); +$ans = $frac->cmp( + studentsMustReduceFractions => 1, + strictFractions => 1, + strictMinus => 1, + strictMultiplication => 1 +); +BEGIN_PGML +Find and simplify completely the value of +[`f([$a])`] if [`` f(x) = \frac{[$b]}{[$c] + x^2}. ``] + +[`f([$a]) = `] [__]{$ans} + +_(Simplify your answer as much as possible, and enter a fraction instead of +a decimal.)_ +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/problem-techniques/RestrictingFunctions.html b/sample-problems/problem-techniques/RestrictingFunctions.html new file mode 100644 index 0000000..77588a1 --- /dev/null +++ b/sample-problems/problem-techniques/RestrictingFunctions.html @@ -0,0 +1,154 @@ + + + + + + + RestrictingFunctions.pg + + + + + + + + + + +
    +
    +
    +

    Restrict Answers to a Constant

    +

    Restricting answers that should reduce to a constant.

    +
    + +
    +
    +
    +

    Complete Code

    +

    + Download file: RestrictingFunctions.pg +

    +
    + +
    +
    +

    PG problem file

    +

    Explanation

    +
    +
    +
    + +
    DOCUMENT();
    +
    +loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl');
    +
    +
    +
    +

    Preamble

    + These standard macros need to be loaded. +
    +
    +
    +
    + +
    $expr  = Formula("sin(x)^2 + cos(x)^2");
    +$deriv = Compute(0)->cmp(showTypeWarnings => 0);
    +
    +
    +
    +

    Setup

    +

    Here we’ve turned off type warnings in the answer checking, so that a student entering an un-simplified answer (e.g., 2 sin(x) cos(x) + 2 cos(x) (-sin(x))) will have it marked wrong (but not get feedback that says “you should have entered a number”).

    +
    +
    +
    +
    + +
    BEGIN_PGML
    +Find and completely simplify:
    +
    +[``\frac{d}{dx}\bigl(\sin^2 x + \cos^2 x\bigr) = ``] [__]{$deriv}
    +END_PGML
    +
    +
    +
    +

    Statement

    + This is the problem statement in PGML. +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/problem-techniques/RestrictingFunctions.pg b/sample-problems/problem-techniques/RestrictingFunctions.pg new file mode 100644 index 0000000..ba0d4ce --- /dev/null +++ b/sample-problems/problem-techniques/RestrictingFunctions.pg @@ -0,0 +1,18 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); + +$expr = Formula("sin(x)^2 + cos(x)^2"); +$deriv = Compute(0)->cmp(showTypeWarnings => 0); + +BEGIN_PGML +Find and completely simplify: + +[``\frac{d}{dx}\bigl(\sin^2 x + \cos^2 x\bigr) = ``] [__]{$deriv} +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/problem-techniques/SimplePopUp.html b/sample-problems/problem-techniques/SimplePopUp.html new file mode 100644 index 0000000..8f0b0e6 --- /dev/null +++ b/sample-problems/problem-techniques/SimplePopUp.html @@ -0,0 +1,181 @@ + + + + + + + SimplePopUp.pg + + + + + + + + + + +
    +
    +
    +

    Simple Popup

    +

    Answers are lists of points

    +
    + +
    +
    +
    +

    Complete Code

    +

    + Download file: SimplePopUp.pg +

    +
    +
    +

    POD for Macro Files

    + +
    +
    +
    +

    PG problem file

    +

    Explanation

    +
    +
    +
    + +
    DOCUMENT();
    +
    +loadMacros('PGstandard.pl', 'PGML.pl', 'parserPopUp.pl', 'PGcourse.pl');
    +
    +
    +
    +

    Preamble

    +

    We need to load parserPopUp.pl for this feature.

    +
    +
    +
    +
    + +
    $popup = PopUp([ "?", "one", "two", "three" ], "three");
    +
    +$dropdown1 = DropDown([ 'one', 'two', 'three' ], 'two');
    +$dropdown2 = DropDown([ 'one', 'two', 'three' ],
    +    'one', placeholder => 'Select an option');
    +$dropdown3 =
    +    DropDown([ 'one', [ 'two', 'three', 'four', 'five' ], 'six' ], 'six');
    +
    +$tf = DropDownTF('T');
    +
    +
    +
    +

    Setup

    +

    This shows a number of ways to use either PopUp (the legacy version) or DropDown (a more flexible version). Both create an HTML select object. The PopUp takes a array reference of option and the correct answer and creates the options. Notice in Popup the first element is shown, but selectable, whereas in DropDown, the first either defaults to ? or whatever is in the placeholder option. In Dropdown, the first element is not selectable.

    +

    Similar to other parser objects, inserting another array reference, randomizes those options.

    +

    Lastly, the DropDownTF creates a true/false dropdown for simplicity.

    +
    +
    +
    +
    + +
    BEGIN_PGML
    +
    +- [_]{$popup} (ans: 'three')
    +- [_]{$dropdown1} (ans: 'two')
    +- [_]{$dropdown2} (ans: 'one')
    +- [_]{$dropdown3} (ans: 'six')
    +- [_]{$tf} (ans: 'True')
    +
    +END_PGML
    +
    +
    +
    +

    Statement

    + This is the problem statement in PGML. +
    +
    +
    +
    + +
    BEGIN_PGML_SOLUTION
    +Solution explanation goes here.
    +END_PGML_SOLUTION
    +
    +COMMENT('MathObject version. Uses PGML.');
    +
    +ENDDOCUMENT();
    +
    +
    +

    Solution

    + A solution should be provided here. +
    +
    +
    + + + + + diff --git a/sample-problems/problem-techniques/SimplePopUp.pg b/sample-problems/problem-techniques/SimplePopUp.pg new file mode 100644 index 0000000..0dea6be --- /dev/null +++ b/sample-problems/problem-techniques/SimplePopUp.pg @@ -0,0 +1,31 @@ +DOCUMENT(); + +loadMacros('PGstandard.pl', 'PGML.pl', 'parserPopUp.pl', 'PGcourse.pl'); + +$popup = PopUp([ "?", "one", "two", "three" ], "three"); + +$dropdown1 = DropDown([ 'one', 'two', 'three' ], 'two'); +$dropdown2 = DropDown([ 'one', 'two', 'three' ], + 'one', placeholder => 'Select an option'); +$dropdown3 = + DropDown([ 'one', [ 'two', 'three', 'four', 'five' ], 'six' ], 'six'); + +$tf = DropDownTF('T'); + +BEGIN_PGML + +- [_]{$popup} (ans: 'three') +- [_]{$dropdown1} (ans: 'two') +- [_]{$dropdown2} (ans: 'one') +- [_]{$dropdown3} (ans: 'six') +- [_]{$tf} (ans: 'True') + +END_PGML + +BEGIN_PGML_SOLUTION +Solution explanation goes here. +END_PGML_SOLUTION + +COMMENT('MathObject version. Uses PGML.'); + +ENDDOCUMENT(); \ No newline at end of file diff --git a/sample-problems/problem-techniques/StaticImages.html b/sample-problems/problem-techniques/StaticImages.html index f05cf08..2063aa0 100644 --- a/sample-problems/problem-techniques/StaticImages.html +++ b/sample-problems/problem-techniques/StaticImages.html @@ -102,7 +102,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/StringsInContext.html b/sample-problems/problem-techniques/StringsInContext.html index f39ec57..eefd509 100644 --- a/sample-problems/problem-techniques/StringsInContext.html +++ b/sample-problems/problem-techniques/StringsInContext.html @@ -159,7 +159,8 @@

    See Also

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/TikZImages.html b/sample-problems/problem-techniques/TikZImages.html index 551f999..44d9deb 100644 --- a/sample-problems/problem-techniques/TikZImages.html +++ b/sample-problems/problem-techniques/TikZImages.html @@ -199,7 +199,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/WeightedGrader.html b/sample-problems/problem-techniques/WeightedGrader.html index 7a403cf..31bbb80 100644 --- a/sample-problems/problem-techniques/WeightedGrader.html +++ b/sample-problems/problem-techniques/WeightedGrader.html @@ -67,56 +67,49 @@

    POD for Macro Files

    -
    BEGIN_PGML
    -
    -* This answer is worth 20%.  Enter 1 [___]
    -
    -* This answer is worth 50%. Enter 3 [___]
    -
    -* This answer is worth 30%. Enter 7 [___]
    -END_PGML
    +					
    install_weighted_grader();
     

    Setup

    -

    The answer blanks do not have answers associated with them because we will use the WEIGHTED_ANS command below.

    +

    Call install_weighted_grader(); so that the weighted grader is used.

    -
    install_weighted_grader();
    +					
    BEGIN_PGML
    +* This answer is worth 20%.  Enter 1 [___]{1}{ cmp_options => { weight => 20 } }
     
    -WEIGHTED_ANS(Real(1)->cmp, 20, Real(3)->cmp, 50, Real(7)->cmp, 30);
    +* This answer is worth 50%. Enter 3 [___]{3}{ cmp_options => { weight => 50 } }
    +
    +* This answer is worth 30%. Enter 7 [___]{7}{ cmp_options => { weight => 30 } }
    +END_PGML
     
    -
    -

    Answer

    -

    Before checking answers, install_weighted_grader(); needs to be called to ensure the weighted grader is used.

    -

    The WEIGHTED_ANS command takes pairs of answer checkers and their relative weights. The example here gives weights as percents as the total weights added to 100, but weights of (2,5,3) or (4,10,6) would have worked the same way.

    +
    +

    Statement

    +

    Assign weights to answers by passing the weight via cmp_options. The example here gives weights as percents that sum to 100, but weights of (2, 5, 3), (4, 10, 6), or (0.2, 0.5, 0.3) would give the same weighting.

    @@ -151,7 +144,8 @@

    POD for Macro Files

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/problem-techniques/WeightedGrader.pg b/sample-problems/problem-techniques/WeightedGrader.pg index 03e855f..c98be88 100644 --- a/sample-problems/problem-techniques/WeightedGrader.pg +++ b/sample-problems/problem-techniques/WeightedGrader.pg @@ -1,19 +1,16 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'weightedGrader.pl', 'PGcourse.pl'); -BEGIN_PGML +install_weighted_grader(); -* This answer is worth 20%. Enter 1 [___] +BEGIN_PGML +* This answer is worth 20%. Enter 1 [___]{1}{ cmp_options => { weight => 20 } } -* This answer is worth 50%. Enter 3 [___] +* This answer is worth 50%. Enter 3 [___]{3}{ cmp_options => { weight => 50 } } -* This answer is worth 30%. Enter 7 [___] +* This answer is worth 30%. Enter 7 [___]{7}{ cmp_options => { weight => 30 } } END_PGML -install_weighted_grader(); - -WEIGHTED_ANS(Real(1)->cmp, 20, Real(3)->cmp, 50, Real(7)->cmp, 30); - BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION diff --git a/sample-problems/snippets/CommentsForInstructors.html b/sample-problems/snippets/CommentsForInstructors.html index e0dd413..836957d 100644 --- a/sample-problems/snippets/CommentsForInstructors.html +++ b/sample-problems/snippets/CommentsForInstructors.html @@ -66,7 +66,8 @@

    Complete Code

    } for (const btn of document.querySelectorAll('.clipboard-btn')) { - btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + if (navigator.clipboard) btn.addEventListener('click', () => navigator.clipboard.writeText(btn.dataset.code)); + else btn?.remove(); } diff --git a/sample-problems/subjects.html b/sample-problems/subjects.html index f6a0186..1012a80 100644 --- a/sample-problems/subjects.html +++ b/sample-problems/subjects.html @@ -83,13 +83,318 @@

    Subject Areas

    - + +
    +

    Sample Problems for Subject: answer

    + +
    +
    +

    Sample Problems for Subject: chemistry

    + +
    + + + +
    +

    Sample Problems for Subject: graph

    + +
    + +
    +

    Sample Problems for Subject: linear algebra

    + +
    +
    +

    Sample Problems for Subject: multivariate calculus

    + +
    + + +
    +

    Sample Problems for Subject: proof

    + +
    +
    +

    Sample Problems for Subject: sequences and series

    + +
    +
    +

    Sample Problems for Subject: statistics

    + +
    + + +