<section xml:id="section-dynamic-exercises" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Dynamic Exercises</title>
<p>
This section demonstrates the use of dynamic randomized exercises built upon the framework of Runestone components. These demonstration problems incorporate a library supporting mathematical expressions both for varying the content of the statement of the exercises as well as the checking of submitted answers. Then there is an example where a custom library is used for defining and parsing answer objects without using the built-in math library, and which also illustrates the use of a config structure passed in JSON format.
</p>
<exercises>
<title>Dynamic Fill-In</title>
<introduction>
<p>
The first problem illustrates revised markup for fill-in problems that don't involve randomization and use simple string and number comparison tests. Later exercises illustrate the use of dynamically generated mathematical expressions.
</p>
</introduction>
<exercise label="fillin-string-integer-new">
<title>Fill-In, String and Number Answers</title>
<statement>
<p>
Complete the following line of a Python program so that it will declare an integer variable <c>age</c> with an initial value of <c>5</c>.
</p>
<p>
<fillin mode="string" answer="int"/> <c>age = </c> <fillin mode="number" answer="5"/><c>;</c>
</p>
</statement>
<evaluation> <evaluate> <test> <strcmp use-answer="yes"/>
<feedback>
<p>
A variable of type <c>int</c> is appropriate for whole number ages.
</p>
</feedback>
</test> <test> <strcmp>.*</strcmp>
<feedback>
<p>
Remember that Java uses just the first three letters of the word <q>integer</q> to define an integral type.
</p>
</feedback>
</test> </evaluate> <evaluate> <test> <numcmp use-answer="yes"/>
<feedback>
<p>
An integer variable may be initialized to a value.
</p>
</feedback>
</test> <test> <strcmp>.*</strcmp>
<feedback>
<p>
Use <c>5</c> as the initial value of the variable.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
<exercise label="fillin-multi-answer-jscmp">
<title>Fill-In, Multiple Strings, Custom Checker</title>
<statement>
<p>
In order to apply the Integral Test to a sequence <m>\{a_n\}</m>, the function <m>a(n) = a_n</m> must be <fillin mode="string" answer="continuous"/>, <fillin mode="string" answer="positive"/><nbsp/>and <fillin mode="string" answer="decreasing"/>.
</p>
</statement>
<evaluation> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) </jscmp> </test> </evaluate> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) && !ans_array.slice(0,1).includes(ans) </jscmp> </test> <test> <jscmp> ans_array.slice(0,1).includes(ans) </jscmp>
<feedback>
<p>
You already gave that answer.
</p>
</feedback>
</test> </evaluate> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) && !ans_array.slice(0,2).includes(ans) </jscmp> </test> <test> <jscmp> ans_array.slice(0,2).includes(ans) </jscmp>
<feedback>
<p>
You already gave that answer.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
<exercise label="dynamic-fitb-simple-formula">
<title>Fill-In Formula (Dynamic)</title>
<statement>
<p>
Find a formula for a cubic function <m>f(x)</m> that has roots at <m>x=<eval obj="x1"/></m>, <m>x=<eval obj="x2"/></m>, and <m>x=<eval obj="x3"/></m> and so that <m>f(0)=<eval obj="y0"/></m>.
</p>
<p>
<m>f(x)=</m> <fillin name="st_cubic" mode="math" ansobj="cubic"/>
</p>
</statement>
<solution>
<p>
Knowing the roots of a polynomial allows us to write down the formula of <m>f(x)</m> in factored form,
<md>
f(x) = A <eval obj="base_cubic"/>
</md>
with an unknown scaling multiple <m>A</m>.
</p>
<p>
When we evaluate <m>f(x)</m> at <m>x=0</m> using this formula, we find
<md>
f(0) = <eval obj="base_yint"/>A
</md>.
Since we also know <m>f(0)=<eval obj="y0"/></m>, we can write down the equation
<md>
A <eval obj="base_cubic"/> = <eval obj="y0"/>
</md>
and find that <m>A=<eval obj="A"/></m>.
</p>
<p>
Consequently, we can write our function in the form
<md>
f(x)=<eval obj="cubic"/>
</md>.
</p>
</solution>
<setup seed="314159"> <de-object name="y0" context="number"> <de-random distribution="discrete" min="-8" max="8" by="1" nonzero="yes"/> </de-object> <de-object name="x1" context="number"> <de-random distribution="discrete" min="-8" max="-4" by="1"/> </de-object> <de-object name="d1" context="number"> <de-random distribution="discrete" min="1" max="4" by="1"/> </de-object> <de-object name="d2" context="number"> <de-random distribution="discrete" min="1" max="4" by="1"/> </de-object> <de-object name="x2" context="number"> <de-number>x1+d1</de-number> </de-object> <de-object name="x3" context="number"> <de-number>x2+d2</de-number> </de-object> <de-object name="base_cubic" context="formula"> <de-expression reduce="yes">(x-x1)*(x-x2)*(x-x3)</de-expression> </de-object> <de-object name="base_yint" context="number"> <de-evaluate> <formula><eval obj="base_cubic"/></formula> <variable name="x"><de-number>0</de-number></variable> </de-evaluate> </de-object> <de-object name="A" context="number"> <de-number reduce="yes">y0/base_yint</de-number> </de-object> <de-object name="cubic" context="formula"> <de-expression reduce="yes">A*(x-x1)*(x-x2)*(x-x3)</de-expression> </de-object> </setup> <evaluation> <evaluate name="st_cubic"> <test correct="yes"> <mathcmp obj="cubic"/> </test> </evaluate> </evaluation>
</exercise>
<exercise label="function-decomposition">
<title>Decompose the Function</title>
<statement>
<p>
Consider the function
<md>
h(x)=<eval obj="composition"/>
</md>.
Find two nontrivial functions <m>f(x)</m> and <m>g(x)</m> so that <m>h(x) = f(g(x))</m>.
</p>
<p>
<m>f(x) = </m> <fillin width="15" mode="math" ansobj="outerFormula" name="fGiven"/> and <m>g(x)=</m> <fillin width="15" mode="math" ansobj="innerFormula" name="gGiven"/>
</p>
</statement>
<solution>
<p>
Noticing that the expression <m><eval obj="innerFormula"/></m> appears inside parentheses with a power, it makes sense to think of that as the inner function, defining <m>g(x) = <eval obj="innerFormula"/></m>. The outer function describes what happens to that. If we imagined replacing the formula <m><eval obj="innerFormula"/></m> with a box and then call that box our variable <m>x</m>, we find the outer function is given by <m>f(x) = <eval obj="outerFormula"/></m>.
</p>
<p>
This is not the only non-trivial composition. Can you find others?
</p>
</solution>
<setup seed="4321"> <de-object name="a" context="number"> <de-random distribution="discrete" min="-4" max="5" by="1" nonzero="yes"/> </de-object> <de-object name="n" context="number"> <de-random distribution="discrete" min="2" max="5"/> </de-object> <de-object name="b" context="number"> <de-random distribution="discrete" min="-10" max="10" by="1" nonzero="yes"/> </de-object> <de-object name="c" context="number"> <de-random distribution="discrete" min="-4" max="5" by="1" nonzero="yes"/> </de-object> <de-object name="d" context="number"> <de-random distribution="discrete" min="-10" max="10" by="1" nonzero="yes"/> </de-object> <de-object name="outerFormula" context="formula"> <de-expression>a*x^n+b</de-expression> </de-object> <de-object name="innerFormula" context="formula"> <de-expression>c*x+d</de-expression> </de-object> <de-object name="identityFunction" context="formula"> <de-expression>x</de-expression> </de-object> <de-object name="composition" context="formula"> <de-expression mode="substitution" reduce="yes"> <formula><eval obj="outerFormula"/></formula> <variable name="x"><eval obj="innerFormula"/></variable> </de-expression> </de-object> </setup> <evaluation answers-coupled="yes"> <evaluate name="fGiven"> <test> <mathcmp obj="identityFunction"/>
<feedback>
<p>
<m>f(x)=x</m> is not allowed for nontrivial compositions.
</p>
</feedback>
</test> <test> <logic op="and"> <logic op="not"> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="fGiven"/></formula> <variable name="x"><eval obj="gGiven"/></variable> </de-expression> </mathcmp> </logic> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="gGiven"/></formula> <variable name="x"><eval obj="fGiven"/></variable> </de-expression> </mathcmp> </logic>
<feedback>
<p>
You have composed in the wrong order.
</p>
</feedback>
</test> </evaluate> <evaluate name="gGiven"> <test> <mathcmp obj="identityFunction"/>
<feedback>
<p>
<m>g(x)=x</m> is not allowed for nontrivial compositions.
</p>
</feedback>
</test> </evaluate> <evaluate all="yes"> <test correct="yes"> <logic op="and"> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="fGiven"/></formula> <variable name="x"><eval obj="gGiven"/></variable> </de-expression> </mathcmp> <logic op="not"> <mathcmp> <eval obj="fGiven"/> <eval obj="identityFunction"/> </mathcmp> </logic> <logic op="not"> <mathcmp> <eval obj="gGiven"/> <eval obj="identityFunction"/> </mathcmp> </logic> </logic> </test> </evaluate> </evaluation>
</exercise>
<exercise label="fillin-remaining-machinery">
<title>Fill-In, Remaining Machinery</title>
<statement>
<p>
Let <m>n = <eval obj="n"/></m>. Enter either <m>n</m> or its negative: <fillin mode="number" name="plusminus" width="5"/>.
</p>
</statement>
<setup seed="1234"> <de-object name="n" context="number"> <de-random distribution="discrete" min="2" max="5"/> </de-object> <postRenderScript> // a hook run after the exercise renders; deliberately inert </postRenderScript> </setup> <evaluation> <evaluate> <test correct="yes"> <logic op="or"> <mathcmp> <eval obj="n"/> </mathcmp> <mathcmp> <de-evaluate reduce="yes"> <formula> <de-expression mode="formula">{{n}}*x</de-expression> </formula> <variable name="x"> <de-number>-1</de-number> </variable> </de-evaluate> </mathcmp> </logic> </test> <test> <de-expression context="number" mode="formula" reduce="yes">2*{{n}}</de-expression>
<feedback>
<p>
Twice the value is neither the value nor its negative.
</p>
</feedback>
</test> </evaluate> </evaluation>
<solution include-automatic="no">
<p>
Both <m><eval obj="n"/></m> and its negative are accepted; the automatic solution is declined in favor of this sentence.
</p>
</solution>
</exercise>
<exercise label="find-row-echelon">
<statement>
<p>
Consider the matrix defined by
<md>
A = <eval obj="baseMatrix"/>
</md>
Find the reduced row echelon form of <m>A</m>.
</p>
<p>
<m>\mathrm{rref}(A) = </m> <fillin name="rref" mode="math" parser="parseMatrix" ansobj="rrefMatrix"/>
</p>
<p>
A matrix is entered by listing the rows separated by commas between brackets [ and ], and for each row listing entries separated by commas between additional brackets. The matrix <m>\begin{bmatrix} 1 \amp 3 \amp 5 \\ 2 \amp 4 \amp 6 \end{bmatrix}</m> would be entered as <c>[ [1, 3, 5], [2, 4, 6] ]</c>.
</p>
</statement>
<solution>
<p>
Row reduction of <m>A</m> gives
<md>
\mathrm{rref}(A) = <eval obj="rrefMatrix"/>
</md>
</p>
</solution>
<setup> <jsimports> <jslibrary source="code/fitb/btm-matrix-library.js"/> </jsimports> <config-json>{ "rows": 3, "cols": 3, "rank": 2 }</config-json> <setupScript> v.baseMatrix = getRandomMatrix(RNG, _config.rows, _config.cols, _config.rank, true); v.rrefMatrix = getRREF(v.baseMatrix); </setupScript> </setup> <evaluation> <evaluate name="rref"> <test correct="yes"> <jscmp> testMatrixEqual(ans, rrefMatrix) </jscmp> </test> <test> <jscmp> isRowEchelon(ans) </jscmp> <jscmp> testRowEquivalent(ans, baseMatrix) </jscmp>
<feedback>
<p>
Your matrix
<md>
<eval obj="ans"/>
</md>
is a valid row echelon form that is row equivalent to the original matrix, but it is not in reduced row echelon form.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
</exercises>
</section>
Section 17 Dynamic Exercises
View Source for section
This section demonstrates the use of dynamic randomized exercises built upon the framework of Runestone components. These demonstration problems incorporate a library supporting mathematical expressions both for varying the content of the statement of the exercises as well as the checking of submitted answers. Then there is an example where a custom library is used for defining and parsing answer objects without using the built-in math library, and which also illustrates the use of a config structure passed in JSON format.
Exercises Dynamic Fill-In
View Source for exercises
<exercises xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Dynamic Fill-In</title>
<introduction>
<p>
The first problem illustrates revised markup for fill-in problems that don't involve randomization and use simple string and number comparison tests. Later exercises illustrate the use of dynamically generated mathematical expressions.
</p>
</introduction>
<exercise label="fillin-string-integer-new">
<title>Fill-In, String and Number Answers</title>
<statement>
<p>
Complete the following line of a Python program so that it will declare an integer variable <c>age</c> with an initial value of <c>5</c>.
</p>
<p>
<fillin mode="string" answer="int"/> <c>age = </c> <fillin mode="number" answer="5"/><c>;</c>
</p>
</statement>
<evaluation> <evaluate> <test> <strcmp use-answer="yes"/>
<feedback>
<p>
A variable of type <c>int</c> is appropriate for whole number ages.
</p>
</feedback>
</test> <test> <strcmp>.*</strcmp>
<feedback>
<p>
Remember that Java uses just the first three letters of the word <q>integer</q> to define an integral type.
</p>
</feedback>
</test> </evaluate> <evaluate> <test> <numcmp use-answer="yes"/>
<feedback>
<p>
An integer variable may be initialized to a value.
</p>
</feedback>
</test> <test> <strcmp>.*</strcmp>
<feedback>
<p>
Use <c>5</c> as the initial value of the variable.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
<exercise label="fillin-multi-answer-jscmp">
<title>Fill-In, Multiple Strings, Custom Checker</title>
<statement>
<p>
In order to apply the Integral Test to a sequence <m>\{a_n\}</m>, the function <m>a(n) = a_n</m> must be <fillin mode="string" answer="continuous"/>, <fillin mode="string" answer="positive"/><nbsp/>and <fillin mode="string" answer="decreasing"/>.
</p>
</statement>
<evaluation> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) </jscmp> </test> </evaluate> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) && !ans_array.slice(0,1).includes(ans) </jscmp> </test> <test> <jscmp> ans_array.slice(0,1).includes(ans) </jscmp>
<feedback>
<p>
You already gave that answer.
</p>
</feedback>
</test> </evaluate> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) && !ans_array.slice(0,2).includes(ans) </jscmp> </test> <test> <jscmp> ans_array.slice(0,2).includes(ans) </jscmp>
<feedback>
<p>
You already gave that answer.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
<exercise label="dynamic-fitb-simple-formula">
<title>Fill-In Formula (Dynamic)</title>
<statement>
<p>
Find a formula for a cubic function <m>f(x)</m> that has roots at <m>x=<eval obj="x1"/></m>, <m>x=<eval obj="x2"/></m>, and <m>x=<eval obj="x3"/></m> and so that <m>f(0)=<eval obj="y0"/></m>.
</p>
<p>
<m>f(x)=</m> <fillin name="st_cubic" mode="math" ansobj="cubic"/>
</p>
</statement>
<solution>
<p>
Knowing the roots of a polynomial allows us to write down the formula of <m>f(x)</m> in factored form,
<md>
f(x) = A <eval obj="base_cubic"/>
</md>
with an unknown scaling multiple <m>A</m>.
</p>
<p>
When we evaluate <m>f(x)</m> at <m>x=0</m> using this formula, we find
<md>
f(0) = <eval obj="base_yint"/>A
</md>.
Since we also know <m>f(0)=<eval obj="y0"/></m>, we can write down the equation
<md>
A <eval obj="base_cubic"/> = <eval obj="y0"/>
</md>
and find that <m>A=<eval obj="A"/></m>.
</p>
<p>
Consequently, we can write our function in the form
<md>
f(x)=<eval obj="cubic"/>
</md>.
</p>
</solution>
<setup seed="314159"> <de-object name="y0" context="number"> <de-random distribution="discrete" min="-8" max="8" by="1" nonzero="yes"/> </de-object> <de-object name="x1" context="number"> <de-random distribution="discrete" min="-8" max="-4" by="1"/> </de-object> <de-object name="d1" context="number"> <de-random distribution="discrete" min="1" max="4" by="1"/> </de-object> <de-object name="d2" context="number"> <de-random distribution="discrete" min="1" max="4" by="1"/> </de-object> <de-object name="x2" context="number"> <de-number>x1+d1</de-number> </de-object> <de-object name="x3" context="number"> <de-number>x2+d2</de-number> </de-object> <de-object name="base_cubic" context="formula"> <de-expression reduce="yes">(x-x1)*(x-x2)*(x-x3)</de-expression> </de-object> <de-object name="base_yint" context="number"> <de-evaluate> <formula><eval obj="base_cubic"/></formula> <variable name="x"><de-number>0</de-number></variable> </de-evaluate> </de-object> <de-object name="A" context="number"> <de-number reduce="yes">y0/base_yint</de-number> </de-object> <de-object name="cubic" context="formula"> <de-expression reduce="yes">A*(x-x1)*(x-x2)*(x-x3)</de-expression> </de-object> </setup> <evaluation> <evaluate name="st_cubic"> <test correct="yes"> <mathcmp obj="cubic"/> </test> </evaluate> </evaluation>
</exercise>
<exercise label="function-decomposition">
<title>Decompose the Function</title>
<statement>
<p>
Consider the function
<md>
h(x)=<eval obj="composition"/>
</md>.
Find two nontrivial functions <m>f(x)</m> and <m>g(x)</m> so that <m>h(x) = f(g(x))</m>.
</p>
<p>
<m>f(x) = </m> <fillin width="15" mode="math" ansobj="outerFormula" name="fGiven"/> and <m>g(x)=</m> <fillin width="15" mode="math" ansobj="innerFormula" name="gGiven"/>
</p>
</statement>
<solution>
<p>
Noticing that the expression <m><eval obj="innerFormula"/></m> appears inside parentheses with a power, it makes sense to think of that as the inner function, defining <m>g(x) = <eval obj="innerFormula"/></m>. The outer function describes what happens to that. If we imagined replacing the formula <m><eval obj="innerFormula"/></m> with a box and then call that box our variable <m>x</m>, we find the outer function is given by <m>f(x) = <eval obj="outerFormula"/></m>.
</p>
<p>
This is not the only non-trivial composition. Can you find others?
</p>
</solution>
<setup seed="4321"> <de-object name="a" context="number"> <de-random distribution="discrete" min="-4" max="5" by="1" nonzero="yes"/> </de-object> <de-object name="n" context="number"> <de-random distribution="discrete" min="2" max="5"/> </de-object> <de-object name="b" context="number"> <de-random distribution="discrete" min="-10" max="10" by="1" nonzero="yes"/> </de-object> <de-object name="c" context="number"> <de-random distribution="discrete" min="-4" max="5" by="1" nonzero="yes"/> </de-object> <de-object name="d" context="number"> <de-random distribution="discrete" min="-10" max="10" by="1" nonzero="yes"/> </de-object> <de-object name="outerFormula" context="formula"> <de-expression>a*x^n+b</de-expression> </de-object> <de-object name="innerFormula" context="formula"> <de-expression>c*x+d</de-expression> </de-object> <de-object name="identityFunction" context="formula"> <de-expression>x</de-expression> </de-object> <de-object name="composition" context="formula"> <de-expression mode="substitution" reduce="yes"> <formula><eval obj="outerFormula"/></formula> <variable name="x"><eval obj="innerFormula"/></variable> </de-expression> </de-object> </setup> <evaluation answers-coupled="yes"> <evaluate name="fGiven"> <test> <mathcmp obj="identityFunction"/>
<feedback>
<p>
<m>f(x)=x</m> is not allowed for nontrivial compositions.
</p>
</feedback>
</test> <test> <logic op="and"> <logic op="not"> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="fGiven"/></formula> <variable name="x"><eval obj="gGiven"/></variable> </de-expression> </mathcmp> </logic> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="gGiven"/></formula> <variable name="x"><eval obj="fGiven"/></variable> </de-expression> </mathcmp> </logic>
<feedback>
<p>
You have composed in the wrong order.
</p>
</feedback>
</test> </evaluate> <evaluate name="gGiven"> <test> <mathcmp obj="identityFunction"/>
<feedback>
<p>
<m>g(x)=x</m> is not allowed for nontrivial compositions.
</p>
</feedback>
</test> </evaluate> <evaluate all="yes"> <test correct="yes"> <logic op="and"> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="fGiven"/></formula> <variable name="x"><eval obj="gGiven"/></variable> </de-expression> </mathcmp> <logic op="not"> <mathcmp> <eval obj="fGiven"/> <eval obj="identityFunction"/> </mathcmp> </logic> <logic op="not"> <mathcmp> <eval obj="gGiven"/> <eval obj="identityFunction"/> </mathcmp> </logic> </logic> </test> </evaluate> </evaluation>
</exercise>
<exercise label="fillin-remaining-machinery">
<title>Fill-In, Remaining Machinery</title>
<statement>
<p>
Let <m>n = <eval obj="n"/></m>. Enter either <m>n</m> or its negative: <fillin mode="number" name="plusminus" width="5"/>.
</p>
</statement>
<setup seed="1234"> <de-object name="n" context="number"> <de-random distribution="discrete" min="2" max="5"/> </de-object> <postRenderScript> // a hook run after the exercise renders; deliberately inert </postRenderScript> </setup> <evaluation> <evaluate> <test correct="yes"> <logic op="or"> <mathcmp> <eval obj="n"/> </mathcmp> <mathcmp> <de-evaluate reduce="yes"> <formula> <de-expression mode="formula">{{n}}*x</de-expression> </formula> <variable name="x"> <de-number>-1</de-number> </variable> </de-evaluate> </mathcmp> </logic> </test> <test> <de-expression context="number" mode="formula" reduce="yes">2*{{n}}</de-expression>
<feedback>
<p>
Twice the value is neither the value nor its negative.
</p>
</feedback>
</test> </evaluate> </evaluation>
<solution include-automatic="no">
<p>
Both <m><eval obj="n"/></m> and its negative are accepted; the automatic solution is declined in favor of this sentence.
</p>
</solution>
</exercise>
<exercise label="find-row-echelon">
<statement>
<p>
Consider the matrix defined by
<md>
A = <eval obj="baseMatrix"/>
</md>
Find the reduced row echelon form of <m>A</m>.
</p>
<p>
<m>\mathrm{rref}(A) = </m> <fillin name="rref" mode="math" parser="parseMatrix" ansobj="rrefMatrix"/>
</p>
<p>
A matrix is entered by listing the rows separated by commas between brackets [ and ], and for each row listing entries separated by commas between additional brackets. The matrix <m>\begin{bmatrix} 1 \amp 3 \amp 5 \\ 2 \amp 4 \amp 6 \end{bmatrix}</m> would be entered as <c>[ [1, 3, 5], [2, 4, 6] ]</c>.
</p>
</statement>
<solution>
<p>
Row reduction of <m>A</m> gives
<md>
\mathrm{rref}(A) = <eval obj="rrefMatrix"/>
</md>
</p>
</solution>
<setup> <jsimports> <jslibrary source="code/fitb/btm-matrix-library.js"/> </jsimports> <config-json>{ "rows": 3, "cols": 3, "rank": 2 }</config-json> <setupScript> v.baseMatrix = getRandomMatrix(RNG, _config.rows, _config.cols, _config.rank, true); v.rrefMatrix = getRREF(v.baseMatrix); </setupScript> </setup> <evaluation> <evaluate name="rref"> <test correct="yes"> <jscmp> testMatrixEqual(ans, rrefMatrix) </jscmp> </test> <test> <jscmp> isRowEchelon(ans) </jscmp> <jscmp> testRowEquivalent(ans, baseMatrix) </jscmp>
<feedback>
<p>
Your matrix
<md>
<eval obj="ans"/>
</md>
is a valid row echelon form that is row equivalent to the original matrix, but it is not in reduced row echelon form.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
</exercises>
The first problem illustrates revised markup for fill-in problems that donβt involve randomization and use simple string and number comparison tests. Later exercises illustrate the use of dynamically generated mathematical expressions.
1. Fill-In, String and Number Answers.
View Source for exercise
<exercise label="fillin-string-integer-new" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Fill-In, String and Number Answers</title>
<statement>
<p>
Complete the following line of a Python program so that it will declare an integer variable <c>age</c> with an initial value of <c>5</c>.
</p>
<p>
<fillin mode="string" answer="int"/> <c>age = </c> <fillin mode="number" answer="5"/><c>;</c>
</p>
</statement>
<evaluation> <evaluate> <test> <strcmp use-answer="yes"/>
<feedback>
<p>
A variable of type <c>int</c> is appropriate for whole number ages.
</p>
</feedback>
</test> <test> <strcmp>.*</strcmp>
<feedback>
<p>
Remember that Java uses just the first three letters of the word <q>integer</q> to define an integral type.
</p>
</feedback>
</test> </evaluate> <evaluate> <test> <numcmp use-answer="yes"/>
<feedback>
<p>
An integer variable may be initialized to a value.
</p>
</feedback>
</test> <test> <strcmp>.*</strcmp>
<feedback>
<p>
Use <c>5</c> as the initial value of the variable.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
2. Fill-In, Multiple Strings, Custom Checker.
View Source for exercise
<exercise label="fillin-multi-answer-jscmp" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Fill-In, Multiple Strings, Custom Checker</title>
<statement>
<p>
In order to apply the Integral Test to a sequence <m>\{a_n\}</m>, the function <m>a(n) = a_n</m> must be <fillin mode="string" answer="continuous"/>, <fillin mode="string" answer="positive"/><nbsp/>and <fillin mode="string" answer="decreasing"/>.
</p>
</statement>
<evaluation> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) </jscmp> </test> </evaluate> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) && !ans_array.slice(0,1).includes(ans) </jscmp> </test> <test> <jscmp> ans_array.slice(0,1).includes(ans) </jscmp>
<feedback>
<p>
You already gave that answer.
</p>
</feedback>
</test> </evaluate> <evaluate> <test correct="yes"> <jscmp> ["continuous","positive","decreasing"].includes(ans) && !ans_array.slice(0,2).includes(ans) </jscmp> </test> <test> <jscmp> ans_array.slice(0,2).includes(ans) </jscmp>
<feedback>
<p>
You already gave that answer.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>
3. Fill-In Formula (Dynamic).
View Source for exercise
<exercise label="dynamic-fitb-simple-formula" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Fill-In Formula (Dynamic)</title>
<statement>
<p>
Find a formula for a cubic function <m>f(x)</m> that has roots at <m>x=<eval obj="x1"/></m>, <m>x=<eval obj="x2"/></m>, and <m>x=<eval obj="x3"/></m> and so that <m>f(0)=<eval obj="y0"/></m>.
</p>
<p>
<m>f(x)=</m> <fillin name="st_cubic" mode="math" ansobj="cubic"/>
</p>
</statement>
<solution>
<p>
Knowing the roots of a polynomial allows us to write down the formula of <m>f(x)</m> in factored form,
<md>
f(x) = A <eval obj="base_cubic"/>
</md>
with an unknown scaling multiple <m>A</m>.
</p>
<p>
When we evaluate <m>f(x)</m> at <m>x=0</m> using this formula, we find
<md>
f(0) = <eval obj="base_yint"/>A
</md>.
Since we also know <m>f(0)=<eval obj="y0"/></m>, we can write down the equation
<md>
A <eval obj="base_cubic"/> = <eval obj="y0"/>
</md>
and find that <m>A=<eval obj="A"/></m>.
</p>
<p>
Consequently, we can write our function in the form
<md>
f(x)=<eval obj="cubic"/>
</md>.
</p>
</solution>
<setup seed="314159"> <de-object name="y0" context="number"> <de-random distribution="discrete" min="-8" max="8" by="1" nonzero="yes"/> </de-object> <de-object name="x1" context="number"> <de-random distribution="discrete" min="-8" max="-4" by="1"/> </de-object> <de-object name="d1" context="number"> <de-random distribution="discrete" min="1" max="4" by="1"/> </de-object> <de-object name="d2" context="number"> <de-random distribution="discrete" min="1" max="4" by="1"/> </de-object> <de-object name="x2" context="number"> <de-number>x1+d1</de-number> </de-object> <de-object name="x3" context="number"> <de-number>x2+d2</de-number> </de-object> <de-object name="base_cubic" context="formula"> <de-expression reduce="yes">(x-x1)*(x-x2)*(x-x3)</de-expression> </de-object> <de-object name="base_yint" context="number"> <de-evaluate> <formula><eval obj="base_cubic"/></formula> <variable name="x"><de-number>0</de-number></variable> </de-evaluate> </de-object> <de-object name="A" context="number"> <de-number reduce="yes">y0/base_yint</de-number> </de-object> <de-object name="cubic" context="formula"> <de-expression reduce="yes">A*(x-x1)*(x-x2)*(x-x3)</de-expression> </de-object> </setup> <evaluation> <evaluate name="st_cubic"> <test correct="yes"> <mathcmp obj="cubic"/> </test> </evaluate> </evaluation>
</exercise>
4. Decompose the Function.
View Source for exercise
<exercise label="function-decomposition" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Decompose the Function</title>
<statement>
<p>
Consider the function
<md>
h(x)=<eval obj="composition"/>
</md>.
Find two nontrivial functions <m>f(x)</m> and <m>g(x)</m> so that <m>h(x) = f(g(x))</m>.
</p>
<p>
<m>f(x) = </m> <fillin width="15" mode="math" ansobj="outerFormula" name="fGiven"/> and <m>g(x)=</m> <fillin width="15" mode="math" ansobj="innerFormula" name="gGiven"/>
</p>
</statement>
<solution>
<p>
Noticing that the expression <m><eval obj="innerFormula"/></m> appears inside parentheses with a power, it makes sense to think of that as the inner function, defining <m>g(x) = <eval obj="innerFormula"/></m>. The outer function describes what happens to that. If we imagined replacing the formula <m><eval obj="innerFormula"/></m> with a box and then call that box our variable <m>x</m>, we find the outer function is given by <m>f(x) = <eval obj="outerFormula"/></m>.
</p>
<p>
This is not the only non-trivial composition. Can you find others?
</p>
</solution>
<setup seed="4321"> <de-object name="a" context="number"> <de-random distribution="discrete" min="-4" max="5" by="1" nonzero="yes"/> </de-object> <de-object name="n" context="number"> <de-random distribution="discrete" min="2" max="5"/> </de-object> <de-object name="b" context="number"> <de-random distribution="discrete" min="-10" max="10" by="1" nonzero="yes"/> </de-object> <de-object name="c" context="number"> <de-random distribution="discrete" min="-4" max="5" by="1" nonzero="yes"/> </de-object> <de-object name="d" context="number"> <de-random distribution="discrete" min="-10" max="10" by="1" nonzero="yes"/> </de-object> <de-object name="outerFormula" context="formula"> <de-expression>a*x^n+b</de-expression> </de-object> <de-object name="innerFormula" context="formula"> <de-expression>c*x+d</de-expression> </de-object> <de-object name="identityFunction" context="formula"> <de-expression>x</de-expression> </de-object> <de-object name="composition" context="formula"> <de-expression mode="substitution" reduce="yes"> <formula><eval obj="outerFormula"/></formula> <variable name="x"><eval obj="innerFormula"/></variable> </de-expression> </de-object> </setup> <evaluation answers-coupled="yes"> <evaluate name="fGiven"> <test> <mathcmp obj="identityFunction"/>
<feedback>
<p>
<m>f(x)=x</m> is not allowed for nontrivial compositions.
</p>
</feedback>
</test> <test> <logic op="and"> <logic op="not"> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="fGiven"/></formula> <variable name="x"><eval obj="gGiven"/></variable> </de-expression> </mathcmp> </logic> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="gGiven"/></formula> <variable name="x"><eval obj="fGiven"/></variable> </de-expression> </mathcmp> </logic>
<feedback>
<p>
You have composed in the wrong order.
</p>
</feedback>
</test> </evaluate> <evaluate name="gGiven"> <test> <mathcmp obj="identityFunction"/>
<feedback>
<p>
<m>g(x)=x</m> is not allowed for nontrivial compositions.
</p>
</feedback>
</test> </evaluate> <evaluate all="yes"> <test correct="yes"> <logic op="and"> <mathcmp> <eval obj="composition"/> <de-expression mode="substitution"> <formula><eval obj="fGiven"/></formula> <variable name="x"><eval obj="gGiven"/></variable> </de-expression> </mathcmp> <logic op="not"> <mathcmp> <eval obj="fGiven"/> <eval obj="identityFunction"/> </mathcmp> </logic> <logic op="not"> <mathcmp> <eval obj="gGiven"/> <eval obj="identityFunction"/> </mathcmp> </logic> </logic> </test> </evaluate> </evaluation>
</exercise>
5. Fill-In, Remaining Machinery.
View Source for exercise
<exercise label="fillin-remaining-machinery" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<title>Fill-In, Remaining Machinery</title>
<statement>
<p>
Let <m>n = <eval obj="n"/></m>. Enter either <m>n</m> or its negative: <fillin mode="number" name="plusminus" width="5"/>.
</p>
</statement>
<setup seed="1234"> <de-object name="n" context="number"> <de-random distribution="discrete" min="2" max="5"/> </de-object> <postRenderScript> // a hook run after the exercise renders; deliberately inert </postRenderScript> </setup> <evaluation> <evaluate> <test correct="yes"> <logic op="or"> <mathcmp> <eval obj="n"/> </mathcmp> <mathcmp> <de-evaluate reduce="yes"> <formula> <de-expression mode="formula">{{n}}*x</de-expression> </formula> <variable name="x"> <de-number>-1</de-number> </variable> </de-evaluate> </mathcmp> </logic> </test> <test> <de-expression context="number" mode="formula" reduce="yes">2*{{n}}</de-expression>
<feedback>
<p>
Twice the value is neither the value nor its negative.
</p>
</feedback>
</test> </evaluate> </evaluation>
<solution include-automatic="no">
<p>
Both <m><eval obj="n"/></m> and its negative are accepted; the automatic solution is declined in favor of this sentence.
</p>
</solution>
</exercise>
6.
View Source for exercise
<exercise label="find-row-echelon" xmlns:pi="http://pretextbook.org/2020/pretext/internal">
<statement>
<p>
Consider the matrix defined by
<md>
A = <eval obj="baseMatrix"/>
</md>
Find the reduced row echelon form of <m>A</m>.
</p>
<p>
<m>\mathrm{rref}(A) = </m> <fillin name="rref" mode="math" parser="parseMatrix" ansobj="rrefMatrix"/>
</p>
<p>
A matrix is entered by listing the rows separated by commas between brackets [ and ], and for each row listing entries separated by commas between additional brackets. The matrix <m>\begin{bmatrix} 1 \amp 3 \amp 5 \\ 2 \amp 4 \amp 6 \end{bmatrix}</m> would be entered as <c>[ [1, 3, 5], [2, 4, 6] ]</c>.
</p>
</statement>
<solution>
<p>
Row reduction of <m>A</m> gives
<md>
\mathrm{rref}(A) = <eval obj="rrefMatrix"/>
</md>
</p>
</solution>
<setup> <jsimports> <jslibrary source="code/fitb/btm-matrix-library.js"/> </jsimports> <config-json>{ "rows": 3, "cols": 3, "rank": 2 }</config-json> <setupScript> v.baseMatrix = getRandomMatrix(RNG, _config.rows, _config.cols, _config.rank, true); v.rrefMatrix = getRREF(v.baseMatrix); </setupScript> </setup> <evaluation> <evaluate name="rref"> <test correct="yes"> <jscmp> testMatrixEqual(ans, rrefMatrix) </jscmp> </test> <test> <jscmp> isRowEchelon(ans) </jscmp> <jscmp> testRowEquivalent(ans, baseMatrix) </jscmp>
<feedback>
<p>
Your matrix
<md>
<eval obj="ans"/>
</md>
is a valid row echelon form that is row equivalent to the original matrix, but it is not in reduced row echelon form.
</p>
</feedback>
</test> </evaluate> </evaluation>
</exercise>

