In one of my homework problems, I had to compute a sum of an array several times. I ended up writing my own sum subroutine, but there is a sum
available in List::Util
. Can I just do use List::Util qw(sum);
? If so, where in the problem would I put it? If not, is there any other way how to use modules?
There are a couple of things going on here: first is whether the object you're working with is a Perl list (array) or a MathObjects List. A second is that I think that use
is a trapped function call, so you won't be able to call it in the homework problem (this is because WeBWorK problems run in a tightly controlled environment for security purposes).
One option is to have a local library of functions in which we include a sum function that we can then use multiple places. For example, if we are working with Perl arrays and aren't worried about error trapping, we might define the subroutine
sub sumlist { my $sum = 0; foreach ( @_ ) { $sum += $_; } return $sum; }
in a file called localMacros.pl
, located in the templates/macros
in the course directory. Then by including localMacros.pl
in the loadMacros()
at the start of the problem file we gain access to our sumlist
function.
Also if we're just in Perl, a cryptic and possibly not overly efficient sum function is one line, so that may be sufficient for our purposes:
my $sum = 0; map { $sum += $_ } @array;
Both of these don't really address the original question: how we get access to other modules. The short answer to that is, I think, that it's not straightforward but that there are a lot of predefined utilities in the PG codebase. In some cases (I don't think sum()
is one of them) something that will do what we need may be located in one of those. A Google search for "WeBWorK blah function" might find what we need if that's the case.
Does that help?
Gavin
I was not that concerned about the sum itself, as it is an easy function to write, but the general possibility of using functions defined elswhere. I suspected that importing any old module may not be allowed for security reasons, thus the question.
Here is the file that lead to this question:
# DESCRIPTION # Standard deviation of a list # written by Jan Hlavacek (jhlavace@svsu.edu) # ENDDESCRIPTION ## DBsubject('Statistics') ## DBchapter('') ## DBsection('') ## KEYWORDS('standard deviation') ## TitleText1('') ## EditionText1('') ## AuthorText1('') ## Section1('') ## Problem1('') ## Author('Jan Hlavacek') ## Institution('SVSU') DOCUMENT(); loadMacros( "PGstandard.pl", "MathObjects.pl", "PGML.pl", "PGcourse.pl", ); Context("Numeric"); # Define variables here: sub sum { local($s); $s = 0; foreach(@_) { $s = $s + $_; } $s; } $length = random(5,9,1); $min = random(0,10,1); $span = random(1,10,1); @data = map { $min + random(0,100*$span)/100 } (1..$length); $mean = sum(@data)/$length; @devs = map {$_ - $mean} @data; @sqdevs = map {($_)**2} @devs; $sumsqdevs = sum( @sqdevs ); $var = $sumsqdevs/($length-1); $sd = sqrt($var); $datarep = join(', ', @data); $datasum = join('+',@data); $calcdevs = join('\\', map { "x_{$_} - \bar{x} &= $data[$_-1] - $mean = $devs[$_-1]"} 1 .. ($#data+1)); $squaredevs = join('\\', map { "($devs[$_])^2 =& $sqdevs[$_]" } 0 .. $#devs); # Actual problem goes here: TEXT(beginproblem()); BEGIN_PGML Find the standard deviation of the following sample: >>[`[$datarep]`]<< The standard deviation of the sample is [_______]{$sd}. END_PGML # Solution: BEGIN_PGML_SOLUTION *SOLUTION* First we calculate the mean of the data: [``\bar{x} = \frac{\sum x}{n} = \frac{[$datasum]}{[$length]} = [$mean]``] Then we calculate the deviations: [``\begin{align*}[$calcdevs]\end{align*}``] We square all the deviations and add the squares together: [``\begin{align*}[$squaredevs]\\\hline\sum(x-\bar{x})^2 =&[$sumsqdevs]\end{align*}``] Since it is a standard deviation of a _sample_, we divide the sum of squared deviations by [`n-1`] to get the variance: [``s^2 = \frac{\sum (x - \bar{x})^2}{n-1} = \frac{[$sumsqdevs]}{[$length] - 1} = [$var]``] Finally, we take the square root of the variance to find the standard deviation: [``s = \sqrt{s^2} = \sqrt{[$var]} = [$sd]``] END_PGML_SOLUTION ENDDOCUMENT();