This is an example of a local html file.
+ + diff --git a/tutorial/sample-problems/README.md b/tutorial/sample-problems/README.md index 558b45025b..64deacc459 100644 --- a/tutorial/sample-problems/README.md +++ b/tutorial/sample-problems/README.md @@ -81,7 +81,7 @@ directory of pg. There are the following options (and many are required): - `out_dir` or `o`: The directory where the resulting documentation files (HTML) will be located. - `pod_root` or `p`: The URL where the POD is located. This is needed to -correctly link POD documentation from the sample problems. +correctly link POD from the sample problems. - `pg_doc_home` or `h`: The URL of the directory for `out_dir`. This is needed for correct linking. - `verbose` or `v`: verbose mode. diff --git a/tutorial/sample-problems/Sequences/AnswerOrderedList.pg b/tutorial/sample-problems/Sequences/AnswerOrderedList.pg index 8ea33bf3f5..2e4bfe69a2 100644 --- a/tutorial/sample-problems/Sequences/AnswerOrderedList.pg +++ b/tutorial/sample-problems/Sequences/AnswerOrderedList.pg @@ -14,7 +14,7 @@ #:% name = Ordered List #:% type = Sample #:% subject = Sequences and Series -#:% categories = [sequences, answer] +#:% categories = [sequences, answers] #:% section = preamble DOCUMENT(); @@ -22,20 +22,16 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); #:% section = setup -#: We create the array `@seq` with the first two entries. The rest is filled -#: with a `for` loop. Since the entries in the array `@seq` do not have commas between -#: them, we create a Perl string `$answer` that joins the entries of the array `@seq` by -#: a comma followed by a space ', '. Then, we make this string a MathObject by -#: putting `Compute()` around it. -#: -#: Since the answer is a MathObject `List`, which is by default unordered, we must -#: specify that the answer checker use `ordered=>1`. +#: Create an array `@seq` with the first two elements of the sequence that will +#: be the answer. The next 5 elements are added in a `for` loop. Then construct +#: a MathObject `List` by calling `List` on that array. Specify that this +#: `List` is ordered by passing the option `ordered => 1` to the `cmp` method. @seq = (1, 1); -for $i (2 .. 6) { - $seq[$i] = $seq[ $i - 1 ] + $seq[ $i - 2 ]; +for (2 .. 6) { + $seq[$_] = $seq[ $_ - 1 ] + $seq[ $_ - 2 ]; } -$answer_cmp = Compute(join(', ', @seq))->cmp(ordered => 1); +$answer_cmp = List(@seq)->cmp(ordered => 1); #:% section = statement BEGIN_PGML diff --git a/tutorial/sample-problems/Sequences/ExplicitSequence.pg b/tutorial/sample-problems/Sequences/ExplicitSequence.pg index 0c880da25f..2d18161cef 100644 --- a/tutorial/sample-problems/Sequences/ExplicitSequence.pg +++ b/tutorial/sample-problems/Sequences/ExplicitSequence.pg @@ -23,33 +23,21 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); #:% section = setup -#: We set the test points to be positive integers to avoid errors when evaluating -#: the answer. Even if you expect students to enter answers such as `cos(pi * n) / n!`, -#: you should still restrict the domain to positive integers, because some students -#: may simplify this to `(-1)^n / n!` and receive errors because the answer checker -#: is substituting things such as n=0.5 into their formula. +#: The answer is a formula involving factorials that are only defined for +#: positive integers. So set the test points to be positive integers to avoid +#: errors when evaluating the answer. #: -#: For more explanation on the `test_points` see PROBLINK('FormulaTestPoints.pg') +#: For more explanation on `test_points` see PROBLINK('FormulaTestPoints.pg') Context()->variables->are(n => 'Real'); $answer = Compute('(-1)^n / n!'); $answer->{test_points} = [ [1], [2], [3], [4], [5], [6] ]; -@seq = ( - "a_0 = 1", - "a_1 = -1", - "a_2 = \frac{1}{2}", - "a_3 = -\frac{1}{6}", - "a_4 = \frac{1}{24}", - "a_5 = -\frac{1}{120}", - "\ldots" -); - -$sequence = join(', ', @seq); - #:% section = statement BEGIN_PGML -Find a formula for [`n^{th}`] term of the sequence [`[$sequence]`]. +Find a formula for [`n^{th}`] term of the sequence [`a_0 = 1`], [`a_1 = -1`]. +[`a_2 = \frac{1}{2}`], [`a_3 = -\frac{1}{6}`], [`a_4 = \frac{1}{24}`], +[`a_5 = -\frac{1}{120}`], [`\ldots`]. [`a_n =`] [_]{$answer}{20} END_PGML diff --git a/tutorial/sample-problems/Sequences/RecursiveSequence.pg b/tutorial/sample-problems/Sequences/RecursiveSequence.pg index 33c5612c04..c967ab954e 100644 --- a/tutorial/sample-problems/Sequences/RecursiveSequence.pg +++ b/tutorial/sample-problems/Sequences/RecursiveSequence.pg @@ -18,35 +18,33 @@ #:% categories = [sequences] #:% section = preamble -#: We will be defining a new named function and adding it to the context, and the -#: easiest way to do this is using parserFunction.pl. There is a more basic way to -#: add functions to the context, which is explained in example 2 at AddingFunctions +#: A new named function will be defined and added to the context. This can be +#: done using PODLINK('parserFunction.pl'). DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'parserFunction.pl', 'PGcourse.pl'); #:% section = setup -#: We define a new named function `f` as something the student is unlikely to guess. -#: The named function `f` is, in some sense, just a placeholder since the student will -#: enter expressions involving `f(n-1)`, WeBWorK will interpret it internally as -#: `sin(pi^(n-1))+e*n^2`, and the only thing the student sees is `f(n-1)`. -#: If the recursion -#: has an closed-form solution (e.g., the Fibonacci numbers are given by -#: `f(n) = (a^n - (1-a)^n)/sqrt(5)` where `a = (1+sqrt(5))/2)` and you want to allows -#: students to enter the closed-form solution, it would be good to define `f` using -#: that explicit solution in case the student tries to answer the question by writing -#: out the explicit solution `(a^n - (1-a)^n)/sqrt(5)` instead of using the shorthand `f(n)`. +#: Define a new named function `f` as something the student is unlikely to +#: guess. The named function `f` is just a placeholder since the student will +#: enter expressions involving `f(n - 1)`. It will be interpreted internally as +#: defined here, and the only thing the student sees is `f(n - 1)`. +#: +#: If the recursion has a closed-form solution (e.g., the Fibonacci numbers are +#: given by `f(n) = (a^n - (1 - a)^n) / sqrt(5)` where `a = (1 + sqrt(5)) / 2`) +#: and you want to allow students to enter the closed-form solution, it would be +#: good to define `f` using that explicit solution in case the student tries to +#: answer the question by entering the explicit solution. Context()->variables->are(n => 'Real'); parserFunction(f => 'sin(pi^n) + e * n^2'); $fn = Formula('3 f(n - 1) + 2'); #:% section = statement -#: We should tell students to use function notation rather than subscript notation -#: so that they aren't confused about syntax. BEGIN_PGML -The current value [`f(n)`] is three times the previous value, plus two. Find a -recursive definition for [`f(n)`]. Enter [`f_{n-1}`] as [`f(n-1)`]. +If [`f(n)`] defines a sequence for all integegers [`n \geq 0`] that satisfies +the property that [`f(n)`] is two more than three times the previous value. +Find a recursive definition for [`f(n)`]. [`f(n) =`] [_]{$fn}{15} END_PGML diff --git a/tutorial/sample-problems/Sequences/SeriesTest.pg b/tutorial/sample-problems/Sequences/SeriesTest.pg index b2bfde3de2..11cbdcdd0a 100644 --- a/tutorial/sample-problems/Sequences/SeriesTest.pg +++ b/tutorial/sample-problems/Sequences/SeriesTest.pg @@ -17,24 +17,39 @@ #:% categories = [sequences, series] #:% section = preamble -#: We load `niceTables.pl` to create a table in which answer blanks are stacked on top -#: of each other to form a fraction. We use `PGgraders.pl` to give partial credit -#: incrementally. We use `parserMultiAnswer.pl` for the fraction answer so that we can -#: accept two correct answers, depending on how much a student has simplified their answer. +#: The PODLINK('parserMultiAnswer.pl') macro is used for the fraction answer so +#: that the numerator and denominator can be checked together. +#: +#: The PODLINK('parserRadioMultiAnswer.pl') macro is used for a better way for +#: students to enter an answer that might not exist than telling students to +#: enter DNE. +#: +#: The PODLINK('niceTables.pl') macro which is loaded by the `PGML.pl` macro is +#: used to create a table in which answer blanks are stacked on top of each +#: other to form a fraction. +#: +#: The PODLINK('PGgraders.pl') macro is used to give incremental partial credit +#: (although that is a poor choice for this problem). DOCUMENT(); loadMacros( - 'PGstandard.pl', 'PGML.pl', - 'niceTables.pl', 'parserPopUp.pl', - 'PGgraders.pl', 'parserMultiAnswer.pl', + 'PGstandard.pl', 'PGML.pl', + 'parserPopUp.pl', 'PGgraders.pl', + 'parserMultiAnswer.pl', 'parserRadioMultiAnswer.pl', 'PGcourse.pl' ); #:% section = setup -#: We use the `MultiAnswer` object `$multians` to allow students to enter one of two -#: correct answers. We could have also accomplished this using two custom answer checkers. +#: Create `$multians` as a `MultiAnswer` with the two answers `$num1` and +#: `$den1`. An alternate form of the correct answer is `$num2 / $den2`. This +#: alternate form is also checked for in the `MultiAnswer` checker. +#: +#: The value of the limit in the limit comparison test is created as a +#: `RadioMultiAnswer`. This allows a clear way for students to enter a +#: non-existent limit, and is better than telling students to enter DNE and +#: results in the invalid statement `lim ... = DNE`. #: -#: We display the answerblanks nicely as a fraction in HTML and TeX modes by how we constructed `$showfraction`. +#: Also create a drop down answer for asking about convergence of the series. Context()->variables->are(n => 'Real'); $a = random(2, 9); @@ -43,18 +58,12 @@ $c = random(5, 20); $d = random(3, 9); $e = random(2, 9); -$dm1 = $d - 1; -$dm2 = $d - 2; - -# TeX -$series = "\sum_{n=$c}^{\infty} \frac{$a n + $b}{$c n^{$d} + $e}"; -$fraction = "\lim_{n\to\infty} \frac{a_n}{b_n} = \lim_{n\to\infty}"; - -$num1 = Formula("$a n^$d + $b n^$dm1"); +$num1 = Formula("$a n^$d + $b n^" . ($d - 1)); $den1 = Formula("$c n^$d + $e"); -$num2 = Formula("$a + $b/n"); -$den2 = Formula("$c + $e/(n^$d)"); +# Alternate form of the correct answer +$num2 = Formula("$a + $b / n"); +$den2 = Formula("$c + $e / (n^$d)"); $multians = MultiAnswer($num1, $den1)->with( singleResult => 0, @@ -82,46 +91,70 @@ $multians = MultiAnswer($num1, $den1)->with( } ); -$limit = Formula("$a/$c"); -$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' } +$limitRMA = RadioMultiAnswer( + [ + [ + '\(\displaystyle\lim_{n \to \infty}\frac{a_n}{b_n} =\) %s', + Formula("$a / $c") + ], + ['The limit does not exist, and is not infinite.'] + ], + 0 ); +$popup = DropDown([ 'Converges', 'Diverges', 'Inconclusive' ], 'Converges'); + #:% section = statement -#: Most of this is standard latex markup in a PGML block. Note that to -#: display the fraction above, we use `[$frac]*` followed by the -#: PGML codeblock `[@ ANS($multians->cmp); '' @]` which does the -#: answer checking using the multianswer described above. There is a -#: `''` at the tend of the codeblock to return an empty string instead of -#: a HASHREF which we get from the ANS method. +#: Display the answer rules nicely as a fraction in HTML and TeX modes by using +#: the `PGML` syntax for a `LayoutTable` from PODLINK('niceTables.pl'). BEGIN_PGML Use the limit comparison test to determine whether -[``\sum_{n=[$c]}^{\infty} a_n = \sum_{n=[$c]}^{\infty} \frac{[$a] n + [$b]}{[$c] n^{[$d]} + [$e]}``] +[``\sum_{n = [$c]}^{\infty} a_n + = \sum_{n = [$c]}^{\infty} \frac{[$a] n + [$b]}{[$c] n^{[$d]} + [$e]}``] converges or diverges. -a. Choose a series [``\sum_{n=[$c]}^\infty b_n``] with terms of the form -[``b_n = \frac{1}{n^p}``] and apply the limit comparison test. Write your -answer as a fully reduced fraction. For [``n \geq [$c]``], -[```\frac{\lim_{n \to \infty} a_n}{\lim_{n \to \infty} b_n}```][$frac]* [@ ANS($multians->cmp); '' @] +Choose a series [``\sum_{n = [$c]}^\infty b_n``] with terms of the form +[``b_n = \frac{1}{n^p}``] to use in the limit comparison test. + +a. Simplify the fraction [``\frac{a_n}{b_n}``] in the application of the limit +comparison test shown. Give your answer as a fully reduced fraction. +[# + [. + For [`n \geq [$c]`], + [``\lim_{n \to \infty}\frac{a_n}{b_n} = \lim_{n \to \infty}``] + .] + [. + [# + [.[_]{$multians}{10}.]*{ bottom => 1 } + [.[_]{$multians}{10}.] + #]*{ padding => [ 0.5, 0 ] } + .] +#]*{ + center => 0, + valign => 'middle', + allcellcss => { padding => '4pt' } +} -b. Evaluate the limit in the previous part. Enter [` \infty `] as _infinity_ -and [` -\infty `] as _-infinity_. If the limit does not exist, enter _DNE_. +b. Evaluate the limit in the previous part. Enter [|infinity|]* for [` \infty `] +and [|-infinity|]* for [`-\infty`]. -[``\lim_{n\to\infty} \frac{a_{n}}{b_{n}} =``] [_]{$limit}{15} + [_]{$limitRMA}{10} c. By the limit comparison test, does the series converge, diverge, or is the -test inconclusive? [_]{$popup} +test inconclusive? [_]{$popup} END_PGML #:% section = answer -#: We use the problem grader fluid to give partial credit incrementally: 0% for 0-1 -#: correct answers, 40% for 2-3 correct answers, and full credit for 4 correct answers. +#: The problem grader fluid is used to give partial credit incrementally. +#: +#: * 0% is awarded for 0-1 correct answers, +#: * 40% is awarded for 2-3 correct answers, and +#: * full credit is awarded for 4 correct answers. +#: +#: This is only here to demonstrate the usage of the fluid problem grader, and +#: because that is how this problem has been. It would be better to use the +#: weighted grader for a problem like this. The parts of this problem are not +#: equal, so the fluid problem grader is not a good choice. install_problem_grader(~~&custom_problem_grader_fluid); $ENV{grader_numright} = [ 2, 4 ]; diff --git a/tutorial/sample-problems/snippets/CommentsForInstructors.pg b/tutorial/sample-problems/Snippets/CommentsForInstructors.pg similarity index 67% rename from tutorial/sample-problems/snippets/CommentsForInstructors.pg rename to tutorial/sample-problems/Snippets/CommentsForInstructors.pg index 149d99a42b..64c4442053 100644 --- a/tutorial/sample-problems/snippets/CommentsForInstructors.pg +++ b/tutorial/sample-problems/Snippets/CommentsForInstructors.pg @@ -15,14 +15,17 @@ #:% name = Comment for Instructors #:% type = snippet +#:% categories = [comments] +#:% section = preamble DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); -#:% section = comment -#: Include the `COMMENT();` just before the `ENDDOCUMENT();` Comments are only visible -#: when the PG file is viewed in the Library Browser, so students will not see them. +#:% section = statement +#: Call `COMMENT` to add a comment that is visible when the PG file is viewed in +#: the Library Browser or the PG problem editor. Students do not see these +#: comments. COMMENT('This problem is not randomized.'); ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Statistics/LinearRegression.pg b/tutorial/sample-problems/Statistics/LinearRegression.pg new file mode 100644 index 0000000000..2bb03618db --- /dev/null +++ b/tutorial/sample-problems/Statistics/LinearRegression.pg @@ -0,0 +1,66 @@ +## DESCRIPTION +## Find the mean and standard deviation of a list of numbers. +## ENDDESCRIPTION +## DBsubject(WeBWorK) +## DBchapter(WeBWorK tutorial) +## DBsection(WeBWorK tutorial) +## Institution(Fitchburg State University) +## Author(Peter Staab) +## KEYWORDS('statistic', 'linear regression', 'correlation coefficient') + +#:% name = Linear Regression +#:% subject = [statistics] +#:% type = sample + +#:% section = preamble +#: The PODLINK('PGstatisticsmacros.pl') macro provides the `sample_correlation` +#: and `linear_regression` methods. +DOCUMENT(); + +loadMacros("PGstandard.pl", "PGML.pl", 'PGstatisticsmacros.pl', "PGcourse.pl"); + +#:% section = setup +#: Generate random numbers, and then use the `sample_correlation` and +#: `linear_regression` methods from PODLINK('PGstatisticsmacros.pl'). + +# Generate a random slope and intercept. +$m = random(0.1, 0.75, 0.05); +$b = random(0.5, 5, 0.25); + +$x = []; +$y = []; + +# Create some random data +for (0 .. 9) { + $x->[$_] = random(2.5, 7.5, 0.5); + $y->[$_] = $m * $x->[$_] + $b; +} + +@rows = map { [ $x->[$_], $y->[$_] ] } 0 .. $#$x; + +$corr = sample_correlation($x, $y); +($m, $b) = linear_regression($x, $y); + +#:% section = statement +BEGIN_PGML +Consider the following data: + +[# + [.[`x`].] [.[`y`].]*{ headerrow => 1 } + [. .]{ rows => \@rows } +#]{ 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 + +#:% section = solution +BEGIN_PGML_SOLUTION +Provide a solution here. +END_PGML_SOLUTION + +ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Statistics/MeanStdDev.pg b/tutorial/sample-problems/Statistics/MeanStdDev.pg new file mode 100644 index 0000000000..a86773c91a --- /dev/null +++ b/tutorial/sample-problems/Statistics/MeanStdDev.pg @@ -0,0 +1,73 @@ +## DESCRIPTION +## Find the mean and standard deviation of a list of numbers. +## ENDDESCRIPTION +## DBsubject(WeBWorK) +## DBchapter(WeBWorK tutorial) +## DBsection(WeBWorK tutorial) +## Institution(Fitchburg State University) +## Author(Peter Staab) +## KEYWORDS('statistic', 'mean', 'standard deviation') + +#:% name = Mean and Standard Deviation +#:% subject = [statistics] +#:% type = sample + +#:% section = preamble +#: The PODLINK('PGstatisticsmacros.pl') macro provides the `stats_mean`, +#: `stats_sd`, and `stats_SX_SXX` methods. +DOCUMENT(); + +loadMacros("PGstandard.pl", "PGML.pl", 'PGstatisticsmacros.pl', "PGcourse.pl"); + +#:% section = setup +#: Generate random numbers and then calculate the mean and standard deviation +#: using the `stats_mean` and `stats_sd` methods from +#: PODLINK('PGstatisticsmacros.pl'). +@x = map { random(1, 10) } 0 .. 7; + +$mean = stats_mean(@x); +$sd = stats_sd(@x); + +#:% section = statement +BEGIN_PGML +Find the mean and standard deviation of the following list of numbers: +[@ join(', ', @x) @] + +a) Mean: [_]{$mean}{8} + +b) Standard Deviation: [_]{$sd}{8} +END_PGML + +#:% section = solution +#: The `stats_SX_SXX` method from `PGstatisticsmacros.pl` returns the sum and +#: sum of squares which are used in the solution. +#: +#: Note that when a long list of equalities are strung together in an equation +#: it is a good idea to use the `aligned` environment to break the equalities +#: onto separate lines. If left on a single line, the equation may extend +#: outside of the solution container and look quite bad. Particularly on narrow +#: screens. +($sum_x, $sum_sq) = stats_SX_SXX(@x); +$var = $sum_sq - ($sum_x**2) / 8; + +BEGIN_PGML_SOLUTION +The mean is + +[``\bar{x} = \frac{1}{n} \sum_{i = 1}^n x_i = \frac{[$sum_x]}{8} = [$mean]``] + +For the standard deviation, first, find the variance. + +[`` + \begin{aligned} + s^2 &= \frac{1}{n - 1} \left( + \sum_{i = 1}^n x_i^2 - \frac{1}{n}\left(\sum_{i = 1}^n x_i\right)^2 + \right) \\ + &= \frac{1}{7} \left( [$sum_sq] - \frac{1}{8} ([$sum_x])^2\right) \\ + &= \frac{[$var]}{7} + \end{aligned} +``] + +Taking the square root gives [`s \approx [$sd]`] +END_PGML_SOLUTION + +ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Statistics/linearRegression.pg b/tutorial/sample-problems/Statistics/linearRegression.pg deleted file mode 100644 index d316f12e9b..0000000000 --- a/tutorial/sample-problems/Statistics/linearRegression.pg +++ /dev/null @@ -1,68 +0,0 @@ -## DESCRIPTION -## Find the mean and standard deviation of a list of numbers. -## ENDDESCRIPTION -## DBsubject(WeBWorK) -## DBchapter(WeBWorK tutorial) -## DBsection(WeBWorK tutorial) -## Institution(Fitchburg State University) -## Author(Peter Staab) -## KEYWORDS('statistic', 'linear regression', 'correlation coefficient') - -#:% name = Linear Regression -#:% subject = [statistics] -#:% type = sample - -#:% section = preamble -#: Statistics functions mean and standard deviation are used so we load -#: `PGstatisticsmacros.pl`. We use the `DataTable` method from the -#: `niceTables.pl` macro. -DOCUMENT(); - -loadMacros( - "PGstandard.pl", "PGML.pl", - 'PGstatisticsmacros.pl', 'niceTables.pl', - "PGcourse.pl" -); - -#:% section = setup -#: First, generate random numbers and then use the methods -#: `sample_correlation` and `linear_regression` -#: from the macro PODLINK('PGstatisticsmacros.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); - -#:% section = statement -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 - -#:% section = solution -BEGIN_PGML_SOLUTION -Provide a solution here. -END_PGML_SOLUTION - -ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Statistics/meanStdDev.pg b/tutorial/sample-problems/Statistics/meanStdDev.pg deleted file mode 100644 index 037e10fe15..0000000000 --- a/tutorial/sample-problems/Statistics/meanStdDev.pg +++ /dev/null @@ -1,64 +0,0 @@ -## DESCRIPTION -## Find the mean and standard deviation of a list of numbers. -## ENDDESCRIPTION -## DBsubject(WeBWorK) -## DBchapter(WeBWorK tutorial) -## DBsection(WeBWorK tutorial) -## Institution(Fitchburg State University) -## Author(Peter Staab) -## KEYWORDS('statistic', 'mean', 'standard deviation') - -#:% name = Mean and Standard Deviation -#:% subject = [statistics] -#:% type = sample - -#:% section = preamble -#: Statistics functions mean and standard deviation are used so we load -#: `PGstatisticsmacros.pl`. -DOCUMENT(); - -loadMacros("PGstandard.pl", "PGML.pl", 'PGstatisticsmacros.pl', "PGcourse.pl"); - -#:% section = setup -#: First, generate random numbers and then calculate the mean and standard -#: deviation using the methods `stats_mean` and `stats_sd` from the macro -#: PODLINK('PGstatisticsmacros.pl'). -for $i (0 .. 7) { - $x[$i] = random(1, 10); -} - -$mean = stats_mean(@x); -$sd = stats_sd(@x); - -#:% section = statement -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 - -#:% section = 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. -($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(); diff --git a/tutorial/sample-problems/Trig/DisableFunctionsTrig.pg b/tutorial/sample-problems/Trig/DisableFunctionsTrig.pg index 567f0a7154..348d2e4273 100644 --- a/tutorial/sample-problems/Trig/DisableFunctionsTrig.pg +++ b/tutorial/sample-problems/Trig/DisableFunctionsTrig.pg @@ -14,45 +14,33 @@ #:% name = Disabling Functions #:% type = [Sample, technique] #:% subject = [trigonometry, precalculus] -#:% categories = [trigonometry] +#:% categories = [functions, exact] #:% section = preamble -#: The `contextFraction.pl` is loaded since we used the `Fraction-NoDecimals` context. +#: The PODLINK('contextFraction.pl') is loaded for the `Fraction-NoDecimals` +#: context. DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'contextFraction.pl', 'PGcourse.pl'); #:% section = 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). +#: Select the `Fraction-NoDecimals` context which requires fractions as answers +#: and does not allow decimals. #: -#: 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(\pi) and sin(\pi/3) as desired. +#: After constructing the formulas involving trig functions, disable all +#: functions and re-enable the `sqrt` function. This means fractions and square +#: roots can be entered, but an error message will be shown if any other +#: function is entered. 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)'); +$f2 = Formula('sin(pi / 3)'); Context()->functions->disable('All'); Context()->functions->enable('sqrt'); $answer1 = Compute('-1'); -$answer2 = Compute('sqrt(3)/2'); +$answer2 = Compute('sqrt(3) / 2'); #:% section = statement BEGIN_PGML @@ -63,9 +51,15 @@ Enter your answers as simplified fractions. + [`[$f2] =`] [_]{$answer2}{15} END_PGML +#:% section = hint +#: A hint is provided. +BEGIN_PGML_HINT +The cosine of an angle is zero when the angle is an integer multiple of [`\pi`]. +END_PGML_HINT + #:% section = solution BEGIN_PGML_SOLUTION -The cosine of an angle is zero when the angle is an integer multiple of [`\pi`]. +Provide a solution here. END_PGML_SOLUTION ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Trig/DraggableIdentity.pg b/tutorial/sample-problems/Trig/DraggableIdentity.pg index 4b5807efc4..742fde95ec 100644 --- a/tutorial/sample-problems/Trig/DraggableIdentity.pg +++ b/tutorial/sample-problems/Trig/DraggableIdentity.pg @@ -14,42 +14,41 @@ #:% name = Draggable Trigonometry Identity #:% type = Sample #:% subject = [proof, trigonometry] -#:% categories = [trigonometry, draggable] +#:% categories = [draggable] #:% section = preamble -#: This problem uses the `draggableProof.pl` macro to display "buckets" that the -#: student can drag statements to and from. +#: This problem uses the PODLINK('draggableProof.pl`) macro to display "buckets" +#: that the student can drag statements to and from. DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'draggableProof.pl', 'PGcourse.pl'); #:% section = setup -#: The `DraggableProof` function takes an arrayref of correct statements, -#: followed (optionally) by extra statements. See -#: PODLINK('the Draggable Proof POD', 'draggableProof.pl') for more options. +#: The `DraggableProof` function takes a reference to an array of correct +#: statements, followed (optionally) by a reference to an array of extra +#: statements. See PODLINK('draggableProof.pl') for more details. #: #: This shows how other identities could be structured. You probably want #: some incorrect statements to make the problem a little bit harder. $proof = DraggableProof( # These are the correct statements of the proof in the correct order. [ - '\(\sin(\pi-\theta) = \sin(\pi)\cos(\theta)-\cos(\pi)\sin(\theta) \)', - '\(\sin(\pi-\theta) = 0 \cdot \cos(\theta) - (-1)\cdot \sin(\theta)\)', - '\(\sin(\pi-\theta) = 0+1\sin(\theta)\)', - '\(\sin(\pi-\theta) = \sin(\theta)\)', + '\(\sin(\pi - \theta) = \sin(\pi)\cos(\theta) - \cos(\pi)\sin(\theta)\)', + '\(\sin(\pi - \theta) = (0)\cos(\theta) - (-1)\sin(\theta)\)', + '\(\sin(\pi - \theta) = 0 + (1)\sin(\theta)\)', + '\(\sin(\pi - \theta) = \sin(\theta)\)', ], # These are extra statements that are not needed. [ - '\(\sin(\pi-\theta) = \cos(\pi)\cos(\theta)-\sin(\pi)\sin(\theta) \)', - '\(\sin(\pi-\theta) = 0\cdot\cos(\theta)-(-1)\sin(\theta) \)', - '\(\sin(\pi-\theta) = \sin(\pi)\cos(\theta)+\cos(\pi)\sin(\theta) \)', - '\(\sin(\pi-\theta) = 0\cdot\cos(\theta)+1 \cdot\sin(\theta) \)', - '\(\sin(\pi-\theta) = 1\cdot\cos(\theta)+0 \cdot\sin(\theta) \)', + '\(\sin(\pi - \theta) = \cos(\pi)\cos(\theta) - \sin(\pi)\sin(\theta)\)', + '\(\sin(\pi - \theta) = \sin(\pi)\cos(\theta) + \cos(\pi)\sin(\theta)\)', + '\(\sin(\pi - \theta) = (1)\cos(\theta) + (0)\sin(\theta)\)', ] ); #:% section = statement -#: The line `[_]{$proof}` prints the statement and options in the proof and sets up the answer rule. +#: The line `[_]{$proof}` inserts the drag and drop "buckets" containing the +#: proof statements that are to be selected and ordered. BEGIN_PGML Prove the trigonmetric identity [`\sin(\pi-\theta) = \sin(\theta)`]. diff --git a/tutorial/sample-problems/Trig/PeriodicAnswers.pg b/tutorial/sample-problems/Trig/PeriodicAnswers.pg index 99963be619..1bf2b540a3 100644 --- a/tutorial/sample-problems/Trig/PeriodicAnswers.pg +++ b/tutorial/sample-problems/Trig/PeriodicAnswers.pg @@ -14,7 +14,7 @@ #:% name = Periodic Answers #:% type = Sample #:% subject = [trigonometry, precalculus] -#:% categories = [trigonometry] +#:% categories = [periodic] #:% section = preamble DOCUMENT(); @@ -22,9 +22,9 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); #:% section = setup -#: This allows any answer of the form `pi/2+n pi` for integer `n` to be -#: accepted. -$answer = Real('pi/2')->with(period => pi); +#: This allows any answer of the form `pi / 2 + n pi` where `n` is a particular +#: integer to be accepted. +$answer = Real('pi / 2')->with(period => pi); #:% section = statement BEGIN_PGML @@ -33,10 +33,16 @@ Enter a solution to [`\cos(\theta) = 0`]. [`\theta =`] [_]{$answer}{15} END_PGML +#:% section = hint +#: A hint is provided. +BEGIN_PGML_HINT +The cosine of an angle is zero when the angle is [`\frac{2n + 1}{2}\pi`] for +any integer [`n`]. +END_PGML_HINT + #:% section = solution BEGIN_PGML_SOLUTION -The cosine of an angle is zero when the angle is [`(n + 1 / 2)\pi`] for any -integer [`n`]. +Solution explanation goes here. END_PGML_SOLUTION ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Trig/ProvingTrigIdentities.pg b/tutorial/sample-problems/Trig/ProvingTrigIdentities.pg index 8a4abb58bd..67026d74c1 100644 --- a/tutorial/sample-problems/Trig/ProvingTrigIdentities.pg +++ b/tutorial/sample-problems/Trig/ProvingTrigIdentities.pg @@ -15,45 +15,43 @@ #:% name = Proving Identities #:% type = Sample #:% subject = [trigonometry, precalculus] -#:% categories = [trigonometry, proof] +#:% categories = [proof] #:% section = preamble -#: This is a scaffolded problem, so load `scaffold.pl`. +#: This is a scaffolded problem, so load PODLINK('scaffold.pl'). DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'scaffold.pl', 'PGcourse.pl'); #:% section = setup -#: We cleverly redefine the sine function so that when the student enters `sin(t)`, -#: it is interpreted and evaluated internally as `exp(pi*t)` but displayed to -#: the student as `sin(t)`. This prevents the entering of the orginally -#: expression as the answer. An alternative method to doing this is in -#: PROBLINK('TrigIdentities.pg'). +#: The sine function is cleverly redefined so that when the student enters +#: `sin(t)`, it is interpreted and evaluated internally as `exp(pi * t)` but +#: displayed to the student as `sin(t)`. This prevents the original expression +#: from being entered as the answer in the last step of the proof. Context()->variables->are(t => 'Real'); # Redefine sin(x) to be e^(pi x). Context()->functions->remove('sin'); -package NewFunc; +package AltSin; # The next line makes the function a function from reals to reals. our @ISA = qw(Parser::Function::numeric); sub sin { shift; my $x = shift; - return CORE::exp($x * 3.1415926535); + return CORE::exp($x * $pi); } package main; -# Make it work on formulas as well as numbers -# sub cos { Parser::Function->call('cos', @_) } # if uncommented, this line will generate error messages + # Add the new functions to the Context. -Context()->functions->add(sin => { class => 'NewFunc', TeX => '\sin' },); +Context()->functions->add(sin => { class => 'AltSin', TeX => '\sin' },); #:% section = statement BEGIN_PGML -This problem has three parts. A part may be open if it is correct or if it is -the first incorrect part. Clicking on the heading for a part toggles whether it +This problem has three parts. A part may be open if it is correct or if it is +the first incorrect part. Clicking on the heading for a part toggles whether it is displayed. In this multi-part problem, we will use algebra to verify the identity @@ -66,16 +64,16 @@ Scaffold::Begin(is_open => 'correct_or_first_incorrect'); Section::Begin('Part 1'); BEGIN_PGML - -First, using algebra we may rewrite the equation above as -[`\displaystyle \sin(t) = \left( \frac{1 + \cos(t)}{\sin(t)} \right) \cdot \Big(`] +First, the equation above can be rewritten as +[`\displaystyle \sin(t) + = \left( \frac{1 + \cos(t)}{\sin(t)} \right) \cdot \Big(`] [_]{'1 - cos(t)'}{15} [` \Big) `]. END_PGML Section::End(); Section::Begin('Part 2'); BEGIN_PGML -Using algebra we may rewrite the equation as +Next, the equation can be rewritten as [`\sin(t) \cdot \big(`] [_]{'sin(t)'}{15} [`\big) = \big(1 + \cos(t)\big) \cdot \big(1 - \cos(t)\big)`]. END_PGML @@ -83,20 +81,14 @@ Section::End(); Section::Begin('Part 3'); BEGIN_PGML -Finally, using algebra we may rewrite the equation as +Finally, the equation can be rewritten as [`\sin^2(t) =`] [_]{'1-(cos(t))^2'}{15}, which is true since -[`\cos^2(t) + \sin^2(t) = 1`]. Thus, the original identity can be derived by -reversing these steps. +[`\cos^2(t) + \sin^2(t) = 1`]. + +Thus, the original identity can be derived by reversing these steps. END_PGML Section::End(); Scaffold::End(); -COMMENT( - 'This is a multi-part problem -in which the next part is revealed only after the previous -part is correct. Prevents students from entering trivial -identities (entering what they were given). Uses PGML.' -); - ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Trig/SpecialTrigValues.pg b/tutorial/sample-problems/Trig/SpecialTrigValues.pg index f3240a1fff..282a85db01 100644 --- a/tutorial/sample-problems/Trig/SpecialTrigValues.pg +++ b/tutorial/sample-problems/Trig/SpecialTrigValues.pg @@ -16,23 +16,23 @@ #:% subject = trigonometry #:% section = preamble -#: We load the `specialTrigValues.pl` macro to use exact values on the -#: unit circle. +#: Load the PODLINK('specialTrigValues.pl') macro for the `specialRadical` and +#: `specialAngle` methods. DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'specialTrigValues.pl', 'PGcourse.pl'); #:% section = 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. +#: 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]`). +#: The `specialRadical` function returns a `Formula` in the form `a sqrt(b) / c` +#: were `b` and `c` come from a list of integers (defaults to `[1, 2, 3]`). #: -#: It is noted that `specialRadical` has a complex form as well. +#: Note that the `specialRadical` function 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]`). +#: 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]`). ($d, $n) = random_coprime([ 2, 3, 4, 6 ], [ 1 .. 12 ]); $r = random(2, 3); @@ -50,13 +50,13 @@ $z = specialRadical("$r exp($n pi i/$d)"); BEGIN_PGML Evaluate the following: -a) [`[$r] \cos([$n] \pi/[$d])=`] [_]{$c} +a) [`[$r] \cos([$n] \pi/[$d]) =`] [_]{$c} -b) [`[$r] \sin([$n] \pi/[$d])=`] [_]{$s} +b) [`[$r] \sin([$n] \pi/[$d]) =`] [_]{$s} -c) [`[$r] \exp([$n] \pi/[$d])=`] [_]{$z} +c) [`[$r] \exp([$n] \pi/[$d]) =`] [_]{$z} -d) [`\arcsin([$x])=`] [_]{$a} +d) [`\arcsin([$x]) =`] [_]{$a} END_PGML #:% section = solution diff --git a/tutorial/sample-problems/Trig/TrigDegrees.pg b/tutorial/sample-problems/Trig/TrigDegrees.pg index 0c5c151356..b766672052 100644 --- a/tutorial/sample-problems/Trig/TrigDegrees.pg +++ b/tutorial/sample-problems/Trig/TrigDegrees.pg @@ -14,40 +14,44 @@ #:% name = Degrees in Trigonometric Functions #:% type = [technique, sample] #:% subject = [trigonometry, precalculus] -#:% categories = [trigonometry, degrees] +#:% categories = [degrees] #:% section = preamble -#: We load the `contextTrigDegrees.pl` macro to help with trig functions with degrees. +#: Load the PODLINK('contextTrigDegrees.pl') macro for the `TrigDegrees` +#: context. Also load the PODLINK('parserNumberWithUnits.pl') so that answers +#: can be asked for with the degree symbol. DOCUMENT(); -loadMacros('PGstandard.pl', 'PGML.pl', 'contextTrigDegrees.pl', 'PGcourse.pl'); +loadMacros( + 'PGstandard.pl', 'PGML.pl', + 'contextTrigDegrees.pl', 'parserNumberWithUnits.pl', + 'PGcourse.pl' +); #:% section = setup -#: To override the WeBWorK default of evaluating trig functions in radians, use the `TrigDegrees` context, -#: which redefines the standard trig functions to be in degrees, both in any formulas that appear -#: later in the PG code and in any formulas that students enter in answer blanks. +#: Select the `TrigDegrees` context to which evaluates trig functions in +#: degrees. This applies to any formulas or student answers in this context. #: -#: These redefined functions allow students to enter inverse functions using syntax such as -#: `atan(x)`, or `arctan(x)`, or `tan^(-1)(x)`. +#: The second answers is constructed with the `NumberWithUnits` method and the +#: degree symbol is specified as the unit. Degree measures should always be +#: given with the degree symbol. Context('TrigDegrees'); -$ans1 = Compute("sin(30)"); -$ans2 = Compute("arcsin(0.5)"); +$ans1 = Compute('sin(30)'); +$ans2 = NumberWithUnits('arcsin(1 / 2)', 'degrees'); #:% section = statement -#: Since this is in degrees, you should tell the students this. +#: Inform the students to give angle measurements in degrees. BEGIN_PGML -1. [`\sin(30^{\circ})=`] [___]{$ans1} -2. [`\arcsin(1/2)=`] [___]{$ans2} +Evaluate the following. Give angles in degrees. -Interpret arguments of the sine and arcsine in terms of degrees. +1. [`\sin(30^{\circ}) =`] [_]{$ans1}{5} +2. [`\arcsin(1 / 2) =`] [_]{$ans2}{5} END_PGML -#:% section=solution +#:% section = solution BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION -COMMENT("Redefines trig functions to be in degrees (not radians)."); - ENDDOCUMENT(); diff --git a/tutorial/sample-problems/Trig/TrigIdentities.pg b/tutorial/sample-problems/Trig/TrigIdentities.pg index d4293d8cd7..40ba98ce69 100644 --- a/tutorial/sample-problems/Trig/TrigIdentities.pg +++ b/tutorial/sample-problems/Trig/TrigIdentities.pg @@ -14,7 +14,7 @@ #:% name = Trigonometric Identities #:% type = Sample #:% subject = [trigonometry, precalculus] -#:% categories = [trigonometry, custom] +#:% categories = [custom] #:% section = preamble DOCUMENT(); @@ -22,20 +22,27 @@ DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGcourse.pl'); #:% section = setup -#: To prevent the student from just entering the given expression, we create -#: a custom answer checker, which 1) performs a `->reduce` which will do some -#: small simplification, 2) returns an error if the original expression -#: was put in and 3) then checks if the answer is correct. +#: To prevent the student from just entering the given expression, a custom +#: answer checker is used, which 1) calls `reduce` on the student answer which +#: will do some small simplification, 2) returns an error if the original +#: expression is entered and 3) then checks if the answer is correct. #: -#: An alternative method to doing this is in -#: PROBLINK('ProvingTrigIdentities.pg'). +#: A better method for doing this is demonstrated in +#: PROBLINK('ProvingTrigIdentities.pg'). Don't use the method demonstrated in +#: this example as it will fail in many cases. A student can enter +#: `tan(x)*cos(x)*2/2` and it will be counted as correct because the `reduce` +#: call does not simplify that to `tan(x)*cos(x)`. Instead it reduces it to +#: `[2*tan(x)*cos(x)]/2`. In general using string comparison is not what you +#: should do with MathObjects. It completely subverts what MathObjects were +#: designed to do. $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; + if $stu_ans->string eq 'cos(x)*tan(x)' + || $stu_ans->string eq 'tan(x)*cos(x)'; + return $student == $correct ? 1 : 0; } ); @@ -43,7 +50,7 @@ $ans = Compute('sin(x)')->cmp( BEGIN_PGML Simplify the expression as much as possible. -[`\tan(x) \cos(x) =`] [_]{$ans}{15} +[`\tan(x)\cos(x) =`] [_]{$ans}{15} END_PGML #:% section = solution @@ -51,8 +58,4 @@ BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION -COMMENT( - 'Prevents students from entering trivial identities (entering what they ' - . 'were given)'); - ENDDOCUMENT(); diff --git a/tutorial/sample-problems/VectorCalc/CylindricalGraph3D.pg b/tutorial/sample-problems/VectorCalc/CylindricalGraph3D.pg index 34663c4084..31d7a2973e 100644 --- a/tutorial/sample-problems/VectorCalc/CylindricalGraph3D.pg +++ b/tutorial/sample-problems/VectorCalc/CylindricalGraph3D.pg @@ -18,54 +18,74 @@ #:% categories = [graph] #:% section = preamble -#: The dynamic graph is generated with `plotly3D.pl`, -#: so this is needed. +#: The dynamic graph is generated with PODLINK('plotly3D.pl'). DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'plotly3D.pl', 'PGcourse.pl'); -#:% section=setup -#: We generate the plot parametrically for the radial functions `z=cos(r^2/4)` -#: and `z=r*sin^2(t)`. +#:% section = setup +#: To add a plotly graph to a problem, first create a `Graph3D` object by +#: calling the `Graph3D` method. Note that there are several options that can be +#: passed to the `Graph3D` method that affect the display of the graph. This +#: example uses the defaults for all of the options. Then add objects to the +#: graph by calling the `Graph3D` object methods. This example demonstrates the +#: usage of the `addSurface` method. Its syntax is #: -#: This occurs with `x=u*cos(v)` and `y=u*sin(v)`, where `u` and `v` are -#: used as the radial and angular variables respectively. These are the -#: default variables used. +#: ```{#addsurface-usage .perl} +#: $graph->addSurface( +#: [xFunction, yFunction, zFunction], +#: [uMin, uMax, uCount], +#: [vMin, vMax, vCount], +#: options +#: ); +#: ``` #: -#: The second plot changes the variables to `r` and `t` and shows a function -#: with a non-rotational symmetric plot. +#: where `xFunction`, `yFunction`, and `zFunction` are the parametric functions +#: for the `x`, `y`, and `z` coordinates, respectively, `uMin` and `uMax` are +#: the maximum and minimum values for the parameter `u` and `uCount` is the +#: number of values in that range to use, `vMin` and `vMax` are the maximum and +#: minimum values for the parameter `v` and `vCount` is the number of values in +#: that range to use, and the `options` are additional options that can be set +#: using the format `option => value`. Note that `uCount` and `vCount` are +#: optional and both default to 20 if not given. #: -#: The `addSurface` is very flexible, but if you are plotting a function in -#: cylindrical coordinates, then the first two functions should remain the -#: same. +#: First, generate the graph for the function parameterized by `x = u * cos(v)`, +#: `y = u * sin(v)`, and `z = $a * cos(u^2 / 4)` is generated. This graph uses +#: the default variables `u` and `v`. #: -#: See PODLINK('plotly3D.pl') for more information on options. +#: Second, generate the graph for the function parameterized by `x = r * cos(t)`, +#: `y = r * sin(t)`, and `z = r * sin(t)^2`. Since the variables `r` and `t` are +#: used and are not the default variables, those must be specified. +#: +#: See PODLINK('plotly3D.pl') for more details on the usage of the `Graph3D` +#: object and its `addSurface` method. $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 ] +$graph1 = Graph3D(); +$graph1->addSurface( + [ '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 ], +$graph2 = Graph3D(); +$graph2->addSurface( + [ 'r * cos(t)', 'r * sin(t)', 'r * sin(t)^2' ], + [ 0, 6, 30 ], + [ 0, 2 * pi, 30 ], variables => [ 'r', 't' ] ); -#:% section=statement -#: This shows how to add a plot to the problem. +#:% section = statement +#: If `$graph` is a `Graph3D` object, then insert its graph into the problem +#: with `[@ $graph->Print @]*`. BEGIN_PGML -This just shows the two plots side by side. +[@ $graph1->Print @]* -[@ $gr1->Print @]* [@ $gr2->Print @]* +[@ $graph2->Print @]* END_PGML -#:% section=solution +#:% section = solution BEGIN_PGML_SOLUTION Solution explanation goes here. END_PGML_SOLUTION diff --git a/tutorial/sample-problems/VectorCalc/DirectionField.pg b/tutorial/sample-problems/VectorCalc/DirectionField.pg index da85cb3ce7..9f329000e7 100644 --- a/tutorial/sample-problems/VectorCalc/DirectionField.pg +++ b/tutorial/sample-problems/VectorCalc/DirectionField.pg @@ -17,54 +17,61 @@ #:% categories = [graph] #:% see_also = [VectorFieldGraph2D.pg] -#:% section=preamble -#: The macro `PGtikz.pl` is used to produced the direction field. +#:% section = preamble +#: The macro PODLINK('PGtikz.pl') is used to produced the direction field graph. DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'PGtikz.pl', 'PGcourse.pl'); -#:% section=setup +#:% section = setup #: A direction field is a vector field where the length of the vectors are -#: constant. We use the same technique as PROBLINK('VectorFieldGraph2D.pg'). +#: constant. Techniques similar to those in PROBLINK('VectorFieldGraph2D.pg') +#: are used. #: -#: The vector fieldThis is an example of a local html file.
- \ No newline at end of file