You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(53) |
Feb
(56) |
Mar
|
Apr
|
May
(30) |
Jun
(78) |
Jul
(121) |
Aug
(155) |
Sep
(77) |
Oct
(61) |
Nov
(45) |
Dec
(94) |
2006 |
Jan
(116) |
Feb
(33) |
Mar
(11) |
Apr
(23) |
May
(60) |
Jun
(89) |
Jul
(130) |
Aug
(109) |
Sep
(124) |
Oct
(63) |
Nov
(82) |
Dec
(45) |
2007 |
Jan
(31) |
Feb
(35) |
Mar
(123) |
Apr
(36) |
May
(18) |
Jun
(134) |
Jul
(133) |
Aug
(241) |
Sep
(126) |
Oct
(31) |
Nov
(15) |
Dec
(5) |
2008 |
Jan
(11) |
Feb
(6) |
Mar
(16) |
Apr
(29) |
May
(43) |
Jun
(149) |
Jul
(27) |
Aug
(29) |
Sep
(37) |
Oct
(20) |
Nov
(4) |
Dec
(6) |
2009 |
Jan
(34) |
Feb
(30) |
Mar
(16) |
Apr
(6) |
May
(1) |
Jun
(32) |
Jul
(22) |
Aug
(7) |
Sep
(18) |
Oct
(50) |
Nov
(22) |
Dec
(8) |
2010 |
Jan
(17) |
Feb
(15) |
Mar
(10) |
Apr
(9) |
May
(67) |
Jun
(30) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
|
From: Sam H. v. a. <we...@ma...> - 2007-10-25 17:20:13
|
Log Message: ----------- new/improved documentation Modified Files: -------------- pg/macros: IO.pl LinearProgramming.pl MathObjects.pl PG.pl Parser.pl extraAnswerEvaluators.pl Revision Data ------------- Index: Parser.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/Parser.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lmacros/Parser.pl -Lmacros/Parser.pl -u -r1.13 -r1.14 --- macros/Parser.pl +++ macros/Parser.pl @@ -1,14 +1,30 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ +=head1 NAME -=head1 DESCRIPTION - - ########################################################################### - ## - ## Set up the functions needed by the Parser. - ## +Parser.pl - Macro-based fronted to the MathObjects system. =cut +########################################################################### +## +## Set up the functions needed by the Parser. +## + if (!$Parser::installed) { die "\n************************************************************\n" . "* This problem requires the Parser.pm package, which doesn't\n". @@ -27,41 +43,39 @@ loadMacros("Value.pl"); loadMacros("PGcommonFunctions.pl"); -=head3 Formula("formula") +=head1 MACROS - # - # The main way to get a MathObject Formula object (an equation - # that depends on one or more variables). - # +=head1 Formula -=cut + Formula("formula"); + +The main way to get a MathObject Formula object (an equation that depends on one +or more variables). +=cut sub Formula {Value->Package("Formula()")->new(@_)} +=head2 Compute + + Compute("formula"[, var=>value, ...]); + +Compute the value of a formula and return a MathObject appropriate to its +value. Set the object so that the correct answer will be shown exatly as in the +given string rather than by its usual stringification. If the value is a +Formula and any var=>value pairs are specified, then the formula will be +evaluated using the given variable values. E.g., + + $x = Compute("x+3",x=>2) + +will produce the equivalent of $x = Real(5). +The original parsed formula will be saved in the object's original_formula +field, and can be obtained by -=head3 Compute("formula"[,var=>value,...]) + $x->{original_formula}; - # - # Compute the value of a formula and return a MathObject appropriate - # to its value. Set the object so that the correct answer will be - # shown exatly as in the given string rather than by its usual - # stringification. If the value is a Formula and any var=>value - # pairs are specified, then the formula will be evaluated using - # the given variable values. E.g., - # - # $x = Compute("x+3",x=>2) - # - # will produce the equivalent of $x = Real(5). - # - # The original parsed formula will be saved in the object's - # original_formula field, and can be obtained by - # - # $x->{original_formula}; - # - # if needed later in the problem. - # +if needed later in the problem. =cut @@ -78,14 +92,16 @@ return $formula; } -=head3 Context(), Context(name) or Context(context) +=head2 Context - # - # Set or get the current context. When a name is given, the context - # with that name is selected as the current context. When a context - # reference is provided, that context is set as the current one. In - # all three cases, the current context (after setting) is returned. - # + Context(); + Context($name); + Context($context); + +Set or get the current context. When a name is given, the context with that +name is selected as the current context. When a context reference is provided, +that context is set as the current one. In all three cases, the current context +(after setting) is returned. =cut Index: IO.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/IO.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/IO.pl -Lmacros/IO.pl -u -r1.7 -r1.8 --- macros/IO.pl +++ macros/IO.pl @@ -1,15 +1,26 @@ - ################################################################################ -# WeBWorK mod-perl (c) 2000-2002 WeBWorK Project -# $Id$ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. ################################################################################ =head1 NAME -IO.pl - Temporary location for IO functions that need access to the problem -environment. Formerly defined in IO.pm +IO.pl - Input/optput macros that require access to the problem environment. + +=head1 DESCRIPTION -See notes in Translator.pm +See notes in L<WeBWorK::PG::Translator>. =cut @@ -22,6 +33,18 @@ ); } +=head1 MACROS + +=head2 [DEPRECATED] send_mail_to + + send_mail_to($address, subject=>$subject, body=>$body) + +Send an email message with the subject $subject and body $body to the address +$address. This used to be used by mail_answers_to in PGbasicmacros.pl, but it no +longer is. Don't use this, I tell yah! + +=cut + # send_mail_to($user_address,'subject'=>$subject,'body'=>$body) sub send_mail_to { my $user_address = shift; # user must be an instructor @@ -80,29 +103,28 @@ return $out; } -sub getCourseTempDirectory { - return $envir{tempDirectory}; -} +=head2 getCourseTempDirectory -=head2 surePathToTmpFile + $path = getCourseTempDirectory() - surePathToTmpFile($path) - Returns: $path +Returns the path to the current course's temporary directory. -Defined in FILE.pl +=cut -Creates all of the subdirectories between the directory specified -by C<&getCourseTempDirectory> and the address of the path. +sub getCourseTempDirectory { + return $envir{tempDirectory}; +} -Uses +=head2 surePathToTmpFile - &createDirectory($path,$Global::tmp_directory_permission, $Global::numericalGroupID) + $path = surePathToTmpFile($path); -The path may begin with the correct path to the temporary -directory. Any other prefix causes a path relative to the temporary -directory to be created. +Creates all of the intermediate directories between the directory specified by +getCourseTempDirectory() and file specified in $path. -The quality of the error checking could be improved. :-) +If $path begins with the path returned by getCourseTempDirectory(), then the +path is treated as absolute. Otherwise, the path is treated as relative the the +course temp directory. =cut Index: LinearProgramming.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/LinearProgramming.pl,v retrieving revision 1.1 retrieving revision 1.2 diff -Lmacros/LinearProgramming.pl -Lmacros/LinearProgramming.pl -u -r1.1 -r1.2 --- macros/LinearProgramming.pl +++ macros/LinearProgramming.pl @@ -1,62 +1,75 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ =head1 NAME - LinearProgramming.pl +LinearProgramming.pl - Macros for the simplex tableau for linear programming +problems. =head1 SYNPOSIS - Macros related to the simplex method for Linear Programming. +Macros related to the simplex method for Linear Programming. - lp_pivot_element() - find the pivot element from a tableau - lp_solve() - pivot until done - lp_current_value() - given a tableau, find the value of a - requested variable - lp_display() - display a tableau - lp_display_mm() - display a tableau while in math mode - lp_pivot() - perform one pivot on a tableau + lp_pivot_element(...); # find the pivot element from a tableau + lp_solve(...); # pivot until done + lp_current_value(...); # given a tableau, find the value of a requested variable + lp_display(...); # display a tableau + lp_display_mm(...); # display a tableau while in math mode + lp_pivot(...); # perform one pivot on a tableau - Matrix display makes use of macros from PGmatrixmacros.pl, so it - must be included too. +Matrix display makes use of macros from PGmatrixmacros.pl, so it must be +included too. =head1 DESCRIPTION - These are macros for dealing with simplex tableau for linear - programming problems. The tableau is a reference to an array - of arrays, which looks like, [[1,2,3], [4,5,6]]. The entries - can be real numbers or Fractions. - - Tableaus are expected to be legal for the simplex method, such as - - [[0, 3, -4, 5, 1, 0, 0, 28], - [0, 2, 0, 1, 0, 1, 0, 11], - [0, 1, 2, 3, 0, 0, 1, 3], - [1, -1, 2, -3, 0, 0, 0, 0]] +These are macros for dealing with simplex tableau for linear programming +problems. The tableau is a reference to an array of arrays, which looks like, +[[1,2,3], [4,5,6]]. The entries can be real numbers or Fractions. - or something similar which arises after pivoting. +Tableaus are expected to be legal for the simplex method, such as -=cut + [[0, 3, -4, 5, 1, 0, 0, 28], + [0, 2, 0, 1, 0, 1, 0, 11], + [0, 1, 2, 3, 0, 0, 1, 3], + [1, -1, 2, -3, 0, 0, 0, 0]] + +or something similar which arises after pivoting. + +=head1 MACROS =head2 lp_pivot -Take a tableau, the row and column number, and perform one pivot operation. -The tableau can be any matrix in the form reference to array of arrays, such -as [[1,2,3],[4,5,6]]. Row and column numbers start at 0. An optional 4th -argument can be specified to indicate that the matrix has entries of type -Fraction (and then all entries should be of type Fraction). +Take a tableau, the row and column number, and perform one pivot operation. The +tableau can be any matrix in the form reference to array of arrays, such as +[[1,2,3],[4,5,6]]. Row and column numbers start at 0. An optional 4th argument +can be specified to indicate that the matrix has entries of type Fraction (and +then all entries should be of type Fraction). - $m = [[1,2,3],[4,5,6]]; - lp_pivot($m, 0,2); + $m = [[1,2,3],[4,5,6]]; + lp_pivot($m, 0,2); -This function is destructive - it changes the values of its matrix rather -than making a copy, and also returns the matrix, so +This function is destructive - it changes the values of its matrix rather than +making a copy, and also returns the matrix, so - $m = lp_pivot([[1,2,3],[4,5,6]], 0, 2); + $m = lp_pivot([[1,2,3],[4,5,6]], 0, 2); will have the same result as the example above. =cut - # perform a pivot operation # lp_pivot([[1,2,3],...,[4,5,6]], row, col, fractionmode) # row and col indecies start at 0 @@ -96,19 +109,17 @@ =head2 lp_pivot_element -Take a simplex tableau, and determine which element is the next pivot -element based on the algorithm in Mizrahi and Sullivan's Finite -Mathematics, section 4.2. The tableau must represent a point in the -region of feasibility for a LP problem. Otherwise, it can be any -matrix in the form reference to array of arrays, such as -[[1,2,3],[4,5,6]]. An optional 2nd argument can be specified to -indicate that the matrix has entries of type Fraction (and then all -entries should be of type Fraction). - -It returns a pair [row, col], with the count starting at 0. If there -is no legal pivot column (final tableau), it returns [-1,-1]. If -there is a column, but no pivot element (unbounded problem), it returns -[-1, col]. +Take a simplex tableau, and determine which element is the next pivot element +based on the algorithm in Mizrahi and Sullivan's Finite Mathematics, section +4.2. The tableau must represent a point in the region of feasibility for a LP +problem. Otherwise, it can be any matrix in the form reference to array of +arrays, such as [[1,2,3],[4,5,6]]. An optional 2nd argument can be specified to +indicate that the matrix has entries of type Fraction (and then all entries +should be of type Fraction). + +It returns a pair [row, col], with the count starting at 0. If there is no +legal pivot column (final tableau), it returns [-1,-1]. If there is a column, +but no pivot element (unbounded problem), it returns [-1, col]. =cut @@ -154,31 +165,37 @@ =head2 lp_solve -Take a tableau, and perform simplex method pivoting until done. -The tableau can be any matrix in the form reference to array of arrays, such -as [[1,2,3],[4,5,6]], which represents a linear programming tableau at a -feasible point. Options are specified in key/value pairs. - - pivot_limit=> 10 (limit the number of pivots to at most 10 - default is 100) - fraction_mode=> 1 (entries are of type Fraction - defaults to 0, i.e., false) - -This function is destructive - it changes the values of its matrix -rather than making a copy. It returns a triple of the final tableau, -an endcode indicating the type of result, and the number of pivots -used. The endcodes are 1 for success, 0 for unbounded. +Take a tableau, and perform simplex method pivoting until done. The tableau can +be any matrix in the form reference to array of arrays, such as +[[1,2,3],[4,5,6]], which represents a linear programming tableau at a feasible +point. Options are specified in key/value pairs. + +=over + +=item C<S<< pivot_limit => 10 >>> + +limit the number of pivots to at most 10 - default is 100 + +=item C<S<< fraction_mode => 1 >>> + +entries are of type Fraction - defaults to 0, i.e., false + +This function is destructive - it changes the values of its matrix rather than +making a copy. It returns a triple of the final tableau, an endcode indicating +the type of result, and the number of pivots used. The endcodes are 1 for +success, 0 for unbounded. Example: -$m = [[0, 3, -4, 5, 1, 0, 0, 28], - [0, 2, 0, 1, 0, 1, 0, 11], - [0, 1, 2, 3, 0, 0, 1, 3], - [1, -1, 2, -3, 0, 0, 0, 0]]; + $m = [[0, 3, -4, 5, 1, 0, 0, 28], + [0, 2, 0, 1, 0, 1, 0, 11], + [0, 1, 2, 3, 0, 0, 1, 3], + [1, -1, 2, -3, 0, 0, 0, 0]]; -($m, $endcode, $pivcount) = lp_solve($m, pivot_limit=>200); + ($m, $endcode, $pivcount) = lp_solve($m, pivot_limit=>200); =cut - # Solve a linear programming problem # lp_solve([[1,2,3],[4,5,6]]) # It returns a triple of the final tableau, a code to say if we @@ -223,10 +240,10 @@ =head2 lp_current_value Takes a simplex tableau and returns the value of a particular variable. -Variables are associated to column numbers which are indexed starting with -0. So, usually this means that the objective function is 0, x_1 is 1, and -so on. This can be used for slack variables too (assuming you know what -columns they are in). +Variables are associated to column numbers which are indexed starting with 0. +So, usually this means that the objective function is 0, x_1 is 1, and so on. +This can be used for slack variables too (assuming you know what columns they +are in). =cut @@ -267,22 +284,22 @@ Display a simplex tableau while in math mode. -$m = [[0, 3, -4, 5, 1, 0, 0, 28], - [0, 2, 0, 1, 0, 1, 0, 11], - [0, 1, 2, 3, 0, 0, 1, 3], - [1, -1, 2, -3, 0, 0, 0, 0]]; - -\[ \{ lp_display_mm($m) \} \] - -Accepts the same optional arguments as lp_display (see below), and -produces nicer looking results. However, it cannot have answer rules -in the tableau (lp_display can have them for fill in the blank -tableaus). + $m = [[0, 3, -4, 5, 1, 0, 0, 28], + [0, 2, 0, 1, 0, 1, 0, 11], + [0, 1, 2, 3, 0, 0, 1, 3], + [1, -1, 2, -3, 0, 0, 0, 0]]; + + BEGIN_TEXT + \[ \{ lp_display_mm($m) \} \] + END_TEXT + +Accepts the same optional arguments as lp_display (see below), and produces +nicer looking results. However, it cannot have answer rules in the tableau +(lp_display can have them for fill in the blank tableaus). =cut # Display a tableau in math mode - sub lp_display_mm { lp_display(@_, force_tex=>1); } @@ -309,21 +326,21 @@ Display a simplex tableau while not in math mode. -$m = [[0, 3, -4, 5, 1, 0, 0, 28], - [0, 2, 0, 1, 0, 1, 0, 11], - [0, 1, 2, 3, 0, 0, 1, 3], - [1, -1, 2, -3, 0, 0, 0, 0]]; - -\{ lp_display($m)\} - -Takes the same optional arguments as display_matrix. The default -for column alignment as "augmentation line" before the last column. -It also adds a horizontal line before the last row if it is not already -specified. + $m = [[0, 3, -4, 5, 1, 0, 0, 28], + [0, 2, 0, 1, 0, 1, 0, 11], + [0, 1, 2, 3, 0, 0, 1, 3], + [1, -1, 2, -3, 0, 0, 0, 0]]; + + BEGIN_TEXT + \{ lp_display($m)\} + END_TEXT + +Takes the same optional arguments as display_matrix. The default for column +alignment as "augmentation line" before the last column. It also adds a +horizontal line before the last row if it is not already specified. =cut - # Display a tableau sub lp_display { my $a1_ref = shift; @@ -345,5 +362,4 @@ display_matrix($a_ref, %opts); } -# return 1 so that this file can be included with require -1 +1; Index: PG.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/PG.pl,v retrieving revision 1.33 retrieving revision 1.34 diff -Lmacros/PG.pl -Lmacros/PG.pl -u -r1.33 -r1.34 --- macros/PG.pl +++ macros/PG.pl @@ -1,13 +1,13 @@ ################################################################################ -# WeBWorK Program Generation Language -# Copyright � 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ # $CVSHeader$ -# +# # This program is free software; you can redistribute it and/or modify it under # the terms of either: (a) the GNU General Public License as published by the # Free Software Foundation; either version 2, or (at your option) any later # version, or (b) the "Artistic License" which comes with this package. -# +# # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the @@ -22,23 +22,23 @@ In a PG problem: - DOCUMENT(); # should be the first statment in the problem - - loadMacros(.....); # (optional) load other macro files if needed. - # (loadMacros is defined in F<dangerousMacros.pl>) - - HEADER_TEXT(...); # (optional) used only for inserting javaScript into problems. - - TEXT( # insert text of problems - "Problem text to be", - "displayed. Enter 1 in this blank:", - ANS_RULE(1,30) # ANS_RULE() defines an answer blank 30 characters long. - # It is defined in F<PGbasicmacros.pl> - ); - - ANS(answer_evalutors); # see F<PGanswermacros.pl> for examples of answer evaluatiors. - - ENDDOCUMENT() # must be the last statement in the problem + DOCUMENT(); # should be the first statment in the problem + + loadMacros(.....); # (optional) load other macro files if needed. + # (loadMacros is defined in F<dangerousMacros.pl>) + + HEADER_TEXT(...); # (optional) used only for inserting javaScript into problems. + + TEXT( # insert text of problems + "Problem text to be displayed. ", + "Enter 1 in this blank:", + ANS_RULE(1,30) # ANS_RULE() defines an answer blank 30 characters long. + # It is defined in F<PGbasicmacros.pl> + ); + + ANS(answer_evalutors); # see F<PGanswermacros.pl> for examples of answer evaluatiors. + + ENDDOCUMENT() # must be the last statement in the problem =head1 DESCRIPTION Index: extraAnswerEvaluators.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/extraAnswerEvaluators.pl,v retrieving revision 1.19 retrieving revision 1.20 diff -Lmacros/extraAnswerEvaluators.pl -Lmacros/extraAnswerEvaluators.pl -u -r1.19 -r1.20 --- macros/extraAnswerEvaluators.pl +++ macros/extraAnswerEvaluators.pl @@ -1,32 +1,41 @@ -loadMacros('MathObjects.pl'); +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ =head1 NAME - extraAnswerEvaluators.pl - -=head1 SYNPOSIS +extraAnswerEvaluators.pl - Answer evaluators for intervals, lists of numbers, +and lists of points. - Answer Evaluators for intervals, lists of numbers, lists of points, - and equations. +=head1 SYNPOSIS - interval_cmp() -- checks answers which are unions of intervals. - It can also be used for checking an ordered pair or - list of ordered pairs. + interval_cmp() -- checks answers which are unions of intervals. It can also + be used for checking an ordered pair or list of ordered + pairs. number_list_cmp() -- checks a comma separated list of numbers. By use of optional arguments, you can request that order be - important, that complex numbers be allowed, and - specify extra arguments to be sent to num_cmp (or - cplx_cmp) for checking individual entries. - - equation_cmp() -- provides a limited facility for checking equations. - It makes no pretense of checking to see if the real locus - of the student's equation matches the real locus of the - instructor's equation. The student's equation must be - of the same general type as the instructors to get credit. - - -=cut + important, that complex numbers be allowed, and specify + extra arguments to be sent to num_cmp (or cplx_cmp) for + checking individual entries. + + equation_cmp() -- provides a limited facility for checking equations. It + makes no pretense of checking to see if the real locus of + the student's equation matches the real locus of the + instructor's equation. The student's equation must be of + the same general type as the instructors to get credit. =head1 DESCRIPTION @@ -35,6 +44,8 @@ =cut +loadMacros('MathObjects.pl'); + { package Equation_eval; @@ -217,41 +228,45 @@ return($context); } -=head3 interval_cmp () +=head1 MACROS + +=head2 interval_cmp Compares an interval or union of intervals. Typical invocations are - interval_cmp("(2, 3] U(7, 11)") + interval_cmp("(2, 3] U(7, 11)") -The U is used for union symbol. In fact, any garbage (or nothing at all) -can go between intervals. It makes sure open/closed parts of intervals -are correct, unless you don't like that. To have it ignore the difference -between open and closed endpoints, use +The U is used for union symbol. In fact, any garbage (or nothing at all) can go +between intervals. It makes sure open/closed parts of intervals are correct, +unless you don't like that. To have it ignore the difference between open and +closed endpoints, use - interval_cmp("(2, 3] U(7, 11)", sloppy=>'yes') + interval_cmp("(2, 3] U(7, 11)", sloppy=>'yes') -interval_cmp uses num_cmp on the endpoints. You can pass optional -arguments for num_cmp, so to change the tolerance, you can use +interval_cmp uses num_cmp on the endpoints. You can pass optional arguments for +num_cmp, so to change the tolerance, you can use - interval_cmp("(2, 3] U(3+4, 11)", relTol=>3) + interval_cmp("(2, 3] U(3+4, 11)", relTol=>3) The intervals can be listed in any order, unless you want to force a particular order, which is signaled as - interval_cmp("(2, 3] U(3+4, 11)", ordered=>'strict') + interval_cmp("(2, 3] U(3+4, 11)", ordered=>'strict') You can specify infinity as an endpoint. It will do a case-insensitive string match looking for I, Infinity, Infty, or Inf. You can prepend a + or -, as in - interval_cmp("(-inf, 3] U [e^10, infinity)") + interval_cmp("(-inf, 3] U [e^10, infinity)") + or - interval_cmp("(-INF, 3] U [e^10, +I)") + + interval_cmp("(-INF, 3] U [e^10, +I)") If the question might have an empty set as the answer, you can use the strings option to allow for it. So - interval_cmp("$ans", strings=>['empty']) + interval_cmp("$ans", strings=>['empty']) will not generate an error message if the student enters the string empty. Better still, it will mark a student answer of "empty" as correct @@ -261,7 +276,7 @@ Internally, this is just a distinction of whether to put nice union symbols between intervals, or commas. To get commas, use - interval_cmp("(1,2), (2,3), (4,-1)", unions=>'no') + interval_cmp("(1,2), (2,3), (4,-1)", unions=>'no') Note that interval_cmp makes no attempt at simplifying overlapping intervals. This becomes an important feature when you are really checking lists of @@ -272,7 +287,7 @@ showCoordinateHints, showHints, partialCredit, and/or showLengthHints as optional arguments: - interval_cmp("(1,2), (2,3), (4,-1)", unions=>'no', partialCredit=>1) + interval_cmp("(1,2), (2,3), (4,-1)", unions=>'no', partialCredit=>1) Also, set differences and 'R' for all real numbers now work too since they work for Parser Intervals and Unions. @@ -371,24 +386,24 @@ return($ans_eval); } -=head3 number_list_cmp () +=head2 number_list_cmp Checks an answer which is a comma-separated list of numbers. The actual numbers are fed to num_cmp, so all of the flexibilty of num_cmp carries over (values can be expressions to be evaluated). For example, - number_list_cmp("1, -2") + number_list_cmp("1, -2") will accept "1, -2", "-2, 1", or "-1-1,sqrt(1)". - number_list_cmp("1^2 + 1, 2^2 + 1, 3^2 + 1", ordered=>'strict') + number_list_cmp("1^2 + 1, 2^2 + 1, 3^2 + 1", ordered=>'strict') will accept "2, 5, 10", but not "5, 2, 10". If you want to allow complex number entries, complex=>'ok' will cause it to use cplx_cmp instead: - number_list_cmp("2, -2, 2i, -2i", complex=>'ok') + number_list_cmp("2, -2, 2i, -2i", complex=>'ok') In cases where you set complex=>'ok', be sure the problem file loads PGcomplexmacros.pl. @@ -396,23 +411,23 @@ Optional arguements for num_cmp (resp. cplx_cmp) can be used as well, such as - number_list_cmp("cos(3), sqrt(111)", relTol => 3) + number_list_cmp("cos(3), sqrt(111)", relTol => 3) The strings=>['hello'] argument is treated specially. It can be used to replace the entire answer. So - number_list_cmp("cos(3), sqrt(111)", strings=>['none']) + number_list_cmp("cos(3), sqrt(111)", strings=>['none']) will mark "none" wrong, but not generate an error. On the other hand, - number_list_cmp("none", strings=>['none']) + number_list_cmp("none", strings=>['none']) will mark "none" as correct. One can also specify optionnal arguments for Parser's List checker: showHints, partialCredit, and showLengthHints, as in: - number_list_cmp("cos(3), sqrt(111)", partialCredit=>1) + number_list_cmp("cos(3), sqrt(111)", partialCredit=>1) =cut @@ -454,7 +469,7 @@ } -=head3 equation_cmp () +=heads equation_cmp Compares an equation. This really piggy-backs off of fun_cmp. It looks at LHS-RHS of the equations to see if they agree up to constant multiple. @@ -466,11 +481,10 @@ Typical invocation would be: - equation_com("x^2+(y-1)^2 = 11", vars=>['x','y']) + equation_com("x^2+(y-1)^2 = 11", vars=>['x','y']) =cut sub equation_cmp { Equation_eval::equation_cmp(@_); } - Index: MathObjects.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/MathObjects.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/MathObjects.pl -Lmacros/MathObjects.pl -u -r1.7 -r1.8 --- macros/MathObjects.pl +++ macros/MathObjects.pl @@ -1,13 +1,34 @@ -=head1 MathObjects.pl +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +=head1 NAME + +MathObjects.pl - Macro-based fronted to the MathObjects system. + +=head1 DESCRIPTION + +This file loads Parser.pl which in turn loads Value.pl The purpose of this file +is to encourage the use of the name MathObjects instead of Parser (which is not +as intuitive for those who don't know the history). -=pod +It may later be used for other purposes as well. -This file loads Parser.pl which in turn loads Value.pl -The purpose of this file is to encourage the use of the name MathObjects -instead of Parser (which is not as intuitive for those who don't know -the history). +=head1 SEE ALSO -It may later be used for other purposes as well. +L<Parser.pl>. =cut |
From: Sam H. v. a. <we...@ma...> - 2007-10-22 20:40:49
|
Log Message: ----------- actually do the file copies, added --pretend and --verbose options. Modified Files: -------------- webwork2/bin: pg-pull Revision Data ------------- Index: pg-pull =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/pg-pull,v retrieving revision 1.2 retrieving revision 1.3 diff -Lbin/pg-pull -Lbin/pg-pull -u -r1.2 -r1.3 --- bin/pg-pull +++ bin/pg-pull @@ -34,6 +34,7 @@ use Data::Dumper; use File::Path; use File::Spec; +use File::Copy; use Getopt::Long; use IO::File; @@ -109,7 +110,6 @@ sub process_file { my $file = shift; - print "$file\n"; # ignoring volume here because we don't care about w32 (undef, my ($dir, $name)) = File::Spec->splitpath($file); @@ -133,12 +133,14 @@ my @files = ($target_name); push @files, @{$tags{UsesAuxiliaryFiles}} if defined $tags{UsesAuxiliaryFiles}; - mkpath($target_dir); + #print "mkpath $target_dir\n" if $o{pretend} or $o{verbose}; + mkpath($target_dir) unless $o{pretend}; + foreach my $curr (@files) { my $src = File::Spec->catpath(undef, $dir, $curr); my $dest = File::Spec->catpath(undef, $target_dir, $curr); - print "$src => $dest\n"; - #copy($src, $dest); + print "copy $src $dest\n" if $o{pretend} or $o{verbose}; + copy($src, $dest) unless $o{pretend}; } } @@ -260,5 +262,7 @@ 'src-lib=s', 'stdin', 'suffix=s', + 'pretend', + 'verbose' ); main(@ARGV); |
From: dpvc v. a. <we...@ma...> - 2007-10-21 12:21:00
|
Log Message: ----------- Fixed problem with ordered=>"strict" in number_list_cmp() Modified Files: -------------- pg/macros: extraAnswerEvaluators.pl Revision Data ------------- Index: extraAnswerEvaluators.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/extraAnswerEvaluators.pl,v retrieving revision 1.18 retrieving revision 1.19 diff -Lmacros/extraAnswerEvaluators.pl -Lmacros/extraAnswerEvaluators.pl -u -r1.18 -r1.19 --- macros/extraAnswerEvaluators.pl +++ macros/extraAnswerEvaluators.pl @@ -418,18 +418,18 @@ sub number_list_cmp { my $list = shift; - + my %num_params = @_; - + my $mode = $num_params{mode} || 'std'; my %options = (debug => $num_params{debug}); - + # # Get an apppropriate context based on the mode # my $oldContext = Context(); my $context = mode2context($mode, %num_params); - + #$context->strings->clear; if ($num_params{strings}) { foreach my $string (@{$num_params{strings}}) { @@ -439,14 +439,14 @@ defined($context->strings->get($string)); } } - - $options{ordered} = 1 if(defined($num_params{ordered}) and $opts{ordered}); + + $options{ordered} = 1 if defined($num_params{ordered}); # These didn't exist before in number_list_cmp so they behaved like # in List()->cmp. Now they can be optionally set for my $o qw( showHints partialCredit showLengthHints ) { $options{$o} = $num_params{$o} || 0; } - + Context($context); my $ans_eval = List($list)->cmp(%options); Context($oldContext); |
From: Sam H. v. a. <we...@ma...> - 2007-10-17 17:06:05
|
Log Message: ----------- use WEBWORK_ROOT to find libdir (not FindBin) Modified Files: -------------- webwork2/bin: pg-append-textbook-tags pg-find-tags pg-pull Revision Data ------------- Index: pg-find-tags =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/pg-find-tags,v retrieving revision 1.1 retrieving revision 1.2 diff -Lbin/pg-find-tags -Lbin/pg-find-tags -u -r1.1 -r1.2 --- bin/pg-find-tags +++ bin/pg-find-tags @@ -25,8 +25,12 @@ use Getopt::Long; use IO::Handle; -use FindBin; -use lib "$FindBin::Bin/../lib"; +BEGIN { + die "WEBWORK_ROOT not found in environment.\n" + unless exists $ENV{WEBWORK_ROOT}; +} + +use lib "$ENV{WEBWORK_ROOT}/lib"; use WeBWorK::NPL qw/gen_find_tags/; sub main { Index: pg-append-textbook-tags =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/pg-append-textbook-tags,v retrieving revision 1.1 retrieving revision 1.2 diff -Lbin/pg-append-textbook-tags -Lbin/pg-append-textbook-tags -u -r1.1 -r1.2 --- bin/pg-append-textbook-tags +++ bin/pg-append-textbook-tags @@ -24,8 +24,12 @@ use Data::Dumper;# $Data::Dumper::Indent = 0; use Getopt::Long; -use FindBin; -use lib "$FindBin::Bin/../lib"; +BEGIN { + die "WEBWORK_ROOT not found in environment.\n" + unless exists $ENV{WEBWORK_ROOT}; +} + +use lib "$ENV{WEBWORK_ROOT}/lib"; use WeBWorK::NPL qw/read_tags format_tags/; sub main { Index: pg-pull =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/pg-pull,v retrieving revision 1.1 retrieving revision 1.2 diff -Lbin/pg-pull -Lbin/pg-pull -u -r1.1 -r1.2 --- bin/pg-pull +++ bin/pg-pull @@ -37,8 +37,12 @@ use Getopt::Long; use IO::File; -use FindBin; -use lib "$FindBin::Bin/../lib"; +BEGIN { + die "WEBWORK_ROOT not found in environment.\n" + unless exists $ENV{WEBWORK_ROOT}; +} + +use lib "$ENV{WEBWORK_ROOT}/lib"; use WeBWorK::NPL qw/read_textbooks read_tags/; my %o; |
From: Sam H. v. a. <we...@ma...> - 2007-10-17 17:04:16
|
Log Message: ----------- Useful tools for managing NPL-style tags in PG problems. These tools were developed in the course of managing the Rogawski problem library for W.H.Freeman: lib/WeBWorK/NPL.pm - Useful routines for parsing and writing PG tags format as well as the Textbooks file format. Also contains a routine gen_find_tags which generates a "wanted" function for File::Find that finds files that match a certain tags specification. As of now, editing of tags is somewhat limited -- a facility for appending tags to the end of the tag block is given, which should be sufficient for adding a new textbook to existing files. The tag parsing routine is all new, and should be somewhat more robust and harder to abuse. One notable improvement is that it can handle escaped single quotes within values, making it possible to say things like: ## DBsection('L\'Hospital\'s Rule') However, the stricter value parsing makes it reject some broken values already in the NPL. In the case of KEYWORDS, if a parse error is encountered it will fall back on the old keyword parsing method. This could be extended to other values if need be. bin/pg-find-tags - Prints file names for files that match specifications given on the command line. Good demo of how to use gen_find_tags. Can be easily modified to perform other tasks. bin/pg-append-textbook-tags - Appends tags for a new textbook to the end of the tag block in an already-tagged file. bin/pg-pull - Pull files from an existing library into a new library. Directory and file names for the new library can be generated from the tags in the problem (and optionally use the names from a Textbooks file). We use this to pull Rogawski-tagged NPL problems out for separate distribution. This script has some annoying limitations right now -- read the comments. Added Files: ----------- webwork2/bin: pg-append-textbook-tags pg-find-tags pg-pull webwork2/lib/WeBWorK: NPL.pm Revision Data ------------- --- /dev/null +++ bin/pg-find-tags @@ -0,0 +1,106 @@ +#!/usr/bin/env perl +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/bin/pg-find-tags,v 1.1 2007/10/17 16:56:16 sh002i Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +# +# Contributed by W.H. Freeman; Bedford, Freeman, and Worth Publishing Group. +################################################################################ + +use strict; +use warnings; + +use Data::Dumper;# $Data::Dumper::Indent = 0; +use File::Find; +use Getopt::Long; +use IO::Handle; + +use FindBin; +use lib "$FindBin::Bin/../lib"; +use WeBWorK::NPL qw/gen_find_tags/; + +sub main { + my ($pattern, @paths) = @_; + my $oldfh = select(STDERR); $|=1; select(STDOUT); $|=1; select($oldfh); + my $wanted = gen_find_tags($pattern, \&report); + find({ wanted=>$wanted, no_chdir=>1, }, @paths); +} + +sub report { + my ($name, $tags) = @_; + print "$name\n"; +} + +my %o; +GetOptions(\%o, + "DESCRIPTION=s", + "KEYWORDS=s", + "DBsubject=s", + "DBchapter=s", + "DBsection=s", + "Date=s", + "Institution=s", + "Author=s", + "title=s", + "edition=s", + "author=s", + "chapter=s", + "section=s", + "problem=s", +); +main(\%o, @ARGV); + +__END__ + +=head1 NAME + +pg-find-tags - Search for PG files that contain the specified metadata tags. + +=head1 SYNOPSIS + + pg-find-tags ~/MyLibrary /ww/OtherLibrary --author=Rogawski --edition=1 + +=head1 DESCRIPTION + +Recusively searches the paths given for PG files containing all of the specified +tags. Output is the path to each matching file. Legal tags are as follows: + +B<Global fields:> + + --DESCRIPTION=STRING + --KEYWORDS=STRING + --DBsubject=STRING + --DBchapter=STRING + --DBsection=STRING + --Date=STRING + --Institution=STRING + --Author=STRING + +B<Text-specific fields:> + + --title=STRING + --edition=STRING + --author=STRING + --chapter=STRING + --section=STRING + --problem=STRING + +If multiple text-specific fields are given, then all must match for a single +textbook. + +=head1 LIMITATIONS + +Doesn't support full boolean searches, and it probably should. Can only match on +full strings, so you can't match on a single keyword, for example. + +=cut --- /dev/null +++ bin/pg-append-textbook-tags @@ -0,0 +1,111 @@ +#!/usr/bin/env perl +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/bin/pg-append-textbook-tags,v 1.1 2007/10/17 16:56:16 sh002i Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +# +# Contributed by W.H. Freeman; Bedford, Freeman, and Worth Publishing Group. +################################################################################ + +use strict; +use warnings; + +use IO::File; +use Data::Dumper;# $Data::Dumper::Indent = 0; +use Getopt::Long; + +use FindBin; +use lib "$FindBin::Bin/../lib"; +use WeBWorK::NPL qw/read_tags format_tags/; + +sub main { + my ($new_tags, @files) = @_; + $new_tags = { textbooks=>[$new_tags] }; + foreach my $file (@files) { + add_tags_to_file($new_tags, $file); + } +} + +sub add_tags_to_file { + my ($new_tags, $file) = @_; + + my $pgfile = new IO::File($file, '+<:utf8') or do { + warn "Failed to open file $file for editing: $!\n"; + warn "New tags will not be written to this file.\n"; + return; + }; + + my $old_tags = {}; + read_tags($pgfile, $old_tags, 1); # 1==extra_editing_info + my $pos = $old_tags->{_pos}; + my $rest = $old_tags->{_rest}; + my $maxtextbook = $old_tags->{_maxtextbook}; + print "pos=$pos maxtextbook=$maxtextbook\n"; + + my @tagstrings = format_tags($new_tags, $maxtextbook+1); + + seek $pgfile, $pos, 0; + foreach my $string (@tagstrings) { + $string =~ s/^/## /gm; + print $pgfile "$string\n"; + } + print $pgfile $rest; +} + +my %o; +GetOptions(\%o, + "title=s", + "edition=s", + "author=s", + "chapter=s", + "section=s", + "problem=s", +); +main(\%o, @ARGV); + +__END__ + +=head1 NAME + +pg-append-text-tags -- Add textbook tags to a PG file. + +=head1 SYNOPSIS + + pg-append-text-tags file1.pg file2.pg --author=Rogawski \ + --title='Calculus: Early Transcendentals' --edition=1 \ + --chapter=3 --section=1 --problem=11,13 + +=head1 DESCRIPTION + +This script appends metadata tags for a new textbook to one or more PG files. +Tags are given as switches on the command line: + + --title=STRING + --edition=STRING + --author=STRING + --chapter=STRING + --section=STRING + --problem=STRING + +More than one problem can be specified for B<--problem> by passing a +comma-separated list. + +=head1 LIMITATIONS + +Only adds tags for a new textbook, can't rewrite existing tags, can't remove +tags. + +At some point I will write Tie::PGFile, which will allow direct editing of tags +just by modifying a hash, and that will fix all of these problems. :) + +=cut --- /dev/null +++ bin/pg-pull @@ -0,0 +1,260 @@ +#!/usr/bin/env perl +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/bin/pg-pull,v 1.1 2007/10/17 16:56:16 sh002i Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +# +# Contributed by W.H. Freeman; Bedford, Freeman, and Worth Publishing Group. +################################################################################ + +# Assemble a new problem library consisting of the specified PG files and any required +# auxiliary files (i.e. images). +# +# Auxiliary files must be specified in the (unofficial) UsesAuxiliaryFiles(...) tag. +# It is assumed that auxiliary files don't depend on further auxiliary files. +# This will be true <100% of the time. +# +# Also, right now this script always uses the FIRST textbook entry in generating +# the new file's path and name. Eventually, a --match-text switch will make the +# script useful for files with multiple text tags. + +use strict; +use warnings; + +use Data::Dumper; +use File::Path; +use File::Spec; +use Getopt::Long; +use IO::File; + +use FindBin; +use lib "$FindBin::Bin/../lib"; +use WeBWorK::NPL qw/read_textbooks read_tags/; + +my %o; +my %textbooks; +my %seen_paths; + +sub main { + my (@files) = @_; + my $oldfh = select(STDERR); $|=1; select(STDOUT); $|=1; select($oldfh); + + my $dest_lib = $o{'dest-lib'}; + $dest_lib = pop @files unless defined $dest_lib; + die "dest-lib not specified.\n" . usage() unless defined $dest_lib; + + die "no files specified (perhaps you meant to use --stdin?)\n" . usage() + unless @files or $o{stdin}; + + if ($o{'orig-paths'} and not defined $o{'src-lib'}) { + die "--src-lib must be specified with --orig-paths.\n", usage(); + } + + if (defined $o{'src-lib'} and not $o{'orig-paths'}) { + warn "ignoring --src-lib since --orig-paths was not specified.\n"; + } + + if ($o{'orig-paths'}) { + if (defined $o{textbooks}) { + warn "ignoring --textbooks since --orig-paths was specified.\n"; + } + } else { + if (defined $o{textbooks}) { + get_texts($o{textbooks}); + } else { + warn "No Textbooks file specified -- directories will not be named.\n"; + } + } + + my $getfile; + if ($o{stdin}) { + $getfile = sub { if (defined ($_=<STDIN>)) { chomp; $_ } else { () } }; + } else { + my $i = 0; + $getfile = sub { defined $files[$i] ? $files[$i++] : () }; + } + + while (defined (my $file = &$getfile)) { + #print "file=$file\n"; + process_file($file); + } +} + +sub get_texts { + my $textbooks = shift; + my @textbooks; + + open my $fh, '<', $textbooks or die "$textbooks: $!\n"; + read_textbooks($fh, \@textbooks); + close $fh; + + foreach my $textbook (@textbooks) { + $textbooks{$textbook->{'_author'}}{$textbook->{'_title'}}{$textbook->{'_edition'}} = $textbook; + } +} + +sub process_file { + my $file = shift; + print "$file\n"; + + # ignoring volume here because we don't care about w32 + (undef, my ($dir, $name)) = File::Spec->splitpath($file); + #print " dir=$dir\n"; + #print " name=$name\n"; + + my %tags; + read_tags($file, \%tags); + #print Dumper(\%tags); + + my ($target_dir_rel, $target_name); + if ($o{'orig-paths'}) { + $target_dir_rel = File::Spec->abs2rel($dir, $o{'src-lib'}); + $target_name = $name; + } else { + ($target_dir_rel, $target_name) = tags_to_path(\%tags, '.pg'); + } + + my $target_dir = File::Spec->catdir($o{'dest-lib'}, $target_dir_rel); + + my @files = ($target_name); + push @files, @{$tags{UsesAuxiliaryFiles}} if defined $tags{UsesAuxiliaryFiles}; + + mkpath($target_dir); + foreach my $curr (@files) { + my $src = File::Spec->catpath(undef, $dir, $curr); + my $dest = File::Spec->catpath(undef, $target_dir, $curr); + print "$src => $dest\n"; + #copy($src, $dest); + } +} + +sub tags_to_path { + my ($tags, $ext) = @_; + + # FIXME here is where we'd put in textbook matching + my $text = $tags->{textbooks}[0]; + unless (defined $text) { + warn "no textbook tags\n"; + return; + } + my %text = %$text; + + if (not defined $text{author} + or not defined $text{title} + or not defined $text{edition} + or not defined $text{chapter} + or not defined $text{section} + or not defined $text{problem} + or @{$text{problem}} == 0) { + warn "incomplete textbook tags\n"; + return; + } + + my $chapter_name = $text{chapter}; + my $chapsec_name = "$text{chapter}.$text{section}"; + + if (defined $o{textbooks}) { + my $text_names = $textbooks{$text{author}}{$text{title}}{$text{edition}}; + if (defined $text_names) { + my %text_names = %$text_names; + + if (defined $text_names{$text{chapter}}) { + $chapter_name .= sissy_filename(" $text_names{$text{chapter}}") + } else { + warn "no chapter name for $text{chapter}"; + } + + if (defined $text_names{"$text{chapter}.$text{section}"}) { + $chapsec_name .= sissy_filename(" $text_names{qq|$text{chapter}.$text{section}|}"); + } else { + warn "no section name for $text{chapter}.$text{section}"; + } + } else { + warn "can't find text $text{author}/$text{title}/$text{edition} in Textbooks file -- directories will be unnamed\n"; + } + } + + my $ex_name = "$text{chapter}.$text{section}.$text{problem}[0]"; + $ex_name .= '+' if @{$text{problem}} > 1; + + #print " chapter_name=$chapter_name\n"; + #print " chapsec_name=$chapsec_name\n"; + #print " ex_name=$ex_name\n"; + + # make sure path hasn't been seen before + my $dir = File::Spec->catdir($chapter_name, $chapsec_name); + my $partA = $ex_name; + $partA .= $o{suffix} if defined $o{suffix}; + my $partB = $ext; + my $uniq = unique_name($dir, $partA, $partB); + + #print " partA=$partA\n"; + #print " uniq=$uniq\n"; + #print " partB=$partB\n"; + + return $dir, "$partA$uniq$partB"; +} + +sub unique_name { + my ($dir, $partA, $partB) = @_; + my $whole = File::Spec->catpath(undef, $dir, "$partA$partB"); + my $uniq = ''; + if (exists $seen_paths{$whole}) { + my $i = 2; + do { + $uniq = "~$i"; + $whole = File::Spec->catpath(undef, $dir, "$partA$uniq$partB"); + } while (exists $seen_paths{$whole}); + } + $seen_paths{$whole} = (); + return $uniq; +} + +#sub find_macro_file { +# my ($name, $ref_by) = @_; +# my (undef,$ref_by_dir,undef) = File::Spec->splitpath($ref_by); +# my $ref_by_dir_rel = File::Spec->abs2rel($ref_by_dir, $o{'src-lib'}); +# my @dirs = File::Spec->splitdir($ref_by_dir_rel); +# while (1) { +# my $dir = File::Spec->catdir(@dirs); +# my $file = File::Spec->catfile(${'src-lib'}, $dir, $name); +# return $file if -f $file; +# pop @dirs; +# } +#} + +sub sissy_filename { + my $string = shift; + $string =~ s/:/-/g; + $string =~ s/[<>\"\/\/|?*]/_/g; + $string =~ s/\s+/_/g; + return $string; +} + +sub usage { + return "USAGE:\n" + . "$0 --textbooks=PATH --suffix=STRING files... dest-lib\n" + . "$0 --textbooks=PATH --suffix=STRING --dest-lib=PATH files...\n" + . "$0 --orig-paths -src-lib=PATH files... dest-lib\n" + . "$0 --orig-paths -src-lib=PATH --dest-lib=PATH files...\n"; +} + +GetOptions(\%o, + 'textbooks=s', + 'dest-lib=s', + 'orig-paths', + 'src-lib=s', + 'stdin', + 'suffix=s', +); +main(@ARGV); --- /dev/null +++ lib/WeBWorK/NPL.pm @@ -0,0 +1,625 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/lib/WeBWorK/NPL.pm,v 1.1 2007/10/17 16:56:16 sh002i Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +# +# Contributed by W.H. Freeman; Bedford, Freeman, and Worth Publishing Group. +################################################################################ + +package WeBWorK::NPL; +use base 'Exporter'; + +=head1 NAME + +WeBWorK::NPL - Parse formats used by the National Problem Library. + +=head1 SYNOPSIS + + use WeBWorK::NPL qw/read_textbooks read_tags format_tags gen_find_tags/; + + open TEXTS, "<", "Textbooks"; + my $textbooks = []; + read_textbooks(\*TEXTS, $textbooks); + + open PGFILE, "<", "file.pg"; + my $tags = {}; + read_tags(\*PGFILE, $tags); + + foreach my $string (format_tags($tags)) { + $string =~ s/^/## /gm; + print "TAG: $string\n"; + } + + use File::Find; + my $process = sub { print "Found: $_[0]\n" }; + my $wanted = gen_find_tags({author=>'Rogawski'}, $process); + find({wanted=>$wanted}, @ARGV); + +=head1 DESCRIPTION + +This package contains parsing routines for the various data formats associated +with the National Problem Library. + +=cut + +use strict; +use warnings; +use Data::Dumper; + +our @EXPORT_OK = qw( + read_textbooks + read_tags + format_tags + gen_find_tags +); + +our @global_fields = qw(DESCRIPTION KEYWORDS DBsubject DBchapter DBsection Date +Institution Author UsesAuxiliaryFiles); +our @textbook_fields = qw(title edition author chapter section problem); + +our %tag2field = ( TitleText => "title", EditionText => "edition", +AuthorText => "author", Section => "section", Problem => "problem", ); +our %field2tag = reverse %tag2field; + +=head1 FUNCTIONS + +=head2 read_textbooks + + read_textbooks($fh, $arrayref) + +Reads a Textbooks file opened for reading on $fh and appends its contents to +$arrayref. Each item appended to $arrayref is a reference to a hash containing +the following keys: + + _title The title of the textbook + _edition The edition of the textbook + _author The author of the textbook + 1 The name of chapter 1 + 1.1 The name of section 1.1 + 1.2 The name of section 1.2 + ... + 2 The name of chapter 2 + 2.1 The name of section 2.1 + ... + +Since the number of sections in a textbook is typically small, it is not terribly +inefficient to pull chapters or sections out: + + @chapters = grep { /^\d+$/ } keys %textbook; + @sections = grep { /^\d+\.\d+$/ } keys %textbook; + +=cut + +sub read_textbooks { + my ($fh, $result) = @_; + + my %curr_textbook; + + while (<$fh>) { + s/#.*$//g; + next unless /\S/; + s/^\s*//; + s/\s*$//; + + if (/^(TitleText|EditionText|AuthorText)\(\s*'(.*?)'\s*\)/) { + my $field = $tag2field{$1}; + my $value = $2; + if (exists $curr_textbook{"_$field"}) { + # repeated tag -- this is a new textbook + push @$result, {%curr_textbook}; + %curr_textbook = (); + } + $curr_textbook{"_$field"} = $value; + } elsif (/^(\d+)(?:\.(\d+))?\s*>>>\s*(.*)$/) { + my $chapter = $1; + my $section = $2; + my $name = $3; + if (defined $section and length $section > 0) { + $curr_textbook{"$chapter.$section"} = $name; + } else { + $curr_textbook{$chapter} = $name; + } + } + } + push @$result, {%curr_textbook}; +} + +=head2 read_tags + + read_tags($fh, $hashref, $extra_editing_info); + +Reads the NPL tags from a PG file opened for reading on $fh and stores the tags +in %$hashref. The following keys may be added to %$hashref: + + DESCRIPTION + KEYWORDS + DBsubject + DBchapter + DBsection + Date + Institution + Author + UsesAuxiliaryFiles (experimental, subject to change) + textbooks (arrayref) + +The value for the C<textbooks> key will be a reference to an array of textbook +hashes containing the textbook tags from the source file. In each textbook hash, +entries with empty values (e.g. C<TitleText1('')>) will be omitted. This is to +deal with the large number of empty-valued tags in the NPL. The keys of each +textbook hash will be among: + + title + edition + author + chapter + section + problem (arrayref) + +The value for the C<problem> key will be a reference to an array of problem +numbers. + +If $extra_editing_info is true, special hash items _pos, _rest, and _maxtextbook +will also be added to %$hashref. + +_pos will contain the position of the first byte of the next line after the last +tag in the file. _rest will contain the bytes of the "rest" of the file, after +all tags, starting at _pos. _maxtextbook will contain the highest number used to +identify a textbook in the file. (e.g. If TitleText1 and TitleText3 appear in +the file, there will only be two items in the textbooks array, but _maxtextbook +will be 3.) + +This is useful for appending tags to a file which contains existing tags, where +the new tags should appear immediately after the existing tags: + + open PGFILE, "+<", "file.pg"; + my $tags = {}; + read_tags(\*PGFILE, $tags, 1); + my $pos = $tags{_pos}; + my $rest = $tags{_rest}; + seek PGFILE, $pos, 0; + print PGFILE "## SomeNewTag('foo','bar')\n"; + print PGFILE $rest; + close PGFILE; + +=cut + +sub read_tags { + my ($file, $result, $extra_editing_info) = @_; + + my $fh; + if (ref $file) { + $fh = $file; + } elsif (defined $file and not ref $file) { + $fh = new IO::File($file, 'r'); + } + + my $pos; + my $rest = ''; + my $maxtextbook; + while (<$fh>) { + #if (0) { + if (/^(.*?\#.*?)(\s*)DESCRIPTION/) { + my $prefix = $1; + my $whitespace = $2; + my $description = ''; + while (<$fh>) { + if (/\#.*ENDDESCRIPTION/) { + chomp $description; + $result->{DESCRIPTION} = $description if length $description > 0; + last; + } else { + # handle prefix and whitespace separately so that we can still + # chop the prefix off even if people are being careless about + # whitespace. :P + s/^$prefix//; + s/^$whitespace//; + $description .= $_; + } + } + if ($extra_editing_info) { + $pos = tell $fh; + $rest = ''; + } + } elsif (/\#.*KEYWORDS\((.*)\)/) { + my $keywords = $1; + push @{$result->{KEYWORDS}}, parse_keywords($keywords); + if ($extra_editing_info) { + $pos = tell $fh; + $rest = ''; + } + } elsif (/\#.*(DBsubject|DBchapter|DBsection|Date|Institution|Author)\(\s*(.*?)\s*\)/) { + my $field = $1; + my $value = $2; + my ($parsed_value, $parse_errors) = parse_normal_value($field, $value); + if (@$parse_errors) { + warn "error while parsing value \"$value\" in field $field:\n" + . join('', @$parse_errors) + . "value may be incomplete. use with caution.\n" + . "(line $. of file $file)\n"; + } + $result->{$field} = $parsed_value; + if ($extra_editing_info) { + $pos = tell $fh; + $rest = ''; + } + } elsif (/\#.*(TitleText|EditionText|AuthorText|Section|Problem)(\d+)\(\s*'(.*?)'\s*\)/) { + my $field = $tag2field{$1}; + my $num = $2; + my $value = $3; + next unless $value =~ /\S/; + $value = [ parse_problems($value) ] if $field eq "problem"; + if ($field eq "section") { + my ($ch, $sec) = split /\./, $value; + $result->{textbooks}[$num]{chapter} = $ch; + $result->{textbooks}[$num]{section} = $sec if defined $sec and length $sec > 0; + } else { + $result->{textbooks}[$num]{$field} = $value; + } + if ($extra_editing_info) { + $pos = tell $fh; + $rest = ''; + $maxtextbook = $num if not defined $maxtextbook or $num > $maxtextbook; + } + } elsif (/\#.*(UsesAuxiliaryFiles)\(\s*(.*?)\s*\)/) { + my $field = $1; + my $value = $2; + my ($parsed_value, $parse_errors) = parse_normal_list($field, $value); + if ($parse_errors) { + warn "error while parsing value \"$value\" in field $field:\n" + . join('', @$parse_errors) + . "value may be incomplete. use with caution.\n" + . "(line $. of file $file)\n"; + } + $result->{$field} = $parsed_value; + if ($extra_editing_info) { + $pos = tell $fh; + $rest = ''; + } + } else { + if ($extra_editing_info) { + $rest .= $_; + } + } + } + + # remove holes in textbook numbering + @{$result->{textbooks}} = grep { defined } @{$result->{textbooks}}; + delete $result->{textbooks} unless @{$result->{textbooks}}; + + if ($extra_editing_info) { + $result->{_pos} = $pos; + $result->{_rest} = $rest; + $result->{_maxtextbook} = $maxtextbook; + } +} + +sub parse_normal_list { + my ($name, $string) = @_; + + use constant NRM=>0; + use constant STR=>1; + use constant ESC=>2; + use constant STP=>3; + my $state = NRM; + my @errors; + my @items; + my $curr_item = ''; + my $next_item = 0; + foreach my $i (0 .. length($string)-1) { + my $c = substr($string,$i,1); + #print "i=$i c=$c state=$state curr_item=$curr_item next_item=$next_item\n"; + # state changes + if ($state == NRM) { + if ($c eq "'") { + $state = STR; + } elsif ($c eq ',' or $c eq ' ') { + # do nothing -- closequote already consumed curr_item + } else { + push @errors, + "illegal char '$c' in state NRM while parsing value for $name.\n" + . " $string\n" + . ' ' . ' 'x$i . "^\n"; + $next_item = 1; + $state = STP; + } + } elsif ($state == STR) { + if ($c eq "'") { + $state = NRM; + $next_item = 1; + } elsif ($c eq '\\') { + $state = ESC; + } else { + $curr_item .= $c; + } + } elsif ($state == ESC) { + $curr_item .= $c; + $state = STR; + } elsif ($state == STP) { + last; + } else { + die "unexpected state $state while parsing value for $name.\n"; + } + #print "i=$i c=$c state=$state curr_item=$curr_item next_item=$next_item\n"; + # actions + if ($next_item) { + push @items, $curr_item; + $curr_item = ''; + $next_item = 0; + #print "stored item to list\n"; + } + } + + return \@items, \@errors; +} + +sub parse_normal_value { + my ($name, $string) = @_; + my ($items, $errors) = parse_normal_list($name, $string); + push @$errors, "only one item allowed in value for $name.\n" if @$items > 1; + return shift @$items, $errors; +} + +# this now works for keywords is embedded spaces (which are later stripped out +# by kwtidy) but now it doesn't work for values with double quotes or no quotes! +sub parse_keywords { + my $string = shift; + my ($items, $errors) = parse_normal_list('KEYWORDS', $string); + if (@$errors) { + warn "errors while parsing KEYWORDS list:\n@$errors\n" + . "Partially-parsed KEYWORDS: @$items\n" + . "Resorting to old-style KEYWORDS parsing...\n"; + @$items = split /(?:,|\s)+/, $string; + warn "Old-style parse result: ", join('|', @$items), "\n"; + } + return map { kwtidy($_) } @$items; +} + +sub kwtidy { + my $keyword = shift; + $keyword =~ s/\W//g; + $keyword =~ s/_//g; + return lc $keyword; +} + +sub parse_problems { + my $string = shift; + $string =~ s/\D/ /g; + return grep { /\S/ } split /\s+/, $string; +} + +=head2 format_tags + + format_tags($tags, $mintextbook); + +Given a reference to a hash of tags, return a list of strings representing said +tags. The strings do not begin with the standard NPL comment prefix ("## ") or +end with newlines. These must be added by the caller if the strings are to be +inserted into a PG source file. + +One complication is the DESCRIPTION field, which contains embedded newlines. If +a DESCRIPTION tag occurs in %$tags, it will be formatted with embedded newlines +but without a trailing newline. For example, after this code executes, + + $tags = { DESCRIPTION => "line one\nline two\nline three" }; + ($desc) = format_tags($tags); + +$desc will contain the string: + + "DESCRIPTION\nline one\nline two\nline three\nENDDESCRIPTION" + +To account for this when writing to a PG file, you could use: + + foreach my $string (format_tags($tags)) { + $string =~ s/^/## /gm; + print PGFILE "$string\n"; + } + +=cut + +sub format_tags { + my ($tags, $mintextbook) = @_; + $mintextbook ||= 1; + my @result; + my @ordered_fields = grep { exists $tags->{$_} } @global_fields, "textbooks"; + foreach my $field (@ordered_fields) { + my $value = $tags->{$field}; + if ($field eq "DESCRIPTION") { + push @result, format_description($value); + } elsif ($field eq "textbooks") { + push @result, format_textbooks($value, $mintextbook); + } else { + push @result, format_tag($field, $value); + } + } + return @result; +} + +sub format_tag { + my ($field, $value, $n) = @_; + my $tag = $field2tag{$field} || $field; + + # problems are always listed in a single string in the tag. + if ($field eq "problem") { + $value = format_problems($value); + } + + # if we have an arrayref, we represent it as multiple strings in one tag. + if (ref $value) { + $value = join(',', map { "'$_'" } @$value); + } elsif (defined $value) { + $value = "'$value'"; + } else { + warn "value is not defined for field $field!\n"; + $value = "''"; + } + + if (defined $n) { + return "$tag$n($value)"; + } else { + return "$tag($value)"; + } +} + +sub format_description { + my $value = shift; + return "DESCRIPTION\n$value\nENDDESCRIPTION"; +} + +sub format_textbooks { + my ($textbook, $n) = @_; + my @textbooks = @$textbook; + my @result; + foreach my $textbook (@textbooks) { + push @result, format_textbook($textbook, $n); + $n++; + } + return @result; +} + +sub format_textbook { + my ($textbook, $n) = @_; + + # combine chapter/section into single section tag + my $chapter = $textbook->{chapter}; + my $section = $textbook->{section}; + if (defined $chapter or defined $section) { + $section = ".$section" if defined $section; + $section = "$chapter$section" if defined $chapter; + delete $textbook->{chapter}; + $textbook->{section} = $section; + } + + my @result; + my @ordered_fields = grep { exists $textbook->{$_} } @textbook_fields; + foreach my $field (@ordered_fields) { + my $value = $textbook->{$field}; + push @result, format_tag($field, $value, $n); + } + return @result; +} + +sub format_problems { + my $first = shift; + my @problems; + if (ref $first) { + @problems = @$first; + } else { + @problems = ($first, @_); + } + + return join(',', @problems); +} + +=head2 gen_find_tags + + gen_find_tags($pattern, $action, $extra_editing_info); + +Generates an anonymous subroutine suitable for passing the the find() function +of the File::Find module. The no_chdir=>1 option must be passed to find() for +the generated subroutine to operate properly. + +$pattern is a reference to a hash describing the fields that must match. $action +is a reference to a subroutine that will be called if all fields match. +$extra_editing_info is passed to read_tags(). + +Legal fields for $pattern are as follows: + +B<Global fields:> DESCRIPTION, KEYWORDS, DBsubject, DBchapter, DBsection, Date, +Institution, Author. (The experimental UsesAuxiliaryFiles field may be supported +in the future.) + +B<Text-specific fields:> title, edition, author, chapter, section, problem. + +If multiple text-specific keys are given, then all must match for a single +textbook. + +$action is called as follows: + + $action->($path, $tags, $text_index) + +There $path the path to the matching file, $tags a reference to the tag hash for +the matching file, and $text_index the index into the @{$tags->{textbooks}} array +if $pattern included textbook-specific tags. + +=cut + +sub gen_find_tags { + my ($pattern, $action, $extra_editing_info) = @_; + return sub { + return unless /\.pg$/ and -f $File::Find::name; + + my $name = $File::Find::name; + #my $relpath = $name; + #$relpath =~ s/^$src\///; + + my %tags; + + open my $fh, "<", $name or do { + warn "skipping $name: $!\n"; + return; + }; + read_tags($fh, \%tags, $extra_editing_info); + close $fh; + + my (%global_pattern, %textbook_pattern); + foreach my $field (@global_fields) { + $global_pattern{$field} = $pattern->{$field} if exists $pattern->{$field}; + } + foreach my $field (@textbook_fields) { + $textbook_pattern{$field} = $pattern->{$field} if exists $pattern->{$field}; + } + + if (%global_pattern) { + return unless match_global(\%tags, \%global_pattern); + } + my $text_index; + if (%textbook_pattern) { + $text_index = match_textbook(\%tags, \%textbook_pattern); + return unless $text_index >= 0; + } + + $action->($name, \%tags, $text_index); + }; +} + +sub match_global { + my ($tags, $matches) = @_; + foreach my $field (keys %$matches) { + return 0 unless $tags->{$field} eq $matches->{$field}; + } + return 1; +} + +sub match_textbook { + my ($tags, $matches) = @_; + return -1 unless defined $tags->{textbooks}; + my @textbooks = @{$tags->{textbooks}}; + + #textbook: foreach my $textbook (@{$tags->{textbooks}}) { + textbook: foreach my $i (0 .. $#{$tags->{textbooks}}) { + my $textbook = $tags->{textbooks}[$i]; + foreach my $field (keys %$matches) { + next if $field !~ /^(title|edition|author|chapter|section|problem)$/; + next textbook unless $textbook->{$field} eq $matches->{$field}; + } + #warn "matched text i=$i: ", Dumper($textbook); + return $i; + } + return -1; +} + +=back + +=cut + +1; |
From: jj v. a. <we...@ma...> - 2007-10-16 18:20:12
|
Log Message: ----------- Added more units. Modified Files: -------------- webwork2/htdocs/helpFiles: Units.html Revision Data ------------- Index: Units.html =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/helpFiles/Units.html,v retrieving revision 1.4 retrieving revision 1.5 diff -Lhtdocs/helpFiles/Units.html -Lhtdocs/helpFiles/Units.html -u -r1.4 -r1.5 --- htdocs/helpFiles/Units.html +++ htdocs/helpFiles/Units.html @@ -68,6 +68,12 @@ <tr><td colspan="2" align="center"><b>Misc</b> <tr><td> Amperes <td align="center"> amp +<tr><td> Moles <td align="center"> mol +<tr><td> Degrees Centrigrade <td align="center"> degC +<tr><td> Degrees Fahrenheit <td align="center"> degF +<tr><td> Degrees Kelvin <td align="center"> degK +<tr><td> Angle degrees <td align="center"> deg +<tr><td> Angle radians <td align="center"> rad </table> |
From: jj v. a. <we...@ma...> - 2007-10-16 18:06:42
|
Log Message: ----------- Added amps to units help page. Modified Files: -------------- webwork2/htdocs/helpFiles: Units.html Revision Data ------------- Index: Units.html =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/helpFiles/Units.html,v retrieving revision 1.3 retrieving revision 1.4 diff -Lhtdocs/helpFiles/Units.html -Lhtdocs/helpFiles/Units.html -u -r1.3 -r1.4 --- htdocs/helpFiles/Units.html +++ htdocs/helpFiles/Units.html @@ -66,6 +66,9 @@ <tr><td> electron volts <td align="center"> eV <tr><td> kilo Watt hours <td align="center"> kWh +<tr><td colspan="2" align="center"><b>Misc</b> +<tr><td> Amperes <td align="center"> amp + </table> |
From: Sam H. v. a. <we...@ma...> - 2007-10-15 16:03:15
|
Log Message: ----------- support hints and solutions in the library browser Modified Files: -------------- webwork2/lib/WeBWorK/ContentGenerator/Instructor: SetMaker.pm webwork2/lib/WeBWorK/Utils: Tasks.pm Revision Data ------------- Index: SetMaker.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v retrieving revision 1.80 retrieving revision 1.81 diff -Llib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm -Llib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm -u -r1.80 -r1.81 --- lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm +++ lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm @@ -38,6 +38,8 @@ require WeBWorK::Utils::ListingDB; +use constant SHOW_HINTS_DEFAULT => 0; +use constant SHOW_SOLUTIONS_DEFAULT => 0; use constant MAX_SHOW_DEFAULT => 20; use constant NO_LOCAL_SET_STRING => 'No sets in this course yet'; use constant SELECT_SET_STRING => 'Select a Set from this Course'; @@ -314,6 +316,11 @@ CGI::popup_menu(-name=> 'max_shown', -values=>[5,10,15,20,25,30,50,'All'], -default=> $defaultMax); + # Option of whether to show hints and solutions + my $defaultHints = $r->param('showHints') || SHOW_HINTS_DEFAULT; + $result .= " ".CGI::checkbox(-name=>"showHints",-checked=>$defaultHints,-label=>"Hints"); + my $defaultSolutions = $r->param('showSolutions') || SHOW_SOLUTIONS_DEFAULT; + $result .= " ".CGI::checkbox(-name=>"showSolutions",-checked=>$defaultSolutions,-label=>"Solutions"); return($result); } @@ -1287,11 +1294,17 @@ my @pg_files = @{$self->{pg_files}}; my @all_db_sets = @{$self->{all_db_sets}}; - my @pg_html=($last_shown>=$first_shown) ? - renderProblems(r=> $r, - user => $user, - problem_list => [@pg_files[$first_shown..$last_shown]], - displayMode => $r->param('mydisplayMode')) : (); + my @pg_html; + if ($last_shown >= $first_shown) { + @pg_html = renderProblems( + r=> $r, + user => $user, + problem_list => [@pg_files[$first_shown..$last_shown]], + displayMode => $r->param('mydisplayMode'), + showHints => $r->param('showHints'), + showSolutions => $r->param('showSolutions'), + ); + } my %isInSet; my $setName = $r->param("local_sets"); Index: Tasks.pm =================================================================== RCS file: /webwork/cvs/system/webwork2/lib/WeBWorK/Utils/Tasks.pm,v retrieving revision 1.14 retrieving revision 1.15 diff -Llib/WeBWorK/Utils/Tasks.pm -Llib/WeBWorK/Utils/Tasks.pm -u -r1.14 -r1.15 --- lib/WeBWorK/Utils/Tasks.pm +++ lib/WeBWorK/Utils/Tasks.pm @@ -131,6 +131,8 @@ my $problem_seed = $args{'problem_seed'} || $r->param('problem_seed') || 0; my $displayMode = $args{displayMode} || $r->param("displayMode") || $ce->{pg}->{options}->{displayMode}; + my $showHints = $args{showHints} || 0; + my $showSolutions = $args{showSolutions} || 0; my $problemNumber= $args{'problem_number'} || 1; $ce->{pg}->{specialPGEnvironmentVars}->{problemPreamble} = { TeX=>'', @@ -164,8 +166,8 @@ $formFields, { # translation options displayMode => $displayMode, - showHints => 0, - showSolutions => 0, + showHints => $showHints, + showSolutions => $showSolutions, refreshMath2img => 0, processAnswers => 0, } |
From: Mike G. v. a. <we...@ma...> - 2007-10-11 01:12:33
|
Log Message: ----------- "improved" the help files -- Mike Tags: ---- rel-2-4-dev Modified Files: -------------- webwork-modperl/htdocs/helpFiles: InstructorScoring.html InstructorUserList.html instructor_links.html Revision Data ------------- Index: InstructorUserList.html =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/helpFiles/InstructorUserList.html,v retrieving revision 1.3.4.1 retrieving revision 1.3.4.2 diff -Lhtdocs/helpFiles/InstructorUserList.html -Lhtdocs/helpFiles/InstructorUserList.html -u -r1.3.4.1 -r1.3.4.2 --- htdocs/helpFiles/InstructorUserList.html +++ htdocs/helpFiles/InstructorUserList.html @@ -52,7 +52,7 @@ <dd> Click the "Add x student(s)" radio button and then click "Take action". This will take you to a new page where the data can be entered for one or more students. It is also possible to assign the student to one or more problem sets as they are being entered: simply select the homework sets from the list below the data entry table. Use 'command' or 'control' click to select more than one homework set.</dd> <dt>Add many students to a course from a class list.</dt> - <dd>This is most easily done by importing a class list. The class list can be uploaded from your workstation to the server using the File Manager page. The class list must be a file ending in .lst and must have a specific <a href="http://webhost.math.rochester.edu/webworkdocs/discuss/msgReader$59#2397">format</a>. Once the file has been uploaded to the server the file will appear in the import action pop-up list (5th action). demoCourse.lst is available for most courses and adds the "practice users" which activate guest logins to the class list .</dd> + <dd>This is most easily done by importing a class list. The class list can be uploaded from your workstation to the server using the File Manager page. The class list must be a file ending in .lst and must have a specific <a href="http://devel.webwork.rochester.edu/twiki/bin/view/Webwork/ClasslistFileFormat">format</a>. Once the file has been uploaded to the server the file will appear in the import action pop-up list (5th action). demoCourse.lst is available for most courses and adds the "practice users" which activate guest logins to the class list .</dd> <dt>Add a TA or an instructor (change permission level of user)</dt> <dd>This is done by first entering the user as a student and then changing the permission level of the user. First edit the user by clicking on the pencil next to their name (or using the technique above for several users), then change their permssion level -- an entry blank at the far right of the screen, you may have to scroll to see it. The permission levels are Index: instructor_links.html =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/helpFiles/instructor_links.html,v retrieving revision 1.5.4.1 retrieving revision 1.5.4.2 diff -Lhtdocs/helpFiles/instructor_links.html -Lhtdocs/helpFiles/instructor_links.html -u -r1.5.4.1 -r1.5.4.2 --- htdocs/helpFiles/instructor_links.html +++ htdocs/helpFiles/instructor_links.html @@ -27,9 +27,12 @@ <h3>Instructor Links Help Page</h3> -Click the icon <a href="instructor_links.html"><img src="/webwork2_files/images/question_mark.png"></a> for -page and item specific help. +<hr/> +<b>For help with an item on a specific page</b><br/> +click the <a href="instructor_links.html"><img src="/webwork2_files/images/question_mark.png"></a> icon. + +<hr/> <dl> <dt>Instructor Tools</dt> <dd>Quick access to many instructor tools, including Index: InstructorScoring.html =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/helpFiles/InstructorScoring.html,v retrieving revision 1.2.4.1 retrieving revision 1.2.4.2 diff -Lhtdocs/helpFiles/InstructorScoring.html -Lhtdocs/helpFiles/InstructorScoring.html -u -r1.2.4.1 -r1.2.4.2 --- htdocs/helpFiles/InstructorScoring.html +++ htdocs/helpFiles/InstructorScoring.html @@ -21,8 +21,76 @@ </head> <body><br> -<p>The files created by this page contain all the scoring data in a comma delimited file. This file can easily be opened by a -spreadsheet program. To download the file after it's been created click on the link below, or go to the file transfer page -where scoring files may also be downloaded.</p> + +<p> +WeBWorK does not have a full featured scoring ability -- we leave that to your +favorite spread sheet application. +</p> + +<p> +What WeBWorK does have is good support for summarizing the scores on WeBWorK +homework sets and exporting them in a form (.csv) which any spreadsheet can use. +WeBWorK reports all of the homework grades, +creates a column which totals these grades and leaves it at that. +</p> + +<p> +Click on the sets you want scored (usually all of them :-) ) +choose the name of the export file you want to +use (by default: courseName_totals.csv) and then click the +"score selected sets" button. +</p> + +<p> +If you want a form that is easy to read on the web (for a quick look at grades) +click the "pad fields" option. This adds spaces the fields which makes the +columns easy to read when in text form but it can confuse +some spread sheet applications since the extra spaces violate the csv standard +(although Excel handles them with no problem). If you want a reliable .csv file +for use in any spreadsheet application unclick the "pad fields" option. +You can download the .csv file immediately by clicking on the link, or you +can download it using the "File Manager" from the scoring directory. +</p> + +<p> +I have no clue what "record scores for single sets" does -- sorry. +</p> + +<p> +The index is a number assigned on the basis of the number of incorrect attempts +(roughly equivalent to 1/the number of attempts) which seems to correlate with +the relative difficulty the student had with the problem. +</p> + +<p> +We would all like to be able to merge the spreadsheet with the webwork grades +and a spread sheet with the excel grades automatically. Unfortunately this +application has not yet been written for WeBWorK and for that matter it doesn't +appear to be an ability that Excel has either. The closes I have been able +to find is third party software for excel (e.g. http://www.synkronizer.com/e/tutorial_merging.html) +</p> + +<p> +To use the Email and spreadsheet merge feature, upload your spreadsheet with +calculated grades to the scoring directory using the File Manager link. +</p> + +<p> +Do NOT use the file name courseName_totals.csv, since you might accidentally +overwrite that if you again export your WeBWorK homework scores (actually the +earlier file is moved to courseName_totals_bak1.csv -- so you can recover +using the File Manager -- but it's still a pain). +</p> + +<p> +If you upload your file on the web with the name: <code>report_grades_data.csv</code> +and also create an email message with the name <code>report_grade.msg</code> with the +approriate <code>$COL</code> variables then not only can you email the message +with the embedded grades to the students, but files with those exact names are +automatically appended to the "Grades" page seen by the students. +</p> + + + </body> </html> |
From: jj v. a. <we...@ma...> - 2007-10-08 19:39:22
|
Log Message: ----------- If the system is using mysql to store image depths, we update the database when deleting images. More specifically, we keep a depth in the database iff we kept the image. Modified Files: -------------- webwork2/bin: remove_stale_images Revision Data ------------- Index: remove_stale_images =================================================================== RCS file: /webwork/cvs/system/webwork2/bin/remove_stale_images,v retrieving revision 1.5 retrieving revision 1.6 diff -Lbin/remove_stale_images -Lbin/remove_stale_images -u -r1.5 -r1.6 --- bin/remove_stale_images +++ bin/remove_stale_images @@ -65,6 +65,7 @@ use Getopt::Long; use Pod::Usage; use File::Find; +use DBI; BEGIN { die "WEBWORK_ROOT not found in environment.\n" @@ -87,7 +88,9 @@ my %kept = (); my %days=(); my %week=(); +my %depths=(); my $grandtotal=0; +my $depthConnection; ##### get command-line options ##### @@ -155,6 +158,12 @@ } if($stat[$type]<$start or $stat[$type]>$end) { $kept{$fullmd5} = ''; + if($depthConnection) { # hold dvipng depths + my $fetchdepth = $depthConnection->selectall_arrayref(" + SELECT depth FROM depths WHERE md5=\"$fullmd5\""); + my $fetchdepthval = $fetchdepth->[0]->[0]; + $depths{$fullmd5} = $fetchdepthval if($fetchdepthval); + } } else { my $result = unlink($File::Find::name); if($result) { @@ -211,11 +220,36 @@ my $tmpdir = $ce->{webworkDirs}->{tmp}; my $tmpfile = "$tmpdir/equationcache.tmp"; +# Prepare to handle depths database table +my $alignType = $ce->{pg}->{displayModeOptions}->{images}->{dvipng_align}; +if($alignType eq 'mysql' and $deloption) { + my $dbinfo = $ce->{pg}->{displayModeOptions}->{images}->{dvipng_depth_db}; + $depthConnection = DBI->connect_cached( + $dbinfo->{dbsource}, + $dbinfo->{user}, + $dbinfo->{passwd}, + { PrintError => 0, RaiseError => 1 }, + ); + print "Could not make database connection for dvipng image depths.\n" unless defined $depthConnection; +} + find({wanted => \&wanted, follow_fast => 1}, $dirHead); print "Removed $num_removed images.\n\n" if($deloption); count_report() if($reportoption); + +# For depth database, empty it and insert only values for the images +# we kept. +my $ent; +if($depthConnection) { # clean out database and put back in good values + $depthConnection->do("TRUNCATE depths"); + for my $ent (keys %depths) { + $depthConnection->do("INSERT INTO `depths` VALUES( + \"$ent\", \"$depths{$ent}\")"); + } +} + ## The rest is updating the equation cache if we deleted images and there is a cache exit() unless($deloption and $num_removed); exit() unless ($cachePath); @@ -223,7 +257,6 @@ my ($perms, $uid, $groupID) = (stat $cachePath)[2,4,5]; #Get values from current cache file my $cachevalues = readFile($cachePath); my @cachelines = split "\n", $cachevalues; -my $ent; for $ent (@cachelines) { chomp($ent); my $entmd5 = $ent; @@ -251,4 +284,3 @@ - |
From: Sam H. v. a. <we...@ma...> - 2007-10-04 17:04:59
|
Log Message: ----------- typo Modified Files: -------------- pg/macros: dangerousMacros.pl Revision Data ------------- Index: dangerousMacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/dangerousMacros.pl,v retrieving revision 1.49 retrieving revision 1.50 diff -Lmacros/dangerousMacros.pl -Lmacros/dangerousMacros.pl -u -r1.49 -r1.50 --- macros/dangerousMacros.pl +++ macros/dangerousMacros.pl @@ -30,7 +30,7 @@ =head1 DESCRIPTION -dangerousMacros.pl contains macros that use potentially dangerous functions line +dangerousMacros.pl contains macros that use potentially dangerous functions like require and eval. They can reference disk files for reading and writing, create links, and execute commands. It may be necessary to modify certain addresses in this file to make the scripts run properly in different environments. |
From: Sam H. v. a. <we...@ma...> - 2007-10-04 16:48:38
|
Log Message: ----------- documentation cleanup Modified Files: -------------- pg/macros: dangerousMacros.pl displayMacros.pl Revision Data ------------- Index: dangerousMacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/dangerousMacros.pl,v retrieving revision 1.48 retrieving revision 1.49 diff -Lmacros/dangerousMacros.pl -Lmacros/dangerousMacros.pl -u -r1.48 -r1.49 --- macros/dangerousMacros.pl +++ macros/dangerousMacros.pl @@ -1,84 +1,84 @@ - - - -#################################################################### -# Copyright @ 1995-1999 University of Rochester -# All Rights Reserved -#################################################################### - -#################################################################### -# -# dangerousMacros.pl contains macros with potentially dangerous commands -# such as require and eval. They can reference disk files for reading and -# writing and can create links. It may be necessary to modify certain addresses -# in this file to make the scripts run in different environments. -# -# +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ =head1 NAME - dangerousMacros.pl --- located in the courseScripts directory +dangerousMacros.pl - Macros which require elevated permissions to execute. =head1 SYNPOSIS loadMacros(macrofile1,macrofile2,...) - - insertGraph(graphObject); - returns a path to the file containing the graph image. - - tth(texString) - returns an HTML version of the tex code passed to it. - - alias(pathToFile); - returns URL which links to that file - + + insertGraph(graphObject); # returns a path to the file containing the graph image. + + tth(texString); # returns an HTML version of the tex code passed to it. + + alias(pathToFile); # returns URL which links to that file =head1 DESCRIPTION +dangerousMacros.pl contains macros that use potentially dangerous functions line +require and eval. They can reference disk files for reading and writing, create +links, and execute commands. It may be necessary to modify certain addresses in +this file to make the scripts run properly in different environments. -C<dangerousMacros.pl> contains macros with potentially dangerous commands -such as require and eval. They can reference disk files for reading and -writing and can create links. It may be necessary to modify certain addresses -in this file to make the scripts run properly in different environments. +This file is loaded implicitly every time a new problem is rendered. -C<dangerousMacros.pl> is loaded and reinitialized -every time a new problem is rendered. +=for comment -=cut +FIXME this information belongs in global.conf where modules to load are listed. +I don't see why this shows up here. + +=head2 Sharing modules +Most modules are loaded by dangerousMacros.pl -######## Dangerous macros######### -## The macros in this file are defined while the safe compartment is wide open. -## Be careful! -######################################### +The modules must be loaded using require (not use) since the +courseScriptsDirectory is defined at run time. +The following considerations come into play. -=head2 Sharing modules: +=over -Most modules are loaded by dangerousMacros.pl +=item * -The modules must be loaded using require (not use) since the courseScriptsDirectory is -defined at run time. +One needs to limit the access to modules for safety -- hence only modules in the +F<courseScriptsDirectory> can be loaded. +=item * - The following considerations come into play. +Loading them in dangerousMacros.pl is wasteful, since the modules would need to +be reloaded everytime a new safe compartment is created. (I believe that using +require takes care of this.) - * One needs to limit the access to modules for safety -- hence only - modules in the F<courseScriptsDirectory> can be loaded. +=item * - * Loading them in dangerousMacros.pl is wasteful, since the modules - would need to be reloaded everytime a new safe compartment is created. - (I believe that using require takes care of this.) +Loading GD within a safeCompartment creates infinite recurrsion in AUTOLOAD +(probably a bug) hence this module is loaded by translate.pl and then shared +with the safe compartment. - * Loading GD within a safeCompartment creates infinite recurrsion in AUTOLOAD (probably a bug) - hence this module is loaded by translate.pl and then shared with - the safe compartment. +=item * - * Other modules loaded by translate.pl are C<Exporter> and C<DynaLoader. +Other modules loaded by translate.pl are C<Exporter> and C<DynaLoader>. - * PGrandom is loaded by F<PG.pl> , since it is needed there. +=item * +PGrandom is loaded by F<PG.pl>, since it is needed there. +=back The module name spaces loaded in dangerousMacros are: @@ -88,7 +88,7 @@ Label Circle -in addition the subroutine &evaluate_units is shared from the module Units. +in addition the subroutine &evaluate_units is shared from the module Units. =cut @@ -145,37 +145,49 @@ =head2 loadMacros -C<loadMacros(macrofile1,macrofile2,...)> + loadMacros(@macroFiles) -loadMacros takes a list of file names and evaluates the contents of each file. This is used to load macros -which define and augment the PG language. The macro files are searched for in the directories specified by -C<($macrosPath)>, which by default is the course macros directory followed by WeBWorK's pg/macros directory. -The latter is where the default behaviour of the PG language is defined. The default path is set in -the C<(global.conf)> file. - -An individual course can modify the PG language, B<for that course only>, by -duplicating one of the macro files in the courseScripts directory and placing this -file in the macro directory for the course. The new file in the course -macro directory will now be used instead of the file in the courseScripts directory. - -The new file in the course macro directory can by modified by adding macros or modifying existing macros. - -I< Modifying macros is for users with some experience.> - -Modifying existing macros might break other standard macros or problems which depend on the -unmodified behavior of these macors so do this with great caution. -In addition problems which use new macros defined in these files or which depend on the -modified behavior of existing macros will not work in other courses unless the macros are also -transferred to the new course. It helps to document the problems by indicating any special macros -which the problems require. +loadMacros takes a list of file names and evaluates the contents of each file. +This is used to load macros which define and augment the PG language. The macro +files are searched for in the directories specified by the array referenced by +$macrosPath, which by default is the current course's macros directory followed +by WeBWorK's pg/macros directory. The latter is where the default behaviour of +the PG language is defined. The default path is set in the global.conf file. + +Macro files named PG.pl, IO.pl, or dangerousMacros.pl will be loaded with no +opcode restrictions, hence any code in those files will be able to execute +privileged operations. This is true no matter which macro directory the file is +in. For example, if $macrosPath contains the path to a problem library macros +directory which contains a PG.pl file, this file will be loaded and allowed to +engage in privileged behavior. + +=head3 Overloading macro files + +An individual course can modify the PG language, for that course only, by +duplicating one of the macro files in the system-wide macros directory and +placing this file in the macros directory for the course. The new file in the +course's macros directory will now be used instead of the file in the +system-wide macros directory. + +The new file in the course macros directory can by modified by adding macros or +modifying existing macros. + +=head3 Modifying existing macros + +I<Modifying macros is for users with some experience.> + +Modifying existing macros might break other standard macros or problems which +depend on the unmodified behavior of these macors so do this with great caution. +In addition problems which use new macros defined in these files or which depend +on the modified behavior of existing macros will not work in other courses +unless the macros are also transferred to the new course. It helps to document +the problems by indicating any special macros which the problems require. -There is no facility for modifying or overloading a single macro. The entire file containing the macro -must be overloaded. +There is no facility for modifying or overloading a single macro. The entire +file containing the macro must be overloaded. Modifications to files in the course macros directory affect only that course, -they will not interfere with the normal behavior of B<WeBWorK> in other courses. - - +they will not interfere with the normal behavior of WeBWorK in other courses. =cut @@ -373,32 +385,20 @@ =head2 insertGraph - $filePath = insertGraph(graphObject); - returns a path to the file containing the graph image. - -insertGraph(graphObject) writes a gif file to the C<html/tmp/gif> directory of the current course. -The file name -is obtained from the graphObject. Warnings are issued if errors occur while writing to -the file. - -The permissions and ownership of the file are controlled by C<$main::tmp_file_permission> -and C<$main::numericalGroupID>. - -B<Returns:> A string containing the full path to the temporary file containing the GIF image. - + # returns a path to the file containing the graph image. + $filePath = insertGraph($graphObject); +insertGraph writes a GIF or PNG image file to the gif subdirectory of the +current course's HTML temp directory. The file name is obtained from the graph +object. Warnings are issued if errors occur while writing to the file. -InsertGraph draws the object $graph, stores it in "${tempDirectory}gif/$gifName.gif (or .png)" where -the $imageName is obtained from the graph object. ConvertPath and surePathToTmpFile are used to insure -that the correct directory separators are used for the platform and that the necessary directories -are created if they are not already present. +Returns a string containing the full path to the temporary file containing the +image. This is most often used in the construct -The directory address to the file is the result. This is most often used in the construct + TEXT(alias(insertGraph($graph))); - TEXT(alias(insertGraph($graph)) ); - -where alias converts the directory address to a URL when serving HTML pages and insures that -an eps file is generated when creating TeX code for downloading. +where alias converts the directory address to a URL when serving HTML pages and +insures that an EPS file is generated when creating TeX code for downloading. =cut @@ -434,43 +434,34 @@ $filePath; } +=head2 [DEPRECATED] tth + # returns an HTML version of the TeX code passed to it. + tth($texString); -=head2 tth - - tth(texString) - returns an HTML version of the tex code passed to it. - -This macro sends the texString to the filter program C<tth> created by Ian Hutchinson. -The tth program was created by Ian Hutchinson and is freely available -for B<non-commerical purposes> at the C<tth> main site: C<http://hutchinson.belmont.ma.us/tth/>. - -The purpose of C<tth> is to translate text in the TeX or Latex markup language into -HTML markup as best as possible. Some symbols, such as square root symbols are not -translated completely. Macintosh users must use the "MacRoman" encoding (available in 4.0 and -higher browsers) in order to view the symbols correctly. WeBWorK attempts to force Macintosh -browsers to use this encoding when such a browser is detected. - -The contents of the file C<tthPreamble.tex> in the courses template directory are prepended -to each string. This allows one to define TeX macros which can be used in every problem. -Currently there is no default C<tthPreamble.tex> file, so if the file is not present in the -course template directory no TeX macro definitions are prepended. C<tth> already understands most -Latex commands, but will not, in general know I<AMS-Latex> commands. Additional information -on C<tth> is available at the C<tth> main site. +This macro sends $texString to the filter program TtH, a TeX to HTML translator +written by Ian Hutchinson. TtH is available free of change non-commerical +use at L<http://hutchinson.belmont.ma.us/tth/>. + +The purpose of TtH is to translate text in the TeX or LaTeX markup language into +HTML markup as best as possible. Some symbols, such as square root symbols are +not translated completely. Macintosh users must use the "MacRoman" encoding +(available in 4.0 and higher browsers) in order to view the symbols correctly. +WeBWorK attempts to force Macintosh browsers to use this encoding when such a +browser is detected. + +The contents of the file F<tthPreamble.tex> in the courses template directory +are prepended to each string. This allows one to define TeX macros which can be +used in every problem. Currently there is no default F<tthPreamble.tex> file, so +if the file is not present in the course template directory no TeX macro +definitions are prepended. TtH already understands most LaTeX commands, but will +not in general know AMS-LaTeX commands. This macro contains code which is system dependent and may need to be modified to run on different systems. -=for html -The link to <CODE>tth</CODE> for <STRONG>non-commerical</STRONG> is -<A HREF="http://hutchinson.belmont.ma.us/tth/">http://hutchinson.belmont.ma.us/tth/</A>. -Binaries for many operating systems are available as well as the source code. Links -describing how to obtain <CODE>tth</CODE> for commerical use are also available on this page. - =cut - - # This file allows the tth display. # Global variables: # ${main::templateDirectory}tthPreamble.tex # location of any preamble TeX commands for tth @@ -576,9 +567,12 @@ # ----- ----- ----- ----- -=head2 math2img +=head2 [DEPRECATED] math2img + + # returns an IMG tag pointing to an image version of the supplied TeX + math2img($texString); -math2img(texString) - returns an IMG tag pointing to an image version of the supplied TeX +This macro was used by the HTML_img display mode, which no longer exists. =cut @@ -621,6 +615,13 @@ } }; +=head2 [DEPRECATED] dvipng + + dvipng($working_directory, $latex_path, $dvipng_path, $tex_string, $target_path) + +This macro was used by the HTML_img display mode, which no longer exists. + +=cut # copied from IO.pm for backward compatibility with WeBWorK1.8; sub dvipng($$$$$) { @@ -705,106 +706,93 @@ =head2 alias - alias(pathToFile); - returns A string describing the URL which links to GIF or html file - (in HTML and Latex2HTML modes). - or a path to the appropriate eps version of a GIF file - (TeX Mode) - - - -C<alias> allows you to refer to auxiliary files which are in a directory along with -the problem definition. In addition alias creates an eps copy of GIF files when -downloading hard copy (TeX mode). - -As a rule auxiliary files that are used by -a number of problems in a course should be placed in C<html/gif> or C<html> -or in a subdirectory of the C<html> directory, -while auxiliary files which are used in only one problem should be placed in -the same directory as the problem in order to make the problem more portable. - - - -=over 4 - -=item Files in the html subdirectory - -B<When not in TeX mode:> - -If the file lies under the C<html> subdirectory, then the approriate URL for the file is created. -Since the C<html> subdirectory is already accessible to the webserver no other changes need to be made. -The file path for this type of file should be the complete file path. The path should -start with the prefix defined in $Global:htmlDirectory. - -B<When in TeX mode:> - - -GIF files will be translated into an eps file (using system dependent code) -and placed in the directory C<tmp/eps>. The full path to this file is returned -for use by TeX in producing the hard copy. (This should work even in a chrooted -environment.) in producing the hard copy. (This should work even in a chrooted -environment.) - -The conversion is done by a system dependent script -called C<gif2eps> which should be in the scripts directory + # In HTML modes, returns the URL of a web-friendly version of the specified file. + # In TeX mode, returns the path to a TeX-friendly version of the specified file. + alias($pathToFile); + +alias allows you to refer to auxiliary files which are in a directory along with +the problem definition. In addition alias creates an EPS version of GIF or PNG +files when called in TeX mode. + +As a rule auxiliary files that are used by a number of problems in a course +should be placed in C<html/gif> or C<html> or in a subdirectory of the C<html> +directory, while auxiliary files which are used in only one problem should be +placed in the same directory as the problem in order to make the problem more +portable. + +=head3 Specific behavior of the alias macro + +=head4 Files in the html subdirectory + +=over + +=item When not in TeX mode + +If the file lies under the F<html> subdirectory, then the approriate URL for the +file is returned. Since the F<html> subdirectory is already accessible to the +webserver no other changes need to be made. The file path for this type of file +should be the complete file path. The path should start with the prefix defined +in $courseDirs{html_temp} in global.conf. + +=item When in TeX mode + +GIF and PNG files will be translated into EPS files and placed in the directory +F<tmp/eps>. The full path to this file is returned for use by TeX in producing +the hard copy. The conversion is done by a system dependent commands defined in +F<global.conf> $externalPrograms{gif2eps} (for GIF images) or +$externalPrograms{png2eps} (for PNG images). The URLs for the other files are +produced as in non-TeX mode but will of course not be usable to TeX. -The URL's for the other files are produced as in non-tex mode -but will of course not be active. - -=item Files in the tmp subdirectory - -B<When not in TeX mode:> +=back -If the file lies under the C<tmp> subdirectory, then the approriate URL for the file is created. -Since the C<tmp> subdirectory is already accessible to the webserver no other changes need to be made. -The file path for this type of file should be the complete file path. The path should -start with the prefix defined in $Global:tempDirectory. +=head4 Files in the tmp subdirectory -B<When in TeX mode:> +=over +=item When not in TeX mode -GIF files will be translated into an eps file (using system dependent code) -and placed in the directory C<tmp/eps>. The full path to this file is returned -for use by TeX in producing the hard copy. (This should work even in a chrooted -environment.) +If the file lies under the F<tmp> subdirectory, then the approriate URL for the +file is created. Since the F<tmp> subdirectory is already accessible to the +webserver no other changes need to be made. The file path for this type of file +should be the complete file path. The path should start with the prefix defined +in $courseDirs{html_temp} in global.conf. + +=item When in TeX mode + +GIF and PNG files will be translated into EPS files and placed in the directory +F<tmp/eps>. The full path to this file is returned for use by TeX in producing +the hard copy. The conversion is done by a system dependent commands defined in +F<global.conf> $externalPrograms{gif2eps} (for GIF images) or +$externalPrograms{png2eps} (for PNG images). The URLs for the other files are +produced as in non-TeX mode but will of course not be usable to TeX. -The conversion is done by a system dependent script -called C<gif2eps> which should be in the scripts directory +=back -The URL's for the other files are produced as in non-tex mode -but will of course not be active. +=head4 Files in the course template subdirectory -=item Files in the course template subdirectory: +=over -B<When not in TeX mode:> +=item When not in TeX mode -If the file lies under the course templates subdirectory, -it is assumed to lie in subdirectory rooted in the directory -containing the problem template file. -An alias is created under the C<html/tmp/gif> or -C<html/tmp/html> directory and linked to the original file. -The file path for this type of file is a relative +If the file lies under the course templates subdirectory, it is assumed to lie +in subdirectory rooted in the directory containing the problem template file. An +alias is created under the F<html/tmp/gif> or F<html/tmp/html> directory and +linked to the original file. The file path for this type of file is a relative path rooted at the directory containing the problem template file. -B<When in TeX mode:> +=item When in TeX mode -GIF files will be translated into an eps file (using system dependent code) -and placed in the directory C<html/tmp/eps>. The full path to this file is returned -for use by TeX in producing the hard copy. (This should work even in a chrooted -environment.) - -The conversion is done by a system dependent script -called C<gif2eps> which should be in the scripts directory - -The URL's for the other files are produced as in non-tex mode -but will of course not be active. +GIF and PNG files will be translated into EPS files and placed in the directory +F<tmp/eps>. The full path to this file is returned for use by TeX in producing +the hard copy. The conversion is done by a system dependent commands defined in +F<global.conf> $externalPrograms{gif2eps} (for GIF images) or +$externalPrograms{png2eps} (for PNG images). The URLs for the other files are +produced as in non-TeX mode but will of course not be usable to TeX. =back =cut - - # Currently gif, html and types are supported. # # If the auxiliary file path has not extension then the extension .gif isassumed. @@ -857,23 +845,6 @@ # local constants $User, $psvn $setNumber $probNum $displayMode -sub sourceAlias { - my $path_to_file = shift; - my $envir = PG_restricted_eval(q!\%main::envir!); - my $user = $envir->{inputs_ref}->{user}; - $user = " " unless defined($user); - my $out = 'source.pl?probSetKey=' . $envir->{psvn}. - '&probNum=' . $envir->{probNum} . - '&Mode=' . $envir->{displayMode} . - '&course=' . $envir->{courseName} . - '&user=' . $user . - '&displayPath=' . $path_to_file . - '&key=' . $envir->{sessionKey}; - - $out; -} - - sub alias { # input is a path to the original auxiliary file my $envir = eval(q!\%main::envir!); # get the current root environment @@ -1261,6 +1232,31 @@ return $adr_output; } +=head2 sourceAlias + + sourceAlias($path_to_PG_file); + +Returns a relative URL to the F<source.pl> script, which may be installed in a +course's F<html> directory to allow formatted viewing of the problem source. + +=cut + +sub sourceAlias { + my $path_to_file = shift; + my $envir = PG_restricted_eval(q!\%main::envir!); + my $user = $envir->{inputs_ref}->{user}; + $user = " " unless defined($user); + my $out = 'source.pl?probSetKey=' . $envir->{psvn}. + '&probNum=' . $envir->{probNum} . + '&Mode=' . $envir->{displayMode} . + '&course=' . $envir->{courseName} . + '&user=' . $user . + '&displayPath=' . $path_to_file . + '&key=' . $envir->{sessionKey}; + + $out; +} + # # Some constants that can be used in perl experssions @@ -1271,16 +1267,19 @@ if (!eval(q!$main::_parser_loaded!)) {return Complex::i} return Value->Package("Formula")->new('i')->eval; } + sub j () { if (!eval(q!$main::_parser_loaded!)) {return 'j'} Value->Package("Formula")->new('j')->eval; } + sub k () { if (!eval(q!$main::_parser_loaded!)) {return 'k'} Value->Package("Formula")->new('k')->eval; } sub pi () {Value->Package("Formula")->new('pi')->eval} + sub Infinity () {Value->Package("Infinity")->new()} -1; # required to load properly +1; Index: displayMacros.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/displayMacros.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/displayMacros.pl -Lmacros/displayMacros.pl -u -r1.8 -r1.9 --- macros/displayMacros.pl +++ macros/displayMacros.pl @@ -1,6 +1,24 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ +=head1 NAME -=head1 displayMacros.pl +displayMacros.pl - [DEPRECATED] WeBWorK 1.x display macros. + +=head1 DESCRIPTION This file is used with WeBWorK 1.9 and is not used for WeBWorK 2.x. |
From: Sam H. v. a. <we...@ma...> - 2007-10-04 16:48:17
|
Log Message: ----------- added standard copyright/license header Modified Files: -------------- pg/macros: answerComposition.pl answerCustom.pl answerHints.pl answerVariableList.pl contextABCD.pl contextCurrency.pl contextInequalities.pl contextIntegerFunctions.pl contextLimitedComplex.pl contextLimitedNumeric.pl contextLimitedPoint.pl contextLimitedPolynomial.pl contextLimitedPowers.pl contextLimitedVector.pl contextPeriodic.pl contextPiecewiseFunction.pl contextScientificNotation.pl contextString.pl contextTF.pl parserAutoStrings.pl parserCustomization.pl parserDifferenceQuotient.pl parserFormulaUpToConstant.pl parserFormulaWithUnits.pl parserFunction.pl parserImplicitEquation.pl parserImplicitPlane.pl parserMultiAnswer.pl parserMultiPart.pl parserNumberWithUnits.pl parserParametricLine.pl parserPopUp.pl parserRadioButtons.pl parserSolutionFor.pl parserVectorUtils.pl problemPreserveAnswers.pl problemRandomize.pl Revision Data ------------- Index: parserParametricLine.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserParametricLine.pl,v retrieving revision 1.15 retrieving revision 1.16 diff -Lmacros/parserParametricLine.pl -Lmacros/parserParametricLine.pl -u -r1.15 -r1.16 --- macros/parserParametricLine.pl +++ macros/parserParametricLine.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserParametricLine.pl - Implements Formulas that represent parametric lines. Index: contextLimitedPoint.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPoint.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/contextLimitedPoint.pl -Lmacros/contextLimitedPoint.pl -u -r1.12 -r1.13 --- macros/contextLimitedPoint.pl +++ macros/contextLimitedPoint.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextLimitedPoint.pl - Allow point entry but no point operations. Index: contextString.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextString.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lmacros/contextString.pl -Lmacros/contextString.pl -u -r1.13 -r1.14 --- macros/contextString.pl +++ macros/contextString.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextString.pl - Allow string-valued answers. Index: parserImplicitPlane.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserImplicitPlane.pl,v retrieving revision 1.18 retrieving revision 1.19 diff -Lmacros/parserImplicitPlane.pl -Lmacros/parserImplicitPlane.pl -u -r1.18 -r1.19 --- macros/parserImplicitPlane.pl +++ macros/parserImplicitPlane.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserImplicitPlane.pl - Implement implicit planes. Index: contextLimitedVector.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedVector.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextLimitedVector.pl -Lmacros/contextLimitedVector.pl -u -r1.11 -r1.12 --- macros/contextLimitedVector.pl +++ macros/contextLimitedVector.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextLimitedVector.pl - Allow vector entry but now vector operations. Index: parserNumberWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserNumberWithUnits.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/parserNumberWithUnits.pl -Lmacros/parserNumberWithUnits.pl -u -r1.8 -r1.9 --- macros/parserNumberWithUnits.pl +++ macros/parserNumberWithUnits.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserNumberWithUnits.pl - Implements a number with units. Index: contextLimitedComplex.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedComplex.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextLimitedComplex.pl -Lmacros/contextLimitedComplex.pl -u -r1.11 -r1.12 --- macros/contextLimitedComplex.pl +++ macros/contextLimitedComplex.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextLimitedComplex.pl - Allow complex numbers but not complex operations. Index: contextCurrency.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextCurrency.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/contextCurrency.pl -Lmacros/contextCurrency.pl -u -r1.12 -r1.13 --- macros/contextCurrency.pl +++ macros/contextCurrency.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextCurrency.pl - Context for entering numbers with currency symbols and Index: contextABCD.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextABCD.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/contextABCD.pl -Lmacros/contextABCD.pl -u -r1.12 -r1.13 --- macros/contextABCD.pl +++ macros/contextABCD.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextABCD.pl - Contexts for matching problems. Index: parserMultiPart.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserMultiPart.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/parserMultiPart.pl -Lmacros/parserMultiPart.pl -u -r1.11 -r1.12 --- macros/parserMultiPart.pl +++ macros/parserMultiPart.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserMultiPart.pl - [DEPRECATED] Renamed to MultiAnswer. Index: answerHints.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerHints.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/answerHints.pl -Lmacros/answerHints.pl -u -r1.5 -r1.6 --- macros/answerHints.pl +++ macros/answerHints.pl @@ -1,4 +1,18 @@ -sub _answerHints_init {} +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ =head1 AnswerHints() @@ -88,6 +102,8 @@ =cut +sub _answerHints_init {} + sub AnswerHints { return (sub { my $ans = shift; $ans->{_filter_name} = "Answer Hints Post Filter"; Index: contextLimitedPowers.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPowers.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/contextLimitedPowers.pl -Lmacros/contextLimitedPowers.pl -u -r1.12 -r1.13 --- macros/contextLimitedPowers.pl +++ macros/contextLimitedPowers.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextLimitedPowers.pl - Restrict the base or power allowed in exponentials. Index: contextTF.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextTF.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lmacros/contextTF.pl -Lmacros/contextTF.pl -u -r1.13 -r1.14 --- macros/contextTF.pl +++ macros/contextTF.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextTF.pl - Imlements contexts for true/false problems. Index: parserAutoStrings.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserAutoStrings.pl,v retrieving revision 1.3 retrieving revision 1.4 diff -Lmacros/parserAutoStrings.pl -Lmacros/parserAutoStrings.pl -u -r1.3 -r1.4 --- macros/parserAutoStrings.pl +++ macros/parserAutoStrings.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserAutoStrings.pl - Force String() to accpet any string. Index: parserFormulaUpToConstant.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFormulaUpToConstant.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/parserFormulaUpToConstant.pl -Lmacros/parserFormulaUpToConstant.pl -u -r1.9 -r1.10 --- macros/parserFormulaUpToConstant.pl +++ macros/parserFormulaUpToConstant.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserFormulaUpToConstant.pl - implements formulas "plus a constant". Index: parserImplicitEquation.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserImplicitEquation.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/parserImplicitEquation.pl -Lmacros/parserImplicitEquation.pl -u -r1.11 -r1.12 --- macros/parserImplicitEquation.pl +++ macros/parserImplicitEquation.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserImplicitEquation.pl - An answer checker for implicit equations. Index: problemPreserveAnswers.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/problemPreserveAnswers.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/problemPreserveAnswers.pl -Lmacros/problemPreserveAnswers.pl -u -r1.5 -r1.6 --- macros/problemPreserveAnswers.pl +++ macros/problemPreserveAnswers.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME problemPreserveAnswers.pl - Allow sticky answers to preserve special characters. Index: contextLimitedNumeric.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedNumeric.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/contextLimitedNumeric.pl -Lmacros/contextLimitedNumeric.pl -u -r1.9 -r1.10 --- macros/contextLimitedNumeric.pl +++ macros/contextLimitedNumeric.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextLimitedNumeric.pl - Allows numeric entry but no operations. Index: parserCustomization.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserCustomization.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/parserCustomization.pl -Lmacros/parserCustomization.pl -u -r1.6 -r1.7 --- macros/parserCustomization.pl +++ macros/parserCustomization.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserCustomization.pl - Placeholder for site/course-local customization file. Index: parserVectorUtils.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserVectorUtils.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/parserVectorUtils.pl -Lmacros/parserVectorUtils.pl -u -r1.7 -r1.8 --- macros/parserVectorUtils.pl +++ macros/parserVectorUtils.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserVectorUtils.pl - Utility macros that are useful in vector problems. Index: parserDifferenceQuotient.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserDifferenceQuotient.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lmacros/parserDifferenceQuotient.pl -Lmacros/parserDifferenceQuotient.pl -u -r1.13 -r1.14 --- macros/parserDifferenceQuotient.pl +++ macros/parserDifferenceQuotient.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserDifferenceQuotient.pl - An answer checker for difference quotients. Index: parserFormulaWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFormulaWithUnits.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/parserFormulaWithUnits.pl -Lmacros/parserFormulaWithUnits.pl -u -r1.10 -r1.11 --- macros/parserFormulaWithUnits.pl +++ macros/parserFormulaWithUnits.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserFormulaWithUnits.pl - Implements a formula with units. Index: answerVariableList.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerVariableList.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/answerVariableList.pl -Lmacros/answerVariableList.pl -u -r1.11 -r1.12 --- macros/answerVariableList.pl +++ macros/answerVariableList.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME answerVariableList.pl - Creates answer checkers that compare the student's Index: answerComposition.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerComposition.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/answerComposition.pl -Lmacros/answerComposition.pl -u -r1.6 -r1.7 --- macros/answerComposition.pl +++ macros/answerComposition.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME answerComposition.pl - An answer checker that determines if two functions Index: contextPeriodic.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPeriodic.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextPeriodic.pl -Lmacros/contextPeriodic.pl -u -r1.11 -r1.12 --- macros/contextPeriodic.pl +++ macros/contextPeriodic.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextPeriodic.pl - [DEPRECATED] Features added to Real and Complex Index: contextPiecewiseFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPiecewiseFunction.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/contextPiecewiseFunction.pl -Lmacros/contextPiecewiseFunction.pl -u -r1.6 -r1.7 --- macros/contextPiecewiseFunction.pl +++ macros/contextPiecewiseFunction.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextPiecewiseFunction.pl - Allow usage of piecewise functions. Index: contextInequalities.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextInequalities.pl,v retrieving revision 1.15 retrieving revision 1.16 diff -Lmacros/contextInequalities.pl -Lmacros/contextInequalities.pl -u -r1.15 -r1.16 --- macros/contextInequalities.pl +++ macros/contextInequalities.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME Context("Inequalities"), Context("Inequalities-Only") - Provides contexts that Index: parserMultiAnswer.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserMultiAnswer.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/parserMultiAnswer.pl -Lmacros/parserMultiAnswer.pl -u -r1.8 -r1.9 --- macros/parserMultiAnswer.pl +++ macros/parserMultiAnswer.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserMultiAnswer.pl - Tie several blanks to a single answer checker. Index: contextScientificNotation.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextScientificNotation.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/contextScientificNotation.pl -Lmacros/contextScientificNotation.pl -u -r1.9 -r1.10 --- macros/contextScientificNotation.pl +++ macros/contextScientificNotation.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextScientificNotation.pl - Allows entry of scientific notation. Index: parserRadioButtons.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserRadioButtons.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/parserRadioButtons.pl -Lmacros/parserRadioButtons.pl -u -r1.9 -r1.10 --- macros/parserRadioButtons.pl +++ macros/parserRadioButtons.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserRadioButtons.pl - Radio buttons compatible with Value objects, specifically MultiAnswer objects. Index: problemRandomize.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/problemRandomize.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/problemRandomize.pl -Lmacros/problemRandomize.pl -u -r1.10 -r1.11 --- macros/problemRandomize.pl +++ macros/problemRandomize.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME problemRandomize.pl - Reseed a problem so that students can do additional versions for Index: contextIntegerFunctions.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextIntegerFunctions.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextIntegerFunctions.pl -Lmacros/contextIntegerFunctions.pl -u -r1.10 -r1.11 --- macros/contextIntegerFunctions.pl +++ macros/contextIntegerFunctions.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextIntegerFunctions.pl - adds integer related functions C(n,r) and P(n,r). Index: parserFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFunction.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/parserFunction.pl -Lmacros/parserFunction.pl -u -r1.11 -r1.12 --- macros/parserFunction.pl +++ macros/parserFunction.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserFunction.pl - An easy way of adding new functions to the current context. Index: contextLimitedPolynomial.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPolynomial.pl,v retrieving revision 1.16 retrieving revision 1.17 diff -Lmacros/contextLimitedPolynomial.pl -Lmacros/contextLimitedPolynomial.pl -u -r1.16 -r1.17 --- macros/contextLimitedPolynomial.pl +++ macros/contextLimitedPolynomial.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME contextLimitedPolynomial.pl - Allow only entry of polynomials. Index: parserPopUp.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserPopUp.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/parserPopUp.pl -Lmacros/parserPopUp.pl -u -r1.6 -r1.7 --- macros/parserPopUp.pl +++ macros/parserPopUp.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserPopUp.pl - Pop-up menus compatible with Value objects. Index: parserSolutionFor.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserSolutionFor.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/parserSolutionFor.pl -Lmacros/parserSolutionFor.pl -u -r1.7 -r1.8 --- macros/parserSolutionFor.pl +++ macros/parserSolutionFor.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME parserSolutionFor.pl - An answer checker that checks if a student's answer Index: answerCustom.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerCustom.pl,v retrieving revision 1.15 retrieving revision 1.16 diff -Lmacros/answerCustom.pl -Lmacros/answerCustom.pl -u -r1.15 -r1.16 --- macros/answerCustom.pl +++ macros/answerCustom.pl @@ -1,3 +1,19 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader$ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + =head1 NAME answerCustom.pl - An easy method for creating answer checkers with a custom |
From: Sam H. v. a. <we...@ma...> - 2007-10-03 20:36:33
|
Log Message: ----------- fixed some POD errors, indentation Modified Files: -------------- pg/macros: answerComposition.pl answerCustom.pl answerHints.pl parserFormulaWithUnits.pl parserFunction.pl parserParametricLine.pl Revision Data ------------- Index: parserFormulaWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFormulaWithUnits.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/parserFormulaWithUnits.pl -Lmacros/parserFormulaWithUnits.pl -u -r1.8 -r1.9 --- macros/parserFormulaWithUnits.pl +++ macros/parserFormulaWithUnits.pl @@ -14,11 +14,11 @@ Usage examples: - ANS(FormulaWithUnits("3x+1 ft")->cmp); - ANS(FormulaWithUnits("$a*x+1 ft")->cmp); - - $x = Formula("x"); - ANS(FormulaWithUnits($a*$x+1,"ft")->cmp); + ANS(FormulaWithUnits("3x+1 ft")->cmp); + ANS(FormulaWithUnits("$a*x+1 ft")->cmp); + + $x = Formula("x"); + ANS(FormulaWithUnits($a*$x+1,"ft")->cmp); =cut Index: parserParametricLine.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserParametricLine.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lmacros/parserParametricLine.pl -Lmacros/parserParametricLine.pl -u -r1.13 -r1.14 --- macros/parserParametricLine.pl +++ macros/parserParametricLine.pl @@ -90,7 +90,7 @@ return bless $line, $class; } -=head3 $lhs == $rhs +=head2 $lhs == $rhs # # Two parametric lines are equal if they have Index: answerComposition.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerComposition.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/answerComposition.pl -Lmacros/answerComposition.pl -u -r1.5 -r1.6 --- macros/answerComposition.pl +++ macros/answerComposition.pl @@ -18,7 +18,7 @@ =head2 COMPOSITION_ANS - COMPOSITION_ANS($f, $g, %options) + COMPOSITION_ANS($f, $g, %options) An answer checked to see if $f composed with $g matches a given function,where $f and $g are one possible decomposition of the target function, and options are @@ -34,11 +34,11 @@ Example: - BEGIN_TEXT - \(f\circ g = (1+x)^2\) when - \(f(x)\) = \{ans_rule(20)\} and \(g(x)\) = \{ans_rule(20)\} - END_TEXT - COMPOSITION_ANS("x^2","1+x"); + BEGIN_TEXT + \(f\circ g = (1+x)^2\) when + \(f(x)\) = \{ans_rule(20)\} and \(g(x)\) = \{ans_rule(20)\} + END_TEXT + COMPOSITION_ANS("x^2","1+x"); =cut Index: answerHints.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerHints.pl,v retrieving revision 1.3 retrieving revision 1.4 diff -Lmacros/answerHints.pl -Lmacros/answerHints.pl -u -r1.3 -r1.4 --- macros/answerHints.pl +++ macros/answerHints.pl @@ -2,76 +2,89 @@ =head1 AnswerHints() - # This is an answer-checker post-filter that allows you to produce - # additional error messages for incorrect answers. You can trigger - # a message for a single answer, a collection of answers, or via a - # subroutine that determines the condition for the message. - # - # Note that this filter only works for MathObjects answer checkers. - # - # The answer hints are given as a pair using => with the right-hand - # side being the answer message and the left-hand side being one of - # three possibilities: 1) the value that triggers the message, - # 2) a reference to an array of values that trigger the message, or - # 3) a code reference to a subtroutine that accepts tthe correct - # answer, the student's answer, and the answer hash, and returns - # 1 or 0 depending on whether the message should or should not be - # displayed. (See the examples below.) - # - # The right-hand side can be either the message string itself, or - # a referrence to an array where the first element is the message - # string, and the remaining elements are name-value pairs that - # set options for the message. These can include: - # - # checkCorrect => 0 or 1 1 means check for messages even - # if the answer is correct. - # Default: 0 - # - # replaceMessage => 0 or 1 1 means it's OK to repalce any - # message that is already in place - # in the answer hash. - # Default: 0 - # - # checkTypes => 0 or 1 1 means only perform the test - # if the student answer is the - # same type as the correct one. - # Default: 1 - # - # score => number Specifies the score to use if - # the message is triggered (so that - # partial credit can be given). - # Default: keep original score - # - # cmp_options => [...] provides options for the cmp routine - # used to check if the student answer - # matches these answers. - # Default: [] - # - # If more than one message matches the student's answer, the first - # one in the list is used. - # - # Example: - # - # ANS(Vector(1,2,3)->cmp(showCoordinateHints=>0)->withPostFilter(AnswerHints( - # Vector(0,0,0) => "The zero vector is not a valid solution", - # "-<1,2,3>" => "Try the opposite direction", - # "<1,2,3>" => "Well done!", - # ["<1,1,1>","<2,2,2>","<3,3,3>"] => "Don't just guess!", - # sub { - # my ($correct,$student,$ans) = @_; - # return $correct . $student == 0; - # } => "Your answer is perpendicular to the correct one", - # Vector(1,2,3) => [ - # "You have the right direction, but not length", - # cmp_options => [parallel=>1], - # ], - # 0 => ["Careful, your answer should be a vector!", checkTypes => 0, replaceMessage => 1], - # sub { - # my ($correct,$student,$ans) = @_; - # return norm($correct-$student) < .1; - # } => ["Close! Keep trying.", score => .25], - # ))); - # +This is an answer-checker post-filter that allows you to produce +additional error messages for incorrect answers. You can trigger +a message for a single answer, a collection of answers, or via a +subroutine that determines the condition for the message. + +Note that this filter only works for MathObjects answer checkers. + +The answer hints are given as a pair using => with the right-hand +side being the answer message and the left-hand side being one of +three possibilities: 1) the value that triggers the message, +2) a reference to an array of values that trigger the message, or +3) a code reference to a subtroutine that accepts tthe correct +answer, the student's answer, and the answer hash, and returns +1 or 0 depending on whether the message should or should not be +displayed. (See the examples below.) + +The right-hand side can be either the message string itself, or +a referrence to an array where the first element is the message +string, and the remaining elements are name-value pairs that +set options for the message. These can include: + +=over + +=item C<S<< checkCorrect => 0 or 1 >>> + +1 means check for messages even +if the answer is correct. +Default: 0 + +=item C<S<< replaceMessage => 0 or 1 >>> + +1 means it's OK to repalce any +message that is already in place +in the answer hash. +Default: 0 + +=item C<S<< checkTypes => 0 or 1 >>> + +1 means only perform the test +if the student answer is the +same type as the correct one. +Default: 1 + +=item C<S<< score => number >>> + +Specifies the score to use if +the message is triggered (so that +partial credit can be given). +Default: keep original score + +=item C<S<< cmp_options => [...] >>> + +provides options for the cmp routine +used to check if the student answer +matches these answers. +Default: [] + +=back + +If more than one message matches the student's answer, the first +one in the list is used. + +Example: + + ANS(Vector(1,2,3)->cmp(showCoordinateHints=>0)->withPostFilter(AnswerHints( + Vector(0,0,0) => "The zero vector is not a valid solution", + "-<1,2,3>" => "Try the opposite direction", + "<1,2,3>" => "Well done!", + ["<1,1,1>","<2,2,2>","<3,3,3>"] => "Don't just guess!", + sub { + my ($correct,$student,$ans) = @_; + return $correct . $student == 0; + } => "Your answer is perpendicular to the correct one", + Vector(1,2,3) => [ + "You have the right direction, but not length", + cmp_options => [parallel=>1], + ], + 0 => ["Careful, your answer should be a vector!", checkTypes => 0, replaceMessage => 1], + sub { + my ($correct,$student,$ans) = @_; + return norm($correct-$student) < .1; + } => ["Close! Keep trying.", score => .25], + ))); =cut Index: parserFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFunction.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/parserFunction.pl -Lmacros/parserFunction.pl -u -r1.9 -r1.10 --- macros/parserFunction.pl +++ macros/parserFunction.pl @@ -32,7 +32,7 @@ object. =cut - + loadMacros('MathObjects.pl'); sub _parserFunction_init {parserFunction::Init()}; # don't reload this file @@ -125,7 +125,7 @@ &{$def->{function}}(@_); } -=head3 ($Function)->D +=head2 ($Function)->D # # Compute the derivative of (single-variable) functions Index: answerCustom.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerCustom.pl,v retrieving revision 1.14 retrieving revision 1.15 diff -Lmacros/answerCustom.pl -Lmacros/answerCustom.pl -u -r1.14 -r1.15 --- macros/answerCustom.pl +++ macros/answerCustom.pl @@ -13,7 +13,7 @@ =head2 custom_cmp - ANS(custom_cmp($correct_ans, $ans_checker, %options)) + ANS(custom_cmp($correct_ans, $ans_checker, %options)) This answer checker provides an easy method for creating an answer checker with a custom subroutine that performs the check for @@ -69,10 +69,10 @@ For example, the following checks if a student entered a unit vector (any unit vector in R^3 will do): - ANS(custom_cmp("<1,0,0>",sub { - my ($correct,$student,$ans) = @_; - return norm($student) == 1; - },showCoordinateHints => 0)); + ANS(custom_cmp("<1,0,0>",sub { + my ($correct,$student,$ans) = @_; + return norm($student) == 1; + },showCoordinateHints => 0)); The checker subroutine can call Value::Error(message) to generate an error message that will be reported in the table at the top of |
From: Sam H. v. a. <we...@ma...> - 2007-10-03 19:55:14
|
Log Message: ----------- fixed indentation of verbatim paragraphs: now using hard tabs exclusively. the downside of this is that these get rendered as eight-column tabs. Modified Files: -------------- pg/macros: answerHints.pl answerVariableList.pl contextABCD.pl contextCurrency.pl contextInequalities.pl contextIntegerFunctions.pl contextLimitedComplex.pl contextLimitedNumeric.pl contextLimitedPoint.pl contextLimitedPolynomial.pl contextLimitedPowers.pl contextLimitedVector.pl contextPeriodic.pl contextPiecewiseFunction.pl contextScientificNotation.pl contextString.pl contextTF.pl parserAutoStrings.pl parserCustomization.pl parserDifferenceQuotient.pl parserFormulaUpToConstant.pl parserFormulaWithUnits.pl parserFunction.pl parserImplicitEquation.pl parserImplicitPlane.pl parserMultiAnswer.pl parserNumberWithUnits.pl parserParametricLine.pl parserVectorUtils.pl problemRandomize.pl Revision Data ------------- Index: parserImplicitEquation.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserImplicitEquation.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/parserImplicitEquation.pl -Lmacros/parserImplicitEquation.pl -u -r1.10 -r1.11 --- macros/parserImplicitEquation.pl +++ macros/parserImplicitEquation.pl @@ -61,14 +61,14 @@ Usage examples: - Context("ImplicitEquation"); - $f = ImplicitEquation("x^2 = cos(y)"); - $f = ImplicitEquation("x^2 - 2y^2 = 5",limits=>[[-3,3],[-2,2]]); - $f = ImplicitEquation("x=1/y",tolerance=>.0001); + Context("ImplicitEquation"); + $f = ImplicitEquation("x^2 = cos(y)"); + $f = ImplicitEquation("x^2 - 2y^2 = 5",limits=>[[-3,3],[-2,2]]); + $f = ImplicitEquation("x=1/y",tolerance=>.0001); Then use - ANS($f->cmp); + ANS($f->cmp); to get the answer checker for $f. @@ -150,13 +150,12 @@ For example: - $f = ImplicitEquation("x^2-y^2=0", - solutions => [[0,0],[1,1],[-1,1],[-1,-1],[1,-1]], - tolerance => .001 - ); + $f = ImplicitEquation("x^2-y^2=0", + solutions => [[0,0],[1,1],[-1,1],[-1,-1],[1,-1]], + tolerance => .001 + ); - - $f = ImplicitEquation("xy=5",limits=>[-3,3]); + $f = ImplicitEquation("xy=5",limits=>[-3,3]); The limits value can be set globally within the Context, if you wish, and the others can be controlled by the Context flags discussed Index: parserParametricLine.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserParametricLine.pl,v retrieving revision 1.14 retrieving revision 1.15 diff -Lmacros/parserParametricLine.pl -Lmacros/parserParametricLine.pl -u -r1.14 -r1.15 --- macros/parserParametricLine.pl +++ macros/parserParametricLine.pl @@ -17,18 +17,18 @@ Usage examples: - $L = ParametricLine(Point(3,-1,2),Vector(1,1,3)); - $L = ParametricLine([3,-1,2],[1,1,3]); - $L = ParametricLine("<t,1-t,2t-3>"); + $L = ParametricLine(Point(3,-1,2),Vector(1,1,3)); + $L = ParametricLine([3,-1,2],[1,1,3]); + $L = ParametricLine("<t,1-t,2t-3>"); - $p = Point(3,-1,2); $v = Vector(1,1,3); - $L = ParametricLine($p,$v); + $p = Point(3,-1,2); $v = Vector(1,1,3); + $L = ParametricLine($p,$v); - $t = Formula('t'); $p = Point(3,-1,2); $v = Vector(1,1,3); - $L = ParametricLine($p+$t*$v); + $t = Formula('t'); $p = Point(3,-1,2); $v = Vector(1,1,3); + $L = ParametricLine($p+$t*$v); - Context()->constants->are(a=>1+pi^2); # won't guess this value - $L = ParametricLine("(a,2a,-1) + t <1,a,a^2>"); + Context()->constants->are(a=>1+pi^2); # won't guess this value + $L = ParametricLine("(a,2a,-1) + t <1,a,a^2>"); Then use Index: contextLimitedPoint.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPoint.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextLimitedPoint.pl -Lmacros/contextLimitedPoint.pl -u -r1.11 -r1.12 --- macros/contextLimitedPoint.pl +++ macros/contextLimitedPoint.pl @@ -9,7 +9,7 @@ students will be able to perform operations within the coordinates of the points, but not between points. - Context("LimitedPoint") + Context("LimitedPoint") =cut Index: contextString.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextString.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/contextString.pl -Lmacros/contextString.pl -u -r1.12 -r1.13 --- macros/contextString.pl +++ macros/contextString.pl @@ -9,12 +9,12 @@ You can add new strings to the context as needed via the Context()->strings->add() method. E.g., - Context("String")->strings->add(Foo=>{}, Bar=>{alias=>"Foo"}); + Context("String")->strings->add(Foo=>{}, Bar=>{alias=>"Foo"}); Use string_cmp() to produce the answer checker(s) for your correct values. Eg. - ANS(string_cmp("Foo")); + ANS(string_cmp("Foo")); =cut Index: parserCustomization.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserCustomization.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/parserCustomization.pl -Lmacros/parserCustomization.pl -u -r1.5 -r1.6 --- macros/parserCustomization.pl +++ macros/parserCustomization.pl @@ -1,33 +1,35 @@ -sub _parserCustomization_init {} +=head1 NAME + +parserCustomization.pl - Placeholder for site/course-local customization file. + +=head1 DESCRIPTION + +Copy this file to your course templates directory and put any +customization for the Parser that you want for your course +here. For example, you can make vectors display using +ijk notation (and force students to use it for entering +vectors) by uncommenting: -=head1 parserCustomization + $context{Vector} = Parser::Context->getCopy("Vector"); + $context{Vector}->flags->set(ijk=>1); + $context{Vector}->parens->remove('<'); - # - # Copy this file to your course templates directory and put any - # customization for the Parser that you want for your course - # here. For example, you can make vectors display using - # ijk notation (and force students to use it for entering - # vectors) by uncommenting: - # - # $context{Vector} = Parser::Context->getCopy("Vector"); - # $context{Vector}->flags->set(ijk=>1); - # $context{Vector}->parens->remove('<'); - # - # To allow vectors to be entered with parens (and displayed with - # parens) rather than angle-brakets, uncomment - # - # $context{Vector} = Parser::Context->getCopy("Vector"); - # $context{Vector}->{cmpDefaults}{Vector} = {promotePoints => 1}; - # $context{Vector}->lists->set(Vector=>{open=>'(', close=>')'}); - # - # (This actually just turns points into vectors in the answer checker - # for vectors, and displays vectors using parens rather than angle - # brakets. The student is really still entering what the Parser - # thinks is a point, but since points get promoted automatically - # in the Value package, that should work. But if a problem checks - # if a student's value is actually a Vector, that will not be true.) - # +To allow vectors to be entered with parens (and displayed with +parens) rather than angle-brakets, uncomment + + $context{Vector} = Parser::Context->getCopy("Vector"); + $context{Vector}->{cmpDefaults}{Vector} = {promotePoints => 1}; + $context{Vector}->lists->set(Vector=>{open=>'(', close=>')'}); + +(This actually just turns points into vectors in the answer checker +for vectors, and displays vectors using parens rather than angle +brakets. The student is really still entering what the Parser +thinks is a point, but since points get promoted automatically +in the Value package, that should work. But if a problem checks +if a student's value is actually a Vector, that will not be true.) =cut +sub _parserCustomization_init {} + 1; Index: contextLimitedNumeric.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedNumeric.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/contextLimitedNumeric.pl -Lmacros/contextLimitedNumeric.pl -u -r1.8 -r1.9 --- macros/contextLimitedNumeric.pl +++ macros/contextLimitedNumeric.pl @@ -11,8 +11,8 @@ and one for a single number. Select them using one of the following commands: - Context("LimitedNumeric-List"); - Context("LimiteNumeric"); + Context("LimitedNumeric-List"); + Context("LimiteNumeric"); (Now uses Parcer::Legacy::LimitedNumeric to implement these contexts.) Index: parserVectorUtils.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserVectorUtils.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/parserVectorUtils.pl -Lmacros/parserVectorUtils.pl -u -r1.6 -r1.7 --- macros/parserVectorUtils.pl +++ macros/parserVectorUtils.pl @@ -14,7 +14,7 @@ =head2 Overline - Overline($vectorName) + Overline($vectorName) formats a vector name (should be used in math mode) @@ -38,7 +38,7 @@ =head2 BoldMath - BoldMath($vectorName) + BoldMath($vectorName) This gets a bold letter in TeX as well as HTML modes. Although \boldsymbol{} works fine on screen in latex2html mode, @@ -63,11 +63,11 @@ =head2 $GRAD - TEXT($GRAD) + TEXT($GRAD) - BEGIN_TEXT - $GRAD - END_TEXT + BEGIN_TEXT + $GRAD + END_TEXT Grad symbol. @@ -77,7 +77,7 @@ =head2 non_zero_point - non_zero_point($Dim,$L_bound,$U_bound,$step) + non_zero_point($Dim,$L_bound,$U_bound,$step) Create a non-zero point with the given number of coordinates with the given random range (which defaults to (-5,5,1)). @@ -102,11 +102,11 @@ =head2 non_zero_vector, non_zero_vector2D, non_zero_vector3D - non_zero_vector($Dim,$L_bound,$U_bound,$step) + non_zero_vector($Dim,$L_bound,$U_bound,$step) - non_zero_vector2D($L_bound,$U_bound,$step) + non_zero_vector2D($L_bound,$U_bound,$step) - non_zero_vector3D($L_bound,$U_bound,$step) + non_zero_vector3D($L_bound,$U_bound,$step) Functions the same as non_zero_point but for Vectors. non_zero_vector2D and non_zero_vector3D automatically set Dimension to 2 and 3 respectively. @@ -150,7 +150,7 @@ =head2 Plane - Plane($point,$NormalVector) + Plane($point,$NormalVector) Creates a displayable string for a plane given its normal vector and a point on the plane. (Better to use Index: parserDifferenceQuotient.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserDifferenceQuotient.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/parserDifferenceQuotient.pl -Lmacros/parserDifferenceQuotient.pl -u -r1.12 -r1.13 --- macros/parserDifferenceQuotient.pl +++ macros/parserDifferenceQuotient.pl @@ -19,16 +19,16 @@ DifferenceQuotient(). You could use a variable like h instead of dx if you prefer. -Usage examples: +=head1 USAGE - $df = DifferenceQuotient("2x+dx"); - ANS($df->cmp); + $df = DifferenceQuotient("2x+dx"); + ANS($df->cmp); - $df = DifferenceQuotient("2x+h","h"); - ANS($df->cmp); + $df = DifferenceQuotient("2x+h","h"); + ANS($df->cmp); - Context()->variables->are(t=>'Real',a=>'Real'); - ANS(DifferenceQuotient("-a/[t(t+dt)]","dt")->cmp); + Context()->variables->are(t=>'Real',a=>'Real'); + ANS(DifferenceQuotient("-a/[t(t+dt)]","dt")->cmp); =cut Index: parserImplicitPlane.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserImplicitPlane.pl,v retrieving revision 1.17 retrieving revision 1.18 diff -Lmacros/parserImplicitPlane.pl -Lmacros/parserImplicitPlane.pl -u -r1.17 -r1.18 --- macros/parserImplicitPlane.pl +++ macros/parserImplicitPlane.pl @@ -27,19 +27,19 @@ Usage examples: - $P = ImplicitPlane(Point(1,0,2),Vector(-1,1,3)); # -x+y+3z = 5 - $P = ImplicitPlane([1,0,2],[-1,1,3]); # -x+y+3z = 5 - $P = ImplicitPlane([1,0,2],4); # x+2z = 4 - $P = ImplicitPlane("x+2y-z=5"); - - Context()->variables->are(x=>'Real',y=>'Real',z=>'Real',w=>'Real'); - $P = ImplicitPlane([1,0,2,-1],10); # w+2y-z = 10 (alphabetical order) - $P = ImplicitPlane([3,-1,2,4],5,['x','y','z','w']); # 3x-y+2z+4w = 5 - $P = ImplicitPlane([3,-1,2],5,['y','z','w']); # 3y-z+2w = 5 + $P = ImplicitPlane(Point(1,0,2),Vector(-1,1,3)); # -x+y+3z = 5 + $P = ImplicitPlane([1,0,2],[-1,1,3]); # -x+y+3z = 5 + $P = ImplicitPlane([1,0,2],4); # x+2z = 4 + $P = ImplicitPlane("x+2y-z=5"); + + Context()->variables->are(x=>'Real',y=>'Real',z=>'Real',w=>'Real'); + $P = ImplicitPlane([1,0,2,-1],10); # w+2y-z = 10 (alphabetical order) + $P = ImplicitPlane([3,-1,2,4],5,['x','y','z','w']); # 3x-y+2z+4w = 5 + $P = ImplicitPlane([3,-1,2],5,['y','z','w']); # 3y-z+2w = 5 Then use - ANS($P->cmp); + ANS($P->cmp); to get the answer checker for $P. Index: contextLimitedVector.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedVector.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextLimitedVector.pl -Lmacros/contextLimitedVector.pl -u -r1.10 -r1.11 --- macros/contextLimitedVector.pl +++ macros/contextLimitedVector.pl @@ -20,9 +20,9 @@ You control which format to use by setting the context to one of the following: - Context("LimitedVector-coordinate"); - Context("LimitedVector-ijk"); - Context("LimitedVector"); # either one + Context("LimitedVector-coordinate"); + Context("LimitedVector-ijk"); + Context("LimitedVector"); # either one =cut Index: parserFormulaWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFormulaWithUnits.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/parserFormulaWithUnits.pl -Lmacros/parserFormulaWithUnits.pl -u -r1.9 -r1.10 --- macros/parserFormulaWithUnits.pl +++ macros/parserFormulaWithUnits.pl @@ -12,7 +12,7 @@ to generate a FormulaWithUnits object, and then call its cmp() method to get an answer checker for your formula with units. -Usage examples: +=head1 USAGE ANS(FormulaWithUnits("3x+1 ft")->cmp); ANS(FormulaWithUnits("$a*x+1 ft")->cmp); Index: parserNumberWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserNumberWithUnits.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/parserNumberWithUnits.pl -Lmacros/parserNumberWithUnits.pl -u -r1.7 -r1.8 --- macros/parserNumberWithUnits.pl +++ macros/parserNumberWithUnits.pl @@ -14,9 +14,9 @@ Usage examples: - ANS(NumberWithUnits("3 ft")->cmp); - ANS(NumberWithUnits("$a*$b ft")->cmp); - ANS(NumberWithUnits($a*$b,"ft")->cmp); + ANS(NumberWithUnits("3 ft")->cmp); + ANS(NumberWithUnits("$a*$b ft")->cmp); + ANS(NumberWithUnits($a*$b,"ft")->cmp); We now call on the Legacy version, which is used by num_cmp to handle numbers with units. Index: answerVariableList.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerVariableList.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/answerVariableList.pl -Lmacros/answerVariableList.pl -u -r1.10 -r1.11 --- macros/answerVariableList.pl +++ macros/answerVariableList.pl @@ -3,6 +3,36 @@ answerVariableList.pl - Creates answer checkers that compare the student's answer to a list of variable names. +=head1 MACROS + +=head2 variable_cmp + + ANS(variable_cmp($var_string, %options)) + +This answer checker compares the student answer to a list of +variable names (so, for example, you can ask for what values a +given function depends on). + +Use addVariables() to create the list of variables that from which +the student can choose, and then use variable_cmp() to generate the +answer checker. If the formula passed to variable_cmp contains +parentheses around the list, then the student's answer must as +well. + +You can also include additional parameters to variable_cmp. These +can be any of the flags appropriate for List() answer checker. + +Usage examples: + + addVariables('x','y','z'); + ANS(variable_cmp("(x,y)")); + + addVariables('x','y','z','s','t,); + ANS(variable_cmp("s,t")); + + addVariables('x','y','z'); + ANS(variable_cmp("(x)",showHints=>0,showLengthHints=>0)); + =cut loadMacros('MathObjects.pl'); @@ -30,38 +60,6 @@ main::Context("VariableList"); ### FIXME: probably should require author to set this explicitly. } -=head1 MACROS - -=head2 variable_cmp - - ANS(variable_cmp($var_string, %options)) - -This answer checker compares the student answer to a list of -variable names (so, for example, you can ask for what values a -given function depends on). - -Use addVariables() to create the list of variables that from which -the student can choose, and then use variable_cmp() to generate the -answer checker. If the formula passed to variable_cmp contains -parentheses around the list, then the student's answer must as -well. - -You can also include additional parameters to variable_cmp. These -can be any of the flags appropriate for List() answer checker. - -Usage examples: - - addVariables('x','y','z'); - ANS(variable_cmp("(x,y)")); - - addVariables('x','y','z','s','t,); - ANS(variable_cmp("s,t")); - - addVariables('x','y','z'); - ANS(variable_cmp("(x)",showHints=>0,showLengthHints=>0)); - -=cut - sub variable_cmp { Value->Package("Formula")->new(shift)->cmp( ordered => 1, Index: contextLimitedComplex.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedComplex.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextLimitedComplex.pl -Lmacros/contextLimitedComplex.pl -u -r1.10 -r1.11 --- macros/contextLimitedComplex.pl +++ macros/contextLimitedComplex.pl @@ -9,7 +9,7 @@ be able to perform operations within the real and imaginary parts of the complex numbers, but not between complex numbers. - Context("LimitedComplex") + Context("LimitedComplex") Complex Numbers can still be entered in a+bi or a*e^(bt) form. The e and i are allowed to be entered only once, so we have @@ -20,27 +20,27 @@ You control which format to use by setting the complex_format context flag to 'cartesian', 'polar' or 'either'. E.g., - Context()->flags->set(complex_format => 'polar'); + Context()->flags->set(complex_format => 'polar'); The default is 'either'. There are predefined contexts that already have these values set: - Context("LimitedComplex-cartesian"); - Context("LimitedComplex-polar"); + Context("LimitedComplex-cartesian"); + Context("LimitedComplex-polar"); You can require that the a and b used in these forms be strictly numbers (not expressions) by setting the strict_numeric flag and disabling all the functions: - Context()->flags->set(strict_numeric=>1); - Context()->functions->disable('All'); + Context()->flags->set(strict_numeric=>1); + Context()->functions->disable('All'); There are predefined contexts that already have these values set: - Context("LimitedComplex-cartesian-strict"); - Context("LimitedComplex-polar-strict"); - Context("LimitedComplex-strict"); + Context("LimitedComplex-cartesian-strict"); + Context("LimitedComplex-polar-strict"); + Context("LimitedComplex-strict"); =cut Index: contextPeriodic.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPeriodic.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextPeriodic.pl -Lmacros/contextPeriodic.pl -u -r1.10 -r1.11 --- macros/contextPeriodic.pl +++ macros/contextPeriodic.pl @@ -10,13 +10,13 @@ =head1 USAGE - Context("Numeric"); - $a = Real("pi/2")->with(period=>pi); - $a->cmp # will match pi/2, 3pi/2 etc. + Context("Numeric"); + $a = Real("pi/2")->with(period=>pi); + $a->cmp # will match pi/2, 3pi/2 etc. - Context("Complex"); - $z0 = Real("i^i")->with(period=>2pi, logPeriodic=>1); - $z0->cmp # will match exp(i*(ln(1) + Arg(pi/2) + 2k pi)) + Context("Complex"); + $z0 = Real("i^i")->with(period=>2pi, logPeriodic=>1); + $z0->cmp # will match exp(i*(ln(1) + Arg(pi/2) + 2k pi)) =cut Index: contextPiecewiseFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPiecewiseFunction.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/contextPiecewiseFunction.pl -Lmacros/contextPiecewiseFunction.pl -u -r1.5 -r1.6 --- macros/contextPiecewiseFunction.pl +++ macros/contextPiecewiseFunction.pl @@ -7,22 +7,22 @@ This file implements a context in which piecewise-defined functions can be specified by students and problem authors. To use it, add - loadMacros("contextPiecewiseFunction.pl"); + loadMacros("contextPiecewiseFunction.pl"); and then use - Context("PiecewiseFuntion"); + Context("PiecewiseFuntion"); to select the context for piecewise functions. There are several ways to produce a piecewise function. For example: - $f = Compute("x if x >= 0 else -x"); - $f = Compute("x if x >= 0 else -x if x < 0"); - $f = Formula("x+1 if x > 2 else 4 if x = 2 else 1-x"); - $f = PiecewiseFunction("x^2 if 1 < x <= 2 else 2x+1"); - $f = PiecewiseFunction("1 < x <= 2" => "x^2", "2x+1"); - $f = PiecewiseFunction("(1,2]" => "x^2", "2x+1"); - $f = PiecewiseFunction(Interval("(1,2]") => "x^2", "2x+1"); + $f = Compute("x if x >= 0 else -x"); + $f = Compute("x if x >= 0 else -x if x < 0"); + $f = Formula("x+1 if x > 2 else 4 if x = 2 else 1-x"); + $f = PiecewiseFunction("x^2 if 1 < x <= 2 else 2x+1"); + $f = PiecewiseFunction("1 < x <= 2" => "x^2", "2x+1"); + $f = PiecewiseFunction("(1,2]" => "x^2", "2x+1"); + $f = PiecewiseFunction(Interval("(1,2]") => "x^2", "2x+1"); You can use either Compute() or Formula() interchangeably to convert a string containing "if" and "else" to the corresponding @@ -41,18 +41,18 @@ output even if you are not asking a student to enter one. For example: - Context("PiecewiseFunction"); - - $f = Formula("1-x if x > 0 else 4 if x = 0 else 1+x if x < 0"); - $a = random(-2,2,.1); - - Context()->texStrings; - BEGIN_TEXT - Suppose \(f(x)=$f\). Then \(f($a)\) = \{ans_rule(20)\}. - END_TEXT - Context()->normalStrings; - - ANS($f->eval(x=>$a)->cmp); + Context("PiecewiseFunction"); + + $f = Formula("1-x if x > 0 else 4 if x = 0 else 1+x if x < 0"); + $a = random(-2,2,.1); + + Context()->texStrings; + BEGIN_TEXT + Suppose \(f(x)=$f\). Then \(f($a)\) = \{ans_rule(20)\}. + END_TEXT + Context()->normalStrings; + + ANS($f->eval(x=>$a)->cmp); =cut Index: contextInequalities.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextInequalities.pl,v retrieving revision 1.14 retrieving revision 1.15 diff -Lmacros/contextInequalities.pl -Lmacros/contextInequalities.pl -u -r1.14 -r1.15 --- macros/contextInequalities.pl +++ macros/contextInequalities.pl @@ -13,18 +13,18 @@ =head1 USAGE - loadMacros("contextInequalities.pl"); - - Context("Inequalities"); - $S1 = Compute("1 < x <= 4"); - $S2 = Inequality("(1,4]"); # force interval to be inequality - - Context("Inequalities-Only"); - $S1 = Compute("1 < x <= 4"); - $S2 = Inequality("(1,4]"); # generates an error - - $S3 = Compute("x < -2 or x > 2"); # forms a Union - $S4 = Compute("x = 1"); # forms a Set + loadMacros("contextInequalities.pl"); + + Context("Inequalities"); + $S1 = Compute("1 < x <= 4"); + $S2 = Inequality("(1,4]"); # force interval to be inequality + + Context("Inequalities-Only"); + $S1 = Compute("1 < x <= 4"); + $S2 = Inequality("(1,4]"); # generates an error + + $S3 = Compute("x < -2 or x > 2"); # forms a Union + $S4 = Compute("x = 1"); # forms a Set You can set the "noneWord" flag to specify the string to use when the inequalities specify the empty set. By default, @@ -32,9 +32,9 @@ that you use a string that is defined in the Context, however, if you expect the student to be able to enter it. For example - Context("Inequalities"); - Context()->constants->add(EmptySet => Set()); - Context()->flags->set(noneWord=>"EmptySet"); + Context("Inequalities"); + Context()->constants->add(EmptySet => Set()); + Context()->flags->set(noneWord=>"EmptySet"); creates an empty set as a named constant and uses that name. @@ -45,11 +45,11 @@ convert from an Inequality object to one in interval notation. For example: - $I0 = Compute("(1,2]"); # the interval (1,2] - $I1 = Inequality($I); # the inequality 1 < x <= 2 + $I0 = Compute("(1,2]"); # the interval (1,2] + $I1 = Inequality($I); # the inequality 1 < x <= 2 - $I0 = Compute("1 < x <= 2"); # the inequality 1 < x <= 2 - $I1 = Interval($I0); # the interval (1,2] + $I0 = Compute("1 < x <= 2"); # the inequality 1 < x <= 2 + $I1 = Interval($I0); # the interval (1,2] Note that ineqaulities and inervals can be compared and combined regardless of the format, so $I0 == $I1 is true in either example Index: parserMultiAnswer.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserMultiAnswer.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/parserMultiAnswer.pl -Lmacros/parserMultiAnswer.pl -u -r1.7 -r1.8 --- macros/parserMultiAnswer.pl +++ macros/parserMultiAnswer.pl @@ -13,20 +13,20 @@ To create a MultiAnswer pass a list of answers to MultiAnswer() in the order they will appear in the problem. For example: - $mp = MultiAnswer("x^2",-1,1); + $mp = MultiAnswer("x^2",-1,1); or - $mp = MultiAnswer(Vector(1,1,1),Vector(2,2,2))->with(singleResult=>1); + $mp = MultiAnswer(Vector(1,1,1),Vector(2,2,2))->with(singleResult=>1); Then, use $mp->ans_rule to create answer blanks for the various parts just as you would ans_rule. You can pass the width of the blank, which defaults to 20 otherwise. For example: - BEGIN_TEXT - \(f(x)\) = \{$mp->ans_rule(20)\} produces the same value - at \(x\) = \{$mp->ans_rule(10)\} as it does at \(x\) = \{$mp->ans_rule(10)\}. - END_TEXT + BEGIN_TEXT + \(f(x)\) = \{$mp->ans_rule(20)\} produces the same value + at \(x\) = \{$mp->ans_rule(10)\} as it does at \(x\) = \{$mp->ans_rule(10)\}. + END_TEXT Finally, call $mp->cmp to produce the answer checker(s) used in the MultiAnswer. You need to provide a checker routine that will be called to determine if the @@ -43,7 +43,7 @@ to an array of scores, one for each blank. The routine can set error messages via the MultiAnswer's setMessage() method (e.g., - $mp->setMessage(1,"The function can't be the identity"); + $mp->setMessage(1,"The function can't be the identity"); would set the message for the first answer blank of the MultiAnswer), or can call Value::Error() to generate an error and die. @@ -51,29 +51,29 @@ The checker routine can be supplied either when the MultiAnswer is created, or when the cmp() method is called. For example: - $mp = MultiAnswer("x^2",1,-1)->with( - singleResult => 1, - checker => sub { - my ($correct,$student,$self) = @_; # get the parameters - my ($f,$x1,$x2) = @{$student}; # extract the student answers - Value::Error("Function can't be the identity") if ($f == 'x'); - Value::Error("Function can't be constant") if ($f->isConstant); - return $f->eval(x=>$x1) == $f->eval(x=>$x2); - }, - ); - ANS($mp->cmp); + $mp = MultiAnswer("x^2",1,-1)->with( + singleResult => 1, + checker => sub { + my ($correct,$student,$self) = @_; # get the parameters + my ($f,$x1,$x2) = @{$student}; # extract the student answers + Value::Error("Function can't be the identity") if ($f == 'x'); + Value::Error("Function can't be constant") if ($f->isConstant); + return $f->eval(x=>$x1) == $f->eval(x=>$x2); + }, + ); + ANS($mp->cmp); or - $mp = MultiAnswer("x^2",1,-1)->with(singleResult=>1); - sub check { - my ($correct,$student,$self) = @_; # get the parameters - my ($f,$x1,$x2) = @{$student}; # extract the student answers - Value::Error("Function can't be the identity") if ($f == 'x'); - Value::Error("Function can't be constant") if ($f->isConstant); - return $f->eval(x=>$x1) == $f->eval(x=>$x2); - }; - ANS($mp->cmp(checker=>~~&check)); + $mp = MultiAnswer("x^2",1,-1)->with(singleResult=>1); + sub check { + my ($correct,$student,$self) = @_; # get the parameters + my ($f,$x1,$x2) = @{$student}; # extract the student answers + Value::Error("Function can't be the identity") if ($f == 'x'); + Value::Error("Function can't be constant") if ($f->isConstant); + return $f->eval(x=>$x1) == $f->eval(x=>$x2); + }; + ANS($mp->cmp(checker=>~~&check)); =cut Index: contextScientificNotation.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextScientificNotation.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/contextScientificNotation.pl -Lmacros/contextScientificNotation.pl -u -r1.8 -r1.9 --- macros/contextScientificNotation.pl +++ macros/contextScientificNotation.pl @@ -19,38 +19,38 @@ To use this context, add - loadMacros("contextScientificNotation.pl"); + loadMacros("contextScientificNotation.pl"); to the top of your problem file, and then use - Context("ScientificNotation"); + Context("ScientificNotation"); to select the contxt and make it active. You can create values in scientific notation in two ways: - $n1 = Compute("1.23 x 10^3"); + $n1 = Compute("1.23 x 10^3"); or - $n2 = ScientificNotation(1.23 * 10**3); + $n2 = ScientificNotation(1.23 * 10**3); (or even $n2 = ScientificNotation(1230), and it will be converted). You can control how many digits are displayed by setting the snDigits flag in the context. For example, - Context()->flags->set(snDigits=>2); + Context()->flags->set(snDigits=>2); sets the context to display at most 2 digits. The default is 6. By default, trailing zeros are removed, but you can ask that they be retained by issuing the command - Context()->flags->set(snTrimZeros=>0); + Context()->flags->set(snTrimZeros=>0); It is also possible to specify how many decimal digits the student must enter. For example, - Context()->flags->set(snMinDigits=>3); + Context()->flags->set(snMinDigits=>3); would require the student to enter at least 3 digits past the decimal place (for a total of 4 significant digits, @@ -60,7 +60,7 @@ Similarly, - Context()->flags->set(snMaxDigits=>6); + Context()->flags->set(snMaxDigits=>6); sets the maximum number to 6, so the student can't enter more than that. Setting this to 0 means no decimal places @@ -73,12 +73,12 @@ As an example, in order to force a fixed precision of three digits of precision, use - Context()->flags->set( - snDigits => 3, - snTrimZeros => 0, - snMinDigits => 3, - snMaxDigits => 3, - ); + Context()->flags->set( + snDigits => 3, + snTrimZeros => 0, + snMinDigits => 3, + snMaxDigits => 3, + ); Note that if you restrict the number of digits, you may need to adjust the tolerance values since the student Index: contextCurrency.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextCurrency.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextCurrency.pl -Lmacros/contextCurrency.pl -u -r1.11 -r1.12 --- macros/contextCurrency.pl +++ macros/contextCurrency.pl @@ -1,6 +1,9 @@ -=head1 Context("Currency"); +=head1 NAME -##################################################################### +contextCurrency.pl - Context for entering numbers with currency symbols and +commas. + +=head1 DESCRIPTION This file implements a context in which students can enter currency values that include a currency symbol and commas every three digits. @@ -9,23 +12,23 @@ To use the context, put - loadMacros("contextCurrency.pl"); + loadMacros("contextCurrency.pl"); at the top of your problem file, and then issue the - Context("Currency"); + Context("Currency"); command to select the context. You can set the currency symbol and the comma or decimal values as in the following examples - Context()->currency->set(symbol=>'#'); - Context()->currency->set(symbol=>'euro'); # accepts '12 euro' - Context()->currency->set(comma=>'.',decimal=>','); # accepts '10.000,00' + Context()->currency->set(symbol=>'#'); + Context()->currency->set(symbol=>'euro'); # accepts '12 euro' + Context()->currency->set(comma=>'.',decimal=>','); # accepts '10.000,00' You can add additional symbols (in case you want to allow more than one way to write the currency). For example: - Context("Currency")->currency->addSymbol("dollars","dollar"); + Context("Currency")->currency->addSymbol("dollars","dollar"); would accept '$12,345.67' or '12.50 dollars' or '1 dollar' as acceptable values. Note that if the symbol cantains any @@ -34,27 +37,27 @@ non-alphabetic characters, it comes before it. You can change this as in these examples: - Context()->currency->setSymbol(euro=>{associativity=>"left"}); - Context()->currency->setSymbol('#'=>{associativity=>"right"}); + Context()->currency->setSymbol(euro=>{associativity=>"left"}); + Context()->currency->setSymbol('#'=>{associativity=>"right"}); You can remove a symbol as follows: - Context()->currency->removeSymbol('dollar'); + Context()->currency->removeSymbol('dollar'); To create a currency value, use - $m = Currency(10.99); + $m = Currency(10.99); or - $m1 = Compute('$10.99'); - $m2 = Compute('$10,000.00'); + $m1 = Compute('$10.99'); + $m2 = Compute('$10,000.00'); and so on. Be careful, however, that you do not put dollar signs inside double quotes, as this refers to variable substitution. For example, - $m = Compute("$10.99"); + $m = Compute("$10.99"); will most likely set $m to the Real value .99 rather than the monitary value of $10.99, since perl thinks $10 is the name of @@ -64,9 +67,9 @@ You can use monitary values within computations, as in - $m1 = Compute('$10.00'); - $m2 = 3*$m1; $m3 = $m2 + .5; - $m4 = Compute('$10.00 + $2.59'); + $m1 = Compute('$10.00'); + $m2 = 3*$m1; $m3 = $m2 + .5; + $m4 = Compute('$10.00 + $2.59'); so that $m2 will be $30.00, $m3 will be $30.50, and $m4 will be $12.59. Students can perform computations within their @@ -77,19 +80,19 @@ to the nearest penny. You can change that on a global basis using - Context()->flags->set(tolerance=>.0001,tolType=>"relative"); + Context()->flags->set(tolerance=>.0001,tolType=>"relative"); for example. You can also change the tolerance on an individual currency value as follows: - $m = Compute('$1,250,000.00')->with(tolerance=>.0001,tolType=>'relative'); + $m = Compute('$1,250,000.00')->with(tolerance=>.0001,tolType=>'relative'); By default, the answer checker for Currency values requires the student to enter the currency symbol, not just a real number. You can relax that condition by including the promoteReals=>1 option to the cmp() method of the Currency value. For example, - ANS(Compute('$150')->cmp(promoteReals=>1)); + ANS(Compute('$150')->cmp(promoteReals=>1)); would allow the student to enter just 150 rather than $150. @@ -97,19 +100,19 @@ force them to supply the commas using forceCommas=>1 in your cmp() call. - ANS(Compute('$10,000.00')->cmp(forceCommas=>1)); + ANS(Compute('$10,000.00')->cmp(forceCommas=>1)); By default, students need not enter decimal digits, so could use $100 or $1,000. as valid entries. You can require that the cents be provided using the forceDecimals=>1 flag. - ANS(Compute('$10.95')->cmp(forceDecimals=>1)); + ANS(Compute('$10.95')->cmp(forceDecimals=>1)); By default, if the monitary value includes decimals digits, it must have exactly two. You can weaken this requirement to all any number of decimals by using noExtraDecimals=>0. - ANS(Compute('$10.23372')->cmp(noExtraDecimals=>0); + ANS(Compute('$10.23372')->cmp(noExtraDecimals=>0); If forceDecimals is set to 1 at the same time, then they must have 2 or more decimals, otherwise any number is OK. Index: contextABCD.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextABCD.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextABCD.pl -Lmacros/contextABCD.pl -u -r1.11 -r1.12 --- macros/contextABCD.pl +++ macros/contextABCD.pl @@ -10,8 +10,8 @@ There are two contexts defined here, - Context("ABCD"); - Context("ABCD-List"); + Context("ABCD"); + Context("ABCD-List"); The second allows the students to enter lists of strings, while the first does not. @@ -20,12 +20,12 @@ via the Context()->strings->add() and Context()-strings->remove() methods, eg. - Context("ABCD-List")->strings->add(E=>{},e=>{alias=>"E"}); + Context("ABCD-List")->strings->add(E=>{},e=>{alias=>"E"}); Use string_cmp() to produce the answer checker(s) for your correct values. Eg. - ANS(string_cmp("A","B")); + ANS(string_cmp("A","B")); when there are two answers, the first being "A" and the second being "B". Index: answerHints.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerHints.pl,v retrieving revision 1.4 retrieving revision 1.5 diff -Lmacros/answerHints.pl -Lmacros/answerHints.pl -u -r1.4 -r1.5 --- macros/answerHints.pl +++ macros/answerHints.pl @@ -66,25 +66,25 @@ Example: - ANS(Vector(1,2,3)->cmp(showCoordinateHints=>0)->withPostFilter(AnswerHints( - Vector(0,0,0) => "The zero vector is not a valid solution", - "-<1,2,3>" => "Try the opposite direction", - "<1,2,3>" => "Well done!", - ["<1,1,1>","<2,2,2>","<3,3,3>"] => "Don't just guess!", - sub { - my ($correct,$student,$ans) = @_; - return $correct . $student == 0; - } => "Your answer is perpendicular to the correct one", - Vector(1,2,3) => [ - "You have the right direction, but not length", - cmp_options => [parallel=>1], - ], - 0 => ["Careful, your answer should be a vector!", checkTypes => 0, replaceMessage => 1], - sub { - my ($correct,$student,$ans) = @_; - return norm($correct-$student) < .1; - } => ["Close! Keep trying.", score => .25], - ))); + ANS(Vector(1,2,3)->cmp(showCoordinateHints=>0)->withPostFilter(AnswerHints( + Vector(0,0,0) => "The zero vector is not a valid solution", + "-<1,2,3>" => "Try the opposite direction", + "<1,2,3>" => "Well done!", + ["<1,1,1>","<2,2,2>","<3,3,3>"] => "Don't just guess!", + sub { + my ($correct,$student,$ans) = @_; + return $correct . $student == 0; + } => "Your answer is perpendicular to the correct one", + Vector(1,2,3) => [ + "You have the right direction, but not length", + cmp_options => [parallel=>1], + ], + 0 => ["Careful, your answer should be a vector!", checkTypes => 0, replaceMessage => 1], + sub { + my ($correct,$student,$ans) = @_; + return norm($correct-$student) < .1; + } => ["Close! Keep trying.", score => .25], + ))); =cut Index: contextLimitedPowers.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPowers.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextLimitedPowers.pl -Lmacros/contextLimitedPowers.pl -u -r1.11 -r1.12 --- macros/contextLimitedPowers.pl +++ macros/contextLimitedPowers.pl @@ -8,17 +8,17 @@ the base or power that is allowed. There are four available restrictions: - No raising e to a power - Only allowing integer powers (positive or negative) - Only allowing positive interger powers - Only allowing positive interger powers (and 0) + No raising e to a power + Only allowing integer powers (positive or negative) + Only allowing positive interger powers + Only allowing positive interger powers (and 0) You install these via one of the commands: - LimitedPowers::NoBaseE(); - LimitedPowers::OnlyIntegers(); - LimitedPowers::OnlyPositiveIntegers(); - LimitedPowers::OnlyNonNegativeIntegers(); + LimitedPowers::NoBaseE(); + LimitedPowers::OnlyIntegers(); + LimitedPowers::OnlyPositiveIntegers(); + LimitedPowers::OnlyNonNegativeIntegers(); Only one of the three can be in effect at a time; setting a second one overrides the first. @@ -26,8 +26,8 @@ These function affect the current context, or you can pass a context reference, as in - $context = Context("Numeric")->copy; - LimitedPowers::OnlyIntegers($context); + $context = Context("Numeric")->copy; + LimitedPowers::OnlyIntegers($context); For the Interger power functions, you can pass additional parameters that control the range of values that are allowed Index: contextTF.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextTF.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/contextTF.pl -Lmacros/contextTF.pl -u -r1.12 -r1.13 --- macros/contextTF.pl +++ macros/contextTF.pl @@ -7,7 +7,7 @@ Implements contexts for string-valued answers especially for matching problems (where you match against T and F). - Context("TF"); + Context("TF"); You can add new strings to the context as needed (or remove old ones) via the Context()->strings->add() and Context()-strings->remove() @@ -15,7 +15,7 @@ Use: - ANS(string_cmp("T","F")); + ANS(string_cmp("T","F")); when there are two answers, the first being "T" and the second being "F". Index: problemRandomize.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/problemRandomize.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/problemRandomize.pl -Lmacros/problemRandomize.pl -u -r1.9 -r1.10 --- macros/problemRandomize.pl +++ macros/problemRandomize.pl @@ -100,11 +100,11 @@ Examples: - ProblemRandomize(); # use all defaults - ProblemRandomize(when=>"Always"); # always can reseed (after due date) + ProblemRandomize(); # use all defaults + ProblemRandomize(when=>"Always"); # always can reseed (after due date) ProblemRandomize(onlyAfterDue=>0); # can reseed whenever correct ProblemRandomize(when=>"always",onlyAfterDue=>0); # always can reseed - ProblemRandomize(style=>"Input"); # use an input box to set the seed + ProblemRandomize(style=>"Input"); # use an input box to set the seed For problems that include "PGcourse.pl" in their loadMacros() calls, you can use that file to provide reseed buttons for ALL problems simply by including Index: parserFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFunction.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/parserFunction.pl -Lmacros/parserFunction.pl -u -r1.10 -r1.11 --- macros/parserFunction.pl +++ macros/parserFunction.pl @@ -13,14 +13,14 @@ students in their answers), use the parserFunction() routine, as in the following examples: - parserFunction(f => "sqrt(x+1)-2"); + parserFunction(f => "sqrt(x+1)-2"); - $x = Formula('x'); - parserFunction(f => sqrt($x+1)-2); + $x = Formula('x'); + parserFunction(f => sqrt($x+1)-2); - parserFunction("f(x)" => "sqrt(x+1)-2"); + parserFunction("f(x)" => "sqrt(x+1)-2"); - parserFunction("f(x,y)" => "sqrt(x*y)"); + parserFunction("f(x,y)" => "sqrt(x*y)"); The first parameter to parserFunction is the name of the function or the name with its argument list. In the first case, the Index: contextIntegerFunctions.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextIntegerFunctions.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/contextIntegerFunctions.pl -Lmacros/contextIntegerFunctions.pl -u -r1.9 -r1.10 --- macros/contextIntegerFunctions.pl +++ macros/contextIntegerFunctions.pl @@ -15,11 +15,11 @@ =head1 USAGE - Context("IntegerFunctions") - - $b = random(2, 5); $a = $b+random(0, 5); - $c = C($a, $b); - ANS(Compute("P($a, $b)")->cmp); + Context("IntegerFunctions") + + $b = random(2, 5); $a = $b+random(0, 5); + $c = C($a, $b); + ANS(Compute("P($a, $b)")->cmp); B<Note:> If the context is set to something else, such as Numeric, it can be set back with Context("IntegerFunctions"). Index: contextLimitedPolynomial.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPolynomial.pl,v retrieving revision 1.15 retrieving revision 1.16 diff -Lmacros/contextLimitedPolynomial.pl -Lmacros/contextLimitedPolynomial.pl -u -r1.15 -r1.16 --- macros/contextLimitedPolynomial.pl +++ macros/contextLimitedPolynomial.pl @@ -9,17 +9,17 @@ Select the context using: - Context("LimitedPolynomial"); + Context("LimitedPolynomial"); If you set the "singlePowers" flag, then only one monomial of each degree can be included in the polynomial: - Context("LimitedPolynomial")->flags->set(singlePowers=>1); + Context("LimitedPolynomial")->flags->set(singlePowers=>1); There is also a strict limited context that does not allow operations even within the coefficients. Select it using: - Context("LimitedPolynomial-Strict"); + Context("LimitedPolynomial-Strict"); In addition to disallowing operations within the coefficients, this context does not reduce constant operations (since they are Index: parserAutoStrings.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserAutoStrings.pl,v retrieving revision 1.2 retrieving revision 1.3 diff -Lmacros/parserAutoStrings.pl -Lmacros/parserAutoStrings.pl -u -r1.2 -r1.3 --- macros/parserAutoStrings.pl +++ macros/parserAutoStrings.pl @@ -10,8 +10,8 @@ To acocmplish this, put the lines - loadMacros("parserAutoStrings.pl"); - AutoStrings(); + loadMacros("parserAutoStrings.pl"); + AutoStrings(); (You can also pass AutoStrings a context pointer if you wish to alter context other than the current one.) @@ -19,8 +19,8 @@ There is also a routine to help making strings easier to predefine. For example: - loadMacros("parserAutoStrings.pl"); - DefineStrings("string1","string2"); + loadMacros("parserAutoStrings.pl"); + DefineStrings("string1","string2"); would define two new strings (string1 and string2). You can pass a context reference as the first argument to add strings to that Index: parserFormulaUpToConstant.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFormulaUpToConstant.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/parserFormulaUpToConstant.pl -Lmacros/parserFormulaUpToConstant.pl -u -r1.8 -r1.9 --- macros/parserFormulaUpToConstant.pl +++ macros/parserFormulaUpToConstant.pl @@ -13,11 +13,11 @@ To use FormulaWithConstat objects, load this macro file at the top of your problem: - loadMacros("parserFormulaUpToConstant.pl"); + loadMacros("parserFormulaUpToConstant.pl"); then create a formula with constant as follows: - $f = FormulaUpToConstant("sin(x)+C"); + $f = FormulaUpToConstant("sin(x)+C"); Note that the C should NOT already be a variable in the Context; the FormulaUpToConstant object will handle adding it in for @@ -28,7 +28,7 @@ The FormulaUpToConstant should work like any normal Formula, and in particular, you use $f->cmp to get its answer checker. - ANS($f->cmp); + ANS($f->cmp); Note that the FormulaUpToConstant object creates its only private copy of the current Context (so that it can add variables without @@ -36,19 +36,19 @@ in general, but if you need to access that context, use $f->{context}. E.g. - Context($f->{context}); + Context($f->{context}); would make the current context the one being used by the FormulaUpToConstant, while - $f->{context}->variables->names + $f->{context}->variables->names would return a list of the variables in the private context. To get the name of the constant in use in the formula, use - $f->constant. + $f->constant. If you combine a FormulaUpToConstant with other formulas, the result will be a new FormulaUpToConstant object, with @@ -58,16 +58,16 @@ then convert back to a FormulaUpToConstant, if necessary. To do this, use the removeConstant() method: - $f = FormulaUpToConstant("sin(x)+C"); - $g = Formula("cos(x)"); - $h = $f->removeConstant + $g; # $h will be "sin(x)+cos(x)" - $h = FormulaUpToConstant($h); # $h will be "sin(x)+cos(x)+C" + $f = FormulaUpToConstant("sin(x)+C"); + $g = Formula("cos(x)"); + $h = $f->removeConstant + $g; # $h will be "sin(x)+cos(x)" + $h = FormulaUpToConstant($h); # $h will be "sin(x)+cos(x)+C" The answer evaluator by default will give "helpful" messages to the student when the "+ C" is left out. You can turn off these messages using the showHints option to the cmp() method: - ANS($f->cmp(showHints => 0)); + ANS($f->cmp(showHints => 0)); One of the hints is about whether the student's answer is linear in the arbitrary constant. This test requires differentiating @@ -75,7 +75,7 @@ problematic, you can disable that test via the showLinearityHints flag. (Note: setting showHints to 0 also disables these hints.) - ANS($f->cmp(showLinearityHints => 0)); + ANS($f->cmp(showLinearityHints => 0)); =cut |
From: Sam H. v. a. <we...@ma...> - 2007-10-03 18:55:18
|
Log Message: ----------- reformatted documentation for the rest of the MathObjects-related macros Modified Files: -------------- pg/macros: parserImplicitEquation.pl parserImplicitPlane.pl parserMultiAnswer.pl parserMultiPart.pl parserNumberWithUnits.pl parserParametricLine.pl parserPopUp.pl parserRadioButtons.pl parserSolutionFor.pl parserVectorUtils.pl problemPreserveAnswers.pl problemRandomize.pl Revision Data ------------- Index: parserRadioButtons.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserRadioButtons.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/parserRadioButtons.pl -Lmacros/parserRadioButtons.pl -u -r1.8 -r1.9 --- macros/parserRadioButtons.pl +++ macros/parserRadioButtons.pl @@ -1,73 +1,87 @@ -loadMacros('MathObjects.pl','contextString.pl'); +=head1 NAME -sub _parserRadioButtons_init {parserRadioButtons::Init()}; # don't reload this file +parserRadioButtons.pl - Radio buttons compatible with Value objects, specifically MultiAnswer objects. =head1 DESCRIPTION - #################################################################### - # - # This file implements a radio button group object that is compatible - # with Value objects, and in particular, with the MultiPart object. - # - # To create a RadioButtons object, use - # - # $radio = RadioButtons([choices,...],correct,options); - # - # where "choices" are the strings for the items in the radio buttons, - # "correct" is the choice that is the correct answer for the group, - # and options are chosen from among: - # - # labels => [label1,...] Specifies the text to be used - # as the student answer for each - # entry in the radio group. - # This can also be set to the string - # "ABC" to get lettered labels or - # "123" to get numbered labels. - # The default is to use a few words - # from the text string for each button. - # - # separator => string text to put between the radio - # buttons. - # Default: $BR - # - # checked => choice the text or index (starting at zero) - # of the button to be checked - # Default: none checked - # - # maxLabelSize => n the approximate largest size that should - # be used for the answer strings to be - # generated by the radio buttons (if - # the choice strings are too long, they - # will be trimmed and "..." inserted) - # Default: 25 - # - # uncheckable => 0 or 1 determines whether the radio buttons can - # or "shift" be unchecked (requires JavaScript). - # To uncheck, click a second time; when - # set to "shift", unchecking requires the - # shift key to be pressed. - # Default: 0 - # - # - # To insert the radio buttons into the problem text, use - # - # BEGIN_TEXT - # \{$radio->buttons\} - # END_TEXT - # - # and then - # - # ANS($radio->cmp); - # - # to get the answer checker for the radion buttons. - # - # You can use the RadioButtons object in MultiPart objects. This is - # the reason for the RadioButton's ans_rule method (since that is what - # MultiPart calls to get answer rules). - # +This file implements a radio button group object that is compatible +with Value objects, and in particular, with the MultiAnswer object. + +To create a RadioButtons object, use + + $radio = RadioButtons([choices,...],correct,options); + +where "choices" are the strings for the items in the radio buttons, +"correct" is the choice that is the correct answer for the group, +and options are chosen from among: + +=over + +=item C<S<< labels => [label1,...] >>> + +Specifies the text to be used +as the student answer for each +entry in the radio group. +This can also be set to the string +"ABC" to get lettered labels or +"123" to get numbered labels. +The default is to use a few words +from the text string for each button. + +=item C<S<< separator => string >>> + +text to put between the radio +buttons. +Default: $BR + +=item C<S<< checked => choice >>> + +the text or index (starting at zero) +of the button to be checked +Default: none checked + +=item C<S<< maxLabelSize => n >>> + +the approximate largest size that should +be used for the answer strings to be +generated by the radio buttons (if +the choice strings are too long, they +will be trimmed and "..." inserted) +Default: 25 + +=item C<S<< uncheckable => 0 or 1 or "shift" >>> + +determines whether the radio buttons can +be unchecked (requires JavaScript). +To uncheck, click a second time; when +set to "shift", unchecking requires the +shift key to be pressed. +Default: 0 + +=back + +To insert the radio buttons into the problem text, use + + BEGIN_TEXT + \{$radio->buttons\} + END_TEXT + +and then + + ANS($radio->cmp); + +to get the answer checker for the radion buttons. + +You can use the RadioButtons object in MultiPart objects. This is +the reason for the RadioButton's ans_rule method (since that is what +MultiPart calls to get answer rules). =cut +loadMacros('MathObjects.pl','contextString.pl'); + +sub _parserRadioButtons_init {parserRadioButtons::Init()}; # don't reload this file + ################################################## # # The package that implements RadioButtons Index: parserImplicitEquation.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserImplicitEquation.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/parserImplicitEquation.pl -Lmacros/parserImplicitEquation.pl -u -r1.9 -r1.10 --- macros/parserImplicitEquation.pl +++ macros/parserImplicitEquation.pl @@ -1,132 +1,173 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _parserImplicitEquation_init {ImplicitEquation::Init()}; # don't reload this file +parserImplicitEquation.pl - An answer checker for implicit equations. =head1 DESCRIPTION - ###################################################################### - # - # This is a MathObject class that implements an answer checker for - # implicitly defined equations. The checker looks for the zeros of - # the equation and tests that the student and professor equations - # both have the same solutions. - # - # This type of check is very subtle, and there are important issues - # that you may have to take into account. The solutions to the - # equations are found numerically, and so they will not be exact; - # that means that there are tolerances that may need to be adjusted - # for your particular equation. Also, it is always possible for the - # student to represent the function in a form that will exceed those - # tolerances, and so be marked as incorrect. The answer checker - # attempts to set the parameters based on the values of the functions - # involved, but this may not work perfectly. - # - # The method used to locate the solutions of A=B is by finding zeros - # of A-B, and it requires this function to take on both positive and - # negative values (that is, it can only find transverse intersections - # of the surface A-B=0 and the plane at height 0). For example, even - # though the solutions of (x^2+y^1-1)^2=0 form a circle, the - # algorithm will fail to find any solutions for this equation. - # - # In order to locate the zeros, you may need to change the limits so - # that they include regions where the function is both positive and - # negative (see below). The algorithm will avoid discontinuities, so - # you can specify things like x-y=1/(x+y) rather than x^2-y^2=1. - # - # Because the solutions are found using a random search, it is - # possible the randomly chosen starting points don't locate enough - # zeros for the function, in which case the check will fail. This - # can happen for both the professor's function and the student's, - # since zeros are found for both. This means that a correct answer - # can sometimes be marked incorrect depending on the random points - # chosen initially. These points also affect the values selected for - # the tolerances used to determine when a function's value is zero, - # and so can affect whether the student's function is marked as - # correct or not. - # - # If an equation has several components or branches, it is possible - # that the random location of solutions will not find zeros on some - # of the branches, and so might incorrectly mark as correct an - # equation that only is zero on one of the components. For example, - # x^2-y^2=0 has solutions along the lines y=x and y=-x, so it is - # possible that x-y=0 or x+y=0 will be marked as correct if the - # random points are unluckily chosen. One way to reduce this problem - # is to increase the number of solutions that are required (by - # setting the ImplicitPoints flag in the Context). Another is to - # specify the solutions yourself, so that you are sure there are - # points on each component. - # - # These problems should be rare, and the values for the various - # parameters have been set in an attempt to minimize the possibility - # of these errors, but they can occur, and you should be aware of - # them, and their possible solutions. - # - # - # Usage examples: - # - # Context("ImplicitEquation"); - # $f = ImplicitEquation("x^2 = cos(y)"); - # $f = ImplicitEquation("x^2 - 2y^2 = 5",limits=>[[-3,3],[-2,2]]); - # $f = ImplicitEquation("x=1/y",tolerance=>.0001); - # - # Then use - # - # ANS($f->cmp); - # - # to get the answer checker for $f. - # - # There are a number of Context flags that control the answer checker. - # These include: - # - # ImplicitPoints => 7 (the number of solutions to test) - # ImplicitTolerance => 1E-6 (relative tolerance value for when - # the tested function is zero) - # ImplicitAbsoluteMinTolerance => 1E-3 (the minimum tolerance allowed) - # ImplicitAbsoluteMaxTolerance => 1E-3 (the maximum tolerance allowed) - # ImplicitPointTolerance => 1E-9 (relative tolerance for how close - # the solution point must be to an - # actual solution) - # BisectionTolerance => .01 (extra factor used for the tolerance - # when finding the solutions) - # BisectionCutoff => 40 (maximum number of bisections to - # perform when looking for a solution) - # - # You may set any of these using Context()->flags->set(...). - # - # In addition to the Context flags, you can set some values within - # the ImplicitEquation itself: - # - # tolerance (the absolute tolerance for zeros of the function) - # bisect_tolerance (the tolerance used when searching for zeros) - # point_tolerance (the absolute tolerance for how close to an - # actual solution the located solution must be) - # limits (the domain to use for the function; see the - # documentation for the Formula object) - # solutions (a reference to an array of references to arrays - # that contain the coordinates of the points - # that are the solutions of the equation) - # - # These can be set in the in the ImplicitEquation() call that creates - # the object, as in the examples below: - # - # For example: - # - # $f = ImplicitEquation("x^2-y^2=0", - # solutions => [[0,0],[1,1],[-1,1],[-1,-1],[1,-1]], - # tolerance => .001 - # ); - # - # - # $f = ImplicitEquation("xy=5",limits=>[-3,3]); - # - # The limits value can be set globally within the Context, if you wish, - # and the others can be controlled by the Context flags discussed - # above. - # - ###################################################################### +This is a MathObject class that implements an answer checker for +implicitly defined equations. The checker looks for the zeros of +the equation and tests that the student and professor equations +both have the same solutions. + +This type of check is very subtle, and there are important issues +that you may have to take into account. The solutions to the +equations are found numerically, and so they will not be exact; +that means that there are tolerances that may need to be adjusted +for your particular equation. Also, it is always possible for the +student to represent the function in a form that will exceed those +tolerances, and so be marked as incorrect. The answer checker +attempts to set the parameters based on the values of the functions +involved, but this may not work perfectly. + +The method used to locate the solutions of A=B is by finding zeros +of A-B, and it requires this function to take on both positive and +negative values (that is, it can only find transverse intersections +of the surface A-B=0 and the plane at height 0). For example, even +though the solutions of (x^2+y^1-1)^2=0 form a circle, the +algorithm will fail to find any solutions for this equation. + +In order to locate the zeros, you may need to change the limits so +that they include regions where the function is both positive and +negative (see below). The algorithm will avoid discontinuities, so +you can specify things like x-y=1/(x+y) rather than x^2-y^2=1. + +Because the solutions are found using a random search, it is +possible the randomly chosen starting points don't locate enough +zeros for the function, in which case the check will fail. This +can happen for both the professor's function and the student's, +since zeros are found for both. This means that a correct answer +can sometimes be marked incorrect depending on the random points +chosen initially. These points also affect the values selected for +the tolerances used to determine when a function's value is zero, +and so can affect whether the student's function is marked as +correct or not. + +If an equation has several components or branches, it is possible +that the random location of solutions will not find zeros on some +of the branches, and so might incorrectly mark as correct an +equation that only is zero on one of the components. For example, +x^2-y^2=0 has solutions along the lines y=x and y=-x, so it is +possible that x-y=0 or x+y=0 will be marked as correct if the +random points are unluckily chosen. One way to reduce this problem +is to increase the number of solutions that are required (by +setting the ImplicitPoints flag in the Context). Another is to +specify the solutions yourself, so that you are sure there are +points on each component. + +These problems should be rare, and the values for the various +parameters have been set in an attempt to minimize the possibility +of these errors, but they can occur, and you should be aware of +them, and their possible solutions. + +Usage examples: + + Context("ImplicitEquation"); + $f = ImplicitEquation("x^2 = cos(y)"); + $f = ImplicitEquation("x^2 - 2y^2 = 5",limits=>[[-3,3],[-2,2]]); + $f = ImplicitEquation("x=1/y",tolerance=>.0001); + +Then use + + ANS($f->cmp); + +to get the answer checker for $f. + +There are a number of Context flags that control the answer checker. +These include: + +=over + +=item C<S<< ImplicitPoints => 7 >>> + +the number of solutions to test. + +=item C<S<< ImplicitTolerance => 1E-6 >>> + +relative tolerance value for when +the tested function is zero. + +=item C<S<< ImplicitAbsoluteMinTolerance => 1E-3 >>> + +the minimum tolerance allowed. + +=item C<S<< ImplicitAbsoluteMaxTolerance => 1E-3 >>> + +the maximum tolerance allowed. + +=item C<S<< ImplicitPointTolerance => 1E-9 >>> + +relative tolerance for how close +the solution point must be to an +actual solution. + +=item C<S<< BisectionTolerance => .01 >>> + +extra factor used for the tolerance +when finding the solutions. + +=item C<S<< BisectionCutoff => 40 >>> + +maximum number of bisections to +perform when looking for a solution. + +=back + +You may set any of these using Context()->flags->set(...). + +In addition to the Context flags, you can set some values within +the ImplicitEquation itself: + +=over + +=item C<S<< tolerance >>> + +the absolute tolerance for zeros of the function. + +=item C<S<< bisect_tolerance >>> + +the tolerance used when searching for zeros. + +=item C<S<< point_tolerance >>> + +the absolute tolerance for how close to an +actual solution the located solution must be. + +=item C<S<< limits >>> + +the domain to use for the function; see the +documentation for the Formula object. + +=item C<S<< solutions >>> + +a reference to an array of references to arrays +that contain the coordinates of the points +that are the solutions of the equation. + +=back + +These can be set in the in the ImplicitEquation() call that creates +the object, as in the examples below: + +For example: + + $f = ImplicitEquation("x^2-y^2=0", + solutions => [[0,0],[1,1],[-1,1],[-1,-1],[1,-1]], + tolerance => .001 + ); + + + $f = ImplicitEquation("xy=5",limits=>[-3,3]); + +The limits value can be set globally within the Context, if you wish, +and the others can be controlled by the Context flags discussed +above. =cut +loadMacros("MathObjects.pl"); + +sub _parserImplicitEquation_init {ImplicitEquation::Init()}; # don't reload this file + # # Create the ImplicitEquation package # Index: problemPreserveAnswers.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/problemPreserveAnswers.pl,v retrieving revision 1.4 retrieving revision 1.5 diff -Lmacros/problemPreserveAnswers.pl -Lmacros/problemPreserveAnswers.pl -u -r1.4 -r1.5 --- macros/problemPreserveAnswers.pl +++ macros/problemPreserveAnswers.pl @@ -1,33 +1,32 @@ +=head1 NAME -sub _problemPreserveAnswers_init {PreserveAnswers::Init()} +problemPreserveAnswers.pl - Allow sticky answers to preserve special characters. + +=head1 DESCRIPTION + +This file implements a fragile hack to overcome a problem with +PGbasicmacros.pl, which removes special characters from student +answers (in order to prevent EV3 from mishandling them). + +Unfortunately, this means that "sticky" answers will lose +those characters, which makes it very difficult to answer +problems with more than one answer when the student wants +to submit several times while working on later parts. -=head1 PreserveAnswers(); +The real fix to to rewrite PGbasicmacros.pl to handle +this better, but this hack will handle the situation for +now until that can be accomplished. - ###################################################################### - # - # This file implements a fragile hack to overcome a problem with - # PGbasicmacros.pl, which removes special characters from student - # answers (in order to prevent EV3 from mishandling them). - # - # Unfortunately, this means that "sticky" answers will lose - # those characters, which makes it very difficult to answer - # problems with more than one answer when the student wants - # to submit several times while working on later parts. - # - # The real fix to to rewrite PGbasicmacros.pl to handle - # this better, but this hack will handle the situation for - # now until that can be accomplished. - # - # To use this hack, simply load the file using - # - # loadMacros("problemPreserveAnswers.pl"); - # - # at the top of your PG file. - # - ###################################################################### +To use this hack, simply load the file using + + loadMacros("problemPreserveAnswers.pl"); + +at the top of your PG file. =cut +sub _problemPreserveAnswers_init {PreserveAnswers::Init()} + package PreserveAnswers; # Index: parserParametricLine.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserParametricLine.pl,v retrieving revision 1.12 retrieving revision 1.13 diff -Lmacros/parserParametricLine.pl -Lmacros/parserParametricLine.pl -u -r1.12 -r1.13 --- macros/parserParametricLine.pl +++ macros/parserParametricLine.pl @@ -1,46 +1,47 @@ -loadMacros('MathObjects.pl'); +=head1 NAME -sub _parserParametricLine_init {ParametricLine::Init()}; # don't reload this file +parserParametricLine.pl - Implements Formulas that represent parametric lines. =head1 DESCRIPTION - ###################################################################### - # - # This is a Parser class that implements parametric lines as - # a subclass of the Formula class. The standard ->cmp routine - # will work for this, provided we define the compare() function - # needed by the overloaded ==. We assign the special precedence - # so that overloaded operations will be promoted to the ones below. - # - # Use ParametricLine(point,vector) or ParametricLine(formula) - # to create a ParametricLine object. You can pass an optional - # additional parameter that indicated the variable to use for the - # parameter for the line. - # - # Usage examples: - # - # $L = ParametricLine(Point(3,-1,2),Vector(1,1,3)); - # $L = ParametricLine([3,-1,2],[1,1,3]); - # $L = ParametricLine("<t,1-t,2t-3>"); - # - # $p = Point(3,-1,2); $v = Vector(1,1,3); - # $L = ParametricLine($p,$v); - # - # $t = Formula('t'); $p = Point(3,-1,2); $v = Vector(1,1,3); - # $L = ParametricLine($p+$t*$v); - # - # Context()->constants->are(a=>1+pi^2); # won't guess this value - # $L = ParametricLine("(a,2a,-1) + t <1,a,a^2>"); - # - # Then use - # - # ANS($L->cmp); - # - # to get the answer checker for $L. - # +This is a Parser class that implements parametric lines as +a subclass of the Formula class. The standard ->cmp routine +will work for this, provided we define the compare() function +needed by the overloaded ==. We assign the special precedence +so that overloaded operations will be promoted to the ones below. + +Use ParametricLine(point,vector) or ParametricLine(formula) +to create a ParametricLine object. You can pass an optional +additional parameter that indicated the variable to use for the +parameter for the line. + +Usage examples: + + $L = ParametricLine(Point(3,-1,2),Vector(1,1,3)); + $L = ParametricLine([3,-1,2],[1,1,3]); + $L = ParametricLine("<t,1-t,2t-3>"); + + $p = Point(3,-1,2); $v = Vector(1,1,3); + $L = ParametricLine($p,$v); + + $t = Formula('t'); $p = Point(3,-1,2); $v = Vector(1,1,3); + $L = ParametricLine($p+$t*$v); + + Context()->constants->are(a=>1+pi^2); # won't guess this value + $L = ParametricLine("(a,2a,-1) + t <1,a,a^2>"); + +Then use + + ANS($L->cmp); + +to get the answer checker for $L. =cut +loadMacros('MathObjects.pl'); + +sub _parserParametricLine_init {ParametricLine::Init()}; # don't reload this file + # # Define the subclass of Formula # Index: parserMultiPart.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserMultiPart.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/parserMultiPart.pl -Lmacros/parserMultiPart.pl -u -r1.10 -r1.11 --- macros/parserMultiPart.pl +++ macros/parserMultiPart.pl @@ -1,17 +1,17 @@ -sub _parserMultiPart_init {} +=head1 NAME + +parserMultiPart.pl - [DEPRECATED] Renamed to MultiAnswer. -=head3 MultiPart +=head1 DESCRIPTION - ###################################################################### - # - # This object has been renamed MultiAnswer and is now available in - # parserMultiAnswer.pl. Using a MultiPart object will produce a - # warning to that effect. - # - ###################################################################### +This object has been renamed MultiAnswer and is now available in +parserMultiAnswer.pl. Using a MultiPart object will produce a +warning to that effect. =cut +sub _parserMultiPart_init {} + loadMacros("parserMultiAnswer.pl"); sub MultiPart { warn "The MultiPart object has been depricated.${BR}You should use MultiAnswer object instead"; Index: parserVectorUtils.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserVectorUtils.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/parserVectorUtils.pl -Lmacros/parserVectorUtils.pl -u -r1.5 -r1.6 --- macros/parserVectorUtils.pl +++ macros/parserVectorUtils.pl @@ -1,27 +1,27 @@ +=head1 NAME + +parserVectorUtils.pl - Utility macros that are useful in vector problems. =head1 DESCRIPTION - ##################################################################### - # - # Some utility routines that are useful in vector problems - # +Some utility routines that are useful in vector problems =cut sub _parserVectorUtils_init {}; # don't reload this file -=head3 Overline($vectorName) +=head1 MACROS + +=head2 Overline + + Overline($vectorName) - ################################################## +formats a vector name (should be used in math mode) - # - # formats a vector name (should be used in math mode) - # - # Vectors will be in bold italics in HTML modes, and - # will be overlined in TeX modes. (Bold italic could also work in - # TeX modes, but the low resolution on screen made it less easy - # to distinguish the difference between bold and regular letters.) - # +Vectors will be in bold italics in HTML modes, and +will be overlined in TeX modes. (Bold italic could also work in +TeX modes, but the low resolution on screen made it less easy +to distinguish the difference between bold and regular letters.) =cut @@ -36,15 +36,15 @@ ); } -=head3 BoldMath($vectorName) +=head2 BoldMath - # - # This gets a bold letter in TeX as well as HTML modes. - # Although \boldsymbol{} works fine on screen in latex2html mode, - # the PDF file produces non-bold letters. I haven't been able to - # track this down, so used \mathbf{} in TeX mode, which produces - # roman bold, not math-italic bold. - # + BoldMath($vectorName) + +This gets a bold letter in TeX as well as HTML modes. +Although \boldsymbol{} works fine on screen in latex2html mode, +the PDF file produces non-bold letters. I haven't been able to +track this down, so used \mathbf{} in TeX mode, which produces +roman bold, not math-italic bold. =cut @@ -61,28 +61,32 @@ ); } -=head3 $GRAD +=head2 $GRAD + + TEXT($GRAD) - # - # Grad symbol - # + BEGIN_TEXT + $GRAD + END_TEXT + +Grad symbol. =cut $GRAD = '\nabla '; -=head3 non_zero_point($Dim,$L_bound,$U_bound,$step) +=head2 non_zero_point + + non_zero_point($Dim,$L_bound,$U_bound,$step) + +Create a non-zero point with the given number of coordinates +with the given random range (which defaults to (-5,5,1)). + +non_zero_point(n,a,b,c) +non_zero_point_2D(a,b,c) +non_zero_point_3D(a,b,c) - # - # Create a non-zero point with the given number of coordinates - # with the given random range (which defaults to (-5,5,1)). - # - # non_zero_point(n,a,b,c) - # non_zero_point_2D(a,b,c) - # non_zero_point_3D(a,b,c) - # - # non_zero_point2D and 3D automatically set Dimension to 2 and 3 respectively. - # +non_zero_point2D and 3D automatically set Dimension to 2 and 3 respectively. =cut @@ -96,13 +100,16 @@ sub non_zero_point2D {non_zero_point(2,@_)} sub non_zero_point3D {non_zero_point(3,@_)} -=head3 non_zero_vector($Dim,$L_bound,$U_bound,$step) +=head2 non_zero_vector, non_zero_vector2D, non_zero_vector3D - # - # Functions the same as non_zero_point but for Vectors - # - # non_zero_vector2D and 3D automatically set Dimension to 2 and 3 respectively. - # + non_zero_vector($Dim,$L_bound,$U_bound,$step) + + non_zero_vector2D($L_bound,$U_bound,$step) + + non_zero_vector3D($L_bound,$U_bound,$step) + +Functions the same as non_zero_point but for Vectors. non_zero_vector2D and +non_zero_vector3D automatically set Dimension to 2 and 3 respectively. =cut @@ -110,22 +117,25 @@ sub non_zero_vector2D {non_zero_vector(2,@_)} sub non_zero_vector3D {non_zero_vector(3,@_)} -=head3 Line(Point(@coords1),Vector(@coords2),'variableLetter') +=head2 Line + + $P = Point(@coords1); + $V = Vector(@coords2); + $t = 't'; + Line($P,$V); + Line($P,$V,$t); - # - # Form the vector-parametric form for a line given its point and vector - # - # Usage: Line(P,V); or Line(P,V,'t'); - # - # where P is the point and V the direction vector for the line, and - # t is the variable to use (default is 't'). - # - # Ex: Line([1,-3],[2,1]) produces Vector("1+2t","-3+t"). - # Ex: Line(Point(1,-3),Vector(2,1)) produces Vector("1+2t","-3+t"). - # - # (It may be better to use the ParametricLine class from - # parserParametricLine.pl). - # +Form the vector-parametric form for a line given its point and vector, where $P +is the point and $V the direction vector for the line, and $t is the variable to +use (default is 't'). + +For example: + + Line([1,-3],[2,1]); # produces Vector("1+2t","-3+t"). + Line(Point(1,-3),Vector(2,1)); # produces Vector("1+2t","-3+t"). + +(It may be better to use the ParametricLine class from +parserParametricLine.pl). =cut @@ -138,15 +148,13 @@ return Vector(@coords); } -=head3 Plane($point,$NormalVector) +=head2 Plane + + Plane($point,$NormalVector) - # - # Creates a displayable string for a plane given its - # normal vector and a point on the plane. (Better to use - # the ImplicitPlane class from parserImplicitPlane.pl). - # - # Usage: Plane(P,N); - # +Creates a displayable string for a plane given its +normal vector and a point on the plane. (Better to use +the ImplicitPlane class from parserImplicitPlane.pl). =cut Index: parserImplicitPlane.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserImplicitPlane.pl,v retrieving revision 1.16 retrieving revision 1.17 diff -Lmacros/parserImplicitPlane.pl -Lmacros/parserImplicitPlane.pl -u -r1.16 -r1.17 --- macros/parserImplicitPlane.pl +++ macros/parserImplicitPlane.pl @@ -1,55 +1,54 @@ -loadMacros('MathObjects.pl'); +=head1 NAME -sub _parserImplicitPlane_init {ImplicitPlane::Init()}; # don't reload this file +parserImplicitPlane.pl - Implement implicit planes. =head1 DESCRIPTION - ###################################################################### - # - # This is a Parser class that implements implicit planes as - # a subclass of the Formula class. The standard ->cmp routine - # will work for this, provided we define the compare() function - # needed by the overloaded ==. We assign the special precedence - # so that overloaded operations will be promoted to the ones below. - # - # - # Use ImplicitPlane(point,vector), ImplicitPlane(point,number) or - # ImplicitPlane(formula) to create an ImplicitPlane object. - # The first form uses the point as a point on the plane and the - # vector as the normal for the plane. The second form uses the point - # as the coefficients of the variables and the number as the value - # that the formula must equal. The third form uses the formula - # directly. - # - # The number of variables in the Context determines the dimension of - # the "plane" being defined. If there are only two, the formula - # produces an implicit line, but if there are four variables, it will - # be a hyperplane in four-space. You can specify the variables you - # want to use by supplying an additional parameter, which is a - # reference to an array of variable names. - # - # - # Usage examples: - # - # $P = ImplicitPlane(Point(1,0,2),Vector(-1,1,3)); # -x+y+3z = 5 - # $P = ImplicitPlane([1,0,2],[-1,1,3]); # -x+y+3z = 5 - # $P = ImplicitPlane([1,0,2],4); # x+2z = 4 - # $P = ImplicitPlane("x+2y-z=5"); - # - # Context()->variables->are(x=>'Real',y=>'Real',z=>'Real',w=>'Real'); - # $P = ImplicitPlane([1,0,2,-1],10); # w+2y-z = 10 (alphabetical order) - # $P = ImplicitPlane([3,-1,2,4],5,['x','y','z','w']); # 3x-y+2z+4w = 5 - # $P = ImplicitPlane([3,-1,2],5,['y','z','w']); # 3y-z+2w = 5 - # - # Then use - # - # ANS($P->cmp); - # - # to get the answer checker for $P. - # +This is a Parser class that implements implicit planes as +a subclass of the Formula class. The standard ->cmp routine +will work for this, provided we define the compare() function +needed by the overloaded ==. We assign the special precedence +so that overloaded operations will be promoted to the ones below. + +Use ImplicitPlane(point,vector), ImplicitPlane(point,number) or +ImplicitPlane(formula) to create an ImplicitPlane object. +The first form uses the point as a point on the plane and the +vector as the normal for the plane. The second form uses the point +as the coefficients of the variables and the number as the value +that the formula must equal. The third form uses the formula +directly. + +The number of variables in the Context determines the dimension of +the "plane" being defined. If there are only two, the formula +produces an implicit line, but if there are four variables, it will +be a hyperplane in four-space. You can specify the variables you +want to use by supplying an additional parameter, which is a +reference to an array of variable names. + +Usage examples: + + $P = ImplicitPlane(Point(1,0,2),Vector(-1,1,3)); # -x+y+3z = 5 + $P = ImplicitPlane([1,0,2],[-1,1,3]); # -x+y+3z = 5 + $P = ImplicitPlane([1,0,2],4); # x+2z = 4 + $P = ImplicitPlane("x+2y-z=5"); + + Context()->variables->are(x=>'Real',y=>'Real',z=>'Real',w=>'Real'); + $P = ImplicitPlane([1,0,2,-1],10); # w+2y-z = 10 (alphabetical order) + $P = ImplicitPlane([3,-1,2,4],5,['x','y','z','w']); # 3x-y+2z+4w = 5 + $P = ImplicitPlane([3,-1,2],5,['y','z','w']); # 3y-z+2w = 5 + +Then use + + ANS($P->cmp); + +to get the answer checker for $P. =cut +loadMacros('MathObjects.pl'); + +sub _parserImplicitPlane_init {ImplicitPlane::Init()}; # don't reload this file + ################################################## # # Define the subclass of Formula Index: problemRandomize.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/problemRandomize.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/problemRandomize.pl -Lmacros/problemRandomize.pl -u -r1.8 -r1.9 --- macros/problemRandomize.pl +++ macros/problemRandomize.pl @@ -1,98 +1,127 @@ +=head1 NAME -=head1 ProblemRandomize(); +problemRandomize.pl - Reseed a problem so that students can do additional versions for +more practice. - ###################################################################### - # - # This file implements a mechanism for allowing a problem file to be - # "reseeded" so that the student can do additional versions of the - # problem. You can control when the reseed message is available, - # and what style to use for it. - # - # To use the problemRandimize library, use - # - # loadMacros("problemRandomize.pl"); - # - # at the top of your problem file, and then create a problemRandomize - # object with - # - # $pr = ProblemRandomize(options); - # - # where '$pr' is the name of the variable you will use to refer - # to the randomized problem (if needed), and 'options' can include: - # - # when => type Specifies the condition on which - # reseeding the problem is allowed. - # The choices include: - # - # "Correct" (only when the problem has - # been answered correctly.) - # - # "Always" (reseeding is always allowed.) - # - # Default: "Correct" - # - # onlyAfterDue => 0 or 1 Specifies if the reseed option is only - # allowed after the due date has passed. - # Default: 1 - # - # style => type Determines the type of interaction needed - # to reseed the problem. Types include: - # - # "Button" (a button) - # - # "Checkbox" (a checkbox plus pressing submit) - # - # "Input" (an input box where the seed - # can be set explicitly) - # - # "HTML" (the HTML is given explicitly - # via the "label" option below) - # - # Default: "Button" - # - # label => "text" Specifies the text used for the button name, - # checkbox label, input box label, or raw HTML - # used for the reseed mechanism. - # - # The problemRandomize library installs a special grader that handles determining - # when the reseed option will be available. It also redefines install_problem_grader - # so that it will not overwrite the one installed by the library (it is stored so - # that it can be called internally by the problemRandomize library's grader). - # - # Note that the problem will store the new problem seed only if the student can - # submit saved answers (i.e., only before the due date). After the due date, - # the student can get new versions, but the problem will revert to the original - # version when they come back to the problem later. Since the default is only - # to allow reseeding afer the due date, the reseeding will not be sticky by default. - # Hardcopy ALWAYS produces the original version of the problem, regardless of - # the seed saved by the student. - # - # Examples: - # - # ProblemRandomize(); # use all defaults - # ProblemRandomize(when=>"Always"); # always can reseed (after due date) - # ProblemRandomize(onlyAfterDue=>0); # can reseed whenever correct - # ProblemRandomize(when=>"always",onlyAfterDue=>0); # always can reseed - # - # ProblemRandomize(style=>"Input"); # use an input box to set the seed - # - # For problems that include "PGcourse.pl" in their loadMacros() calls, you can - # use that file to provide reseed buttons for ALL problems simply by including - # - # loadMacros("problemRandomize.pl"); - # ProblemRandomize(); - # - # in PGcourse.pl. You can make the ProblemRandomize() be dependent on the set - # number or the set or the login ID or whatever. For example - # - # loadMacros("problemRandomize.pl"); - # ProblemRandomize(when=>"always",onlyAfterDue=>0,style=>"Input") - # if $studentLogin eq "dpvc"; - # - # would enable reseeding at any time for the user called "dpvc" (presumably a - # professor). You can test $probNum and $setNumber to make reseeding available - # only for specific sets or problems within a set. - # +=head1 DESCRIPTION + +This file implements a mechanism for allowing a problem file to be +"reseeded" so that the student can do additional versions of the +problem. You can control when the reseed message is available, +and what style to use for it. + +To use the problemRandimize library, use + + loadMacros("problemRandomize.pl"); + +at the top of your problem file, and then create a problemRandomize +object with + + $pr = ProblemRandomize(options); + +where '$pr' is the name of the variable you will use to refer +to the randomized problem (if needed), and 'options' can include: + +=over + +=item C<S<< when => type >>> + +Specifies the condition on which +reseeding the problem is allowed. +The choices include: + +=over + +=item * + +C<Correct> - only when the problem has been answered correctly. + +=item * + +C<Always> - reseeding is always allowed. + +=back + +Default: "Correct" + +=item C<S<< onlyAfterDue => 0 or 1 >>> + +Specifies if the reseed option is only +allowed after the due date has passed. +Default: 1 + +=item C<S<< style => type >>> + +Determines the type of interaction needed +to reseed the problem. Types include: + +=over + +=item * + +C<Button> - a button. + +=item * + +C<Checkbox> - a checkbox plus pressing submit. + +=item * + +C<Input> - an input box where the seed can be set explicitly. + +=item * + +C<HTML> - the HTML is given explicitly via the "label" option below. + +=back + +Default: "Button" + +=item C<S<< label => "text" >>> + +Specifies the text used for the button name, +checkbox label, input box label, or raw HTML +used for the reseed mechanism. + +=back + +The problemRandomize library installs a special grader that handles determining +when the reseed option will be available. It also redefines install_problem_grader +so that it will not overwrite the one installed by the library (it is stored so +that it can be called internally by the problemRandomize library's grader). + +Note that the problem will store the new problem seed only if the student can +submit saved answers (i.e., only before the due date). After the due date, +the student can get new versions, but the problem will revert to the original +version when they come back to the problem later. Since the default is only +to allow reseeding afer the due date, the reseeding will not be sticky by default. +Hardcopy ALWAYS produces the original version of the problem, regardless of +the seed saved by the student. + +Examples: + + ProblemRandomize(); # use all defaults + ProblemRandomize(when=>"Always"); # always can reseed (after due date) + ProblemRandomize(onlyAfterDue=>0); # can reseed whenever correct + ProblemRandomize(when=>"always",onlyAfterDue=>0); # always can reseed + ProblemRandomize(style=>"Input"); # use an input box to set the seed + +For problems that include "PGcourse.pl" in their loadMacros() calls, you can +use that file to provide reseed buttons for ALL problems simply by including + + loadMacros("problemRandomize.pl"); + ProblemRandomize(); + +in PGcourse.pl. You can make the ProblemRandomize() be dependent on the set +number or the set or the login ID or whatever. For example + + loadMacros("problemRandomize.pl"); + ProblemRandomize(when=>"always",onlyAfterDue=>0,style=>"Input") + if $studentLogin eq "dpvc"; + +would enable reseeding at any time for the user called "dpvc" (presumably a +professor). You can test $probNum and $setNumber to make reseeding available +only for specific sets or problems within a set. =cut Index: parserNumberWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserNumberWithUnits.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/parserNumberWithUnits.pl -Lmacros/parserNumberWithUnits.pl -u -r1.6 -r1.7 --- macros/parserNumberWithUnits.pl +++ macros/parserNumberWithUnits.pl @@ -1,31 +1,30 @@ -loadMacros('MathObjects.pl'); +=head1 NAME + +parserNumberWithUnits.pl - Implements a number with units. =head1 DESCRIPTION - ###################################################################### - # - # This is a Parser class that implements a number with units. - # It is a temporary version until the Parser can handle it - # directly. - # - # Use NumberWithUnits("num units") or NumberWithUnits(formula,"units") - # to generate a NumberWithUnits object, and then call its cmp method - # to get an answer checker for your number with units. - # - # Usage examples: - # - # ANS(NumberWithUnits("3 ft")->cmp); - # ANS(NumberWithUnits("$a*$b ft")->cmp); - # ANS(NumberWithUnits($a*$b,"ft")->cmp); - # - - # - # We now call on the Legacy version, which is used by - # num_cmp to handle numbers with units. - # +This is a Parser class that implements a number with units. +It is a temporary version until the Parser can handle it +directly. + +Use NumberWithUnits("num units") or NumberWithUnits(formula,"units") +to generate a NumberWithUnits object, and then call its cmp method +to get an answer checker for your number with units. + +Usage examples: + + ANS(NumberWithUnits("3 ft")->cmp); + ANS(NumberWithUnits("$a*$b ft")->cmp); + ANS(NumberWithUnits($a*$b,"ft")->cmp); + +We now call on the Legacy version, which is used by +num_cmp to handle numbers with units. =cut +loadMacros('MathObjects.pl'); + sub _parserNumberWithUnits_init { main::PG_restricted_eval('sub NumberWithUnits {Parser::Legacy::NumberWithUnits->new(@_)}'); } Index: parserPopUp.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserPopUp.pl,v retrieving revision 1.5 retrieving revision 1.6 diff -Lmacros/parserPopUp.pl -Lmacros/parserPopUp.pl -u -r1.5 -r1.6 --- macros/parserPopUp.pl +++ macros/parserPopUp.pl @@ -1,41 +1,42 @@ -loadMacros('MathObjects.pl','contextString.pl'); +=head1 NAME -sub _parserPopUp_init {parserPopUp::Init()}; # don't reload this file +parserPopUp.pl - Pop-up menus compatible with Value objects. =head1 DESCRIPTION - #################################################################### - # - # This file implements a pop-up menu object that is compatible - # with Value objects, and in particular, with the MultiPart object. - # - # To create a PopUp object, use - # - # $popup = PopUp([choices,...],correct); - # - # where "choices" are the strings for the items in the popup menu, - # and "correct" is the choice that is the correct answer for the - # popup. - # - # To insert the popup menu into the problem text, use - # - # BEGIN_TEXT - # \{$popup->menu\} - # END_TEXT - # - # and then - # - # ANS($popup->cmp); - # - # to get the answer checker for the popup. - # - # You can use the PopUp menu object in MultiPart objects. This is - # the reason for the pop-up menu's ans_rule method (since that is what - # MultiPart calls to get answer rules). - # +This file implements a pop-up menu object that is compatible +with Value objects, and in particular, with the MultiAnswer object. + +To create a PopUp object, use + + $popup = PopUp([choices,...],correct); + +where "choices" are the strings for the items in the popup menu, +and "correct" is the choice that is the correct answer for the +popup. + +To insert the popup menu into the problem text, use + + BEGIN_TEXT + \{$popup->menu\} + END_TEXT + +and then + + ANS($popup->cmp); + +to get the answer checker for the popup. + +You can use the PopUp menu object in MultiAnswer objects. This is +the reason for the pop-up menu's ans_rule method (since that is what +MultiAnswer calls to get answer rules). =cut +loadMacros('MathObjects.pl','contextString.pl'); + +sub _parserPopUp_init {parserPopUp::Init()}; # don't reload this file + # # The package that implements pop-up menus # Index: parserSolutionFor.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserSolutionFor.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/parserSolutionFor.pl -Lmacros/parserSolutionFor.pl -u -r1.6 -r1.7 --- macros/parserSolutionFor.pl +++ macros/parserSolutionFor.pl @@ -1,60 +1,61 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _parserSolutionFor_init {}; # don't reload this file +parserSolutionFor.pl - An answer checker that checks if a student's answer +satisifies an implicit equation. =head1 DESCRIPTION - ###################################################################### - # - # This is a Parser class that implements an answer checker that - # checks if a student's answer satisfies an implicit equation. - # We define a SolutionFor object class that lets you specify an - # equality that the student answer must satisfy, and a point that - # DOES satify the equation. The overloaded == operator will - # check if a given point satisfies the given equality. - # - # Use SolutionFor(equality,point[,options]) to create a SolutionFor object. - # The equality is a Formula object containing an equality, or a string - # representing such a formula, and the point is a Point object or string - # containing a point that satisfies the equation (to be used as the - # correct answer when the student asks to see the answers). - # - # The variables to use are declared in the Context in the usual way, - # and the coordinates of the student point will be considered to be in - # alphabetical order. You can override this by supplying the vars=>[...] - # option, where you specify the variable names in the order you want the - # student to give them. E.g., vars=>['y','x'] will make the student answer - # represent the point (y,x) rather than the default (x,y). - # - # Usage examples: - # - # Context("Vector")->variables->are(x=>'Real',y=>'Real'); - # $f = SolutionFor("x^2 = cos(y)","(1,0)"); - # $f = SolutionFor("x^2 - y = 0",[2,4]); - # $f = SolutionFor("x^2 - y = 0",Point(4,2),vars=>['y','x']); - # - # Then use - # - # ANS($f->cmp); - # - # to get the answer checker for $f. - # - # You can use $f->{f} to get the Formula object for the equality used - # in the object, and $f->f(point) to determine if the given point is - # a solution to the equality or not. For example, if you want to include - # the TeX version of a formula within the text of a problem, you can use: - # - # Context()->texStrings; - # BEGIN_TEXT - # A solution to \($f->{f}\) is \((x,y)\) = \{ans_rule(30)\}. - # END_TEXT - # Context()->normalStrings; - # ANS($f->cmp); - # - ###################################################################### +This is a Parser class that implements an answer checker that +checks if a student's answer satisfies an implicit equation. +We define a SolutionFor object class that lets you specify an +equality that the student answer must satisfy, and a point that +DOES satify the equation. The overloaded == operator will +check if a given point satisfies the given equality. + +Use SolutionFor(equality,point[,options]) to create a SolutionFor object. +The equality is a Formula object containing an equality, or a string +representing such a formula, and the point is a Point object or string +containing a point that satisfies the equation (to be used as the +correct answer when the student asks to see the answers). + +The variables to use are declared in the Context in the usual way, +and the coordinates of the student point will be considered to be in +alphabetical order. You can override this by supplying the vars=>[...] +option, where you specify the variable names in the order you want the +student to give them. E.g., vars=>['y','x'] will make the student answer +represent the point (y,x) rather than the default (x,y). + +Usage examples: + + Context("Vector")->variables->are(x=>'Real',y=>'Real'); + $f = SolutionFor("x^2 = cos(y)","(1,0)"); + $f = SolutionFor("x^2 - y = 0",[2,4]); + $f = SolutionFor("x^2 - y = 0",Point(4,2),vars=>['y','x']); + +Then use + + ANS($f->cmp); + +to get the answer checker for $f. + +You can use $f->{f} to get the Formula object for the equality used +in the object, and $f->f(point) to determine if the given point is +a solution to the equality or not. For example, if you want to include +the TeX version of a formula within the text of a problem, you can use: + + Context()->texStrings; + BEGIN_TEXT + A solution to \($f->{f}\) is \((x,y)\) = \{ans_rule(30)\}. + END_TEXT + Context()->normalStrings; + ANS($f->cmp); =cut +loadMacros("MathObjects.pl"); + +sub _parserSolutionFor_init {}; # don't reload this file + # # Create a SolutionFor object of the correct type # Index: parserMultiAnswer.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserMultiAnswer.pl,v retrieving revision 1.6 retrieving revision 1.7 diff -Lmacros/parserMultiAnswer.pl -Lmacros/parserMultiAnswer.pl -u -r1.6 -r1.7 --- macros/parserMultiAnswer.pl +++ macros/parserMultiAnswer.pl @@ -1,90 +1,84 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -=head3 MultiAnswer +parserMultiAnswer.pl - Tie several blanks to a single answer checker. - ###################################################################### - # - # MultiAnswer objects let you tie several answer blanks to a single - # answer checker, so you can have the answer in one blank influence - # the answer in another. The MultiAnswer can produce either a single - # result in the answer results area, or a separate result for each - # blank. - # - # To create a MultiAnswer pass a list of answers to MultiAnswer() in the - # order they will appear in the problem. For example: - # - # $mp = MultiAnswer("x^2",-1,1); - # - # or - # - # $mp = MultiAnswer(Vector(1,1,1),Vector(2,2,2))->with(singleResult=>1); - # - # Then, use $mp->ans_rule to create answer blanks for the various parts - # just as you would ans_rule. You can pass the width of the blank, which - # defaults to 20 otherwise. For example: - # - # BEGIN_TEXT - # \(f(x)\) = \{$mp->ans_rule(20)\} produces the same value - # at \(x\) = \{$mp->ans_rule(10)\} as it does at \(x\) = \{$mp->ans_rule(10)\}. - # END_TEXT - # - # Finally, call $mp->cmp to produce the answer checker(s) used in the MultiAnswer. - # You need to provide a checker routine that will be called to determine if the - # answers are correct or not. The checker will only be called if the student - # answers have no syntax errors and their types match the types of the professor's - # answers, so you don't have to worry about handling bad data from the student - # (at least as far as typechecking goes). - # - # The checker routine should accept four parameters: a reference to the array - # of correct answers, a reference to the array of student answers, a reference - # to the MultiAnswer itself, and a reference to the answer hash. It should do - # whatever checking it needs to do and then return a score for the MultiAnswer - # as a whole (every answer blank will be given the same score), or a reference - # to an array of scores, one for each blank. The routine can set error messages - # via the MultiAnswer's setMessage() method (e.g., - # - # $mp->setMessage(1,"The function can't be the identity"); - # - # would set the message for the first answer blank of the MultiAnswer), or can - # call Value::Error() to generate an error and die. - # - # The checker routine can be supplied either when the MultiAnswer is created, or - # when the cmp() method is called. For example: - # - # $mp = MultiAnswer("x^2",1,-1)->with( - # singleResult => 1, - # checker => sub { - # my ($correct,$student,$self) = @_; # get the parameters - # my ($f,$x1,$x2) = @{$student}; # extract the student answers - # Value::Error("Function can't be the identity") if ($f == 'x'); - # Value::Error("Function can't be constant") if ($f->isConstant); - # return $f->eval(x=>$x1) == $f->eval(x=>$x2); - # }, - # ); - # . - # . - # . - # ANS($mp->cmp); - # - # or - # - # $mp = MultiAnswer("x^2",1,-1)->with(singleResult=>1); - # sub check { - # my ($correct,$student,$self) = @_; # get the parameters - # my ($f,$x1,$x2) = @{$student}; # extract the student answers - # Value::Error("Function can't be the identity") if ($f == 'x'); - # Value::Error("Function can't be constant") if ($f->isConstant); - # return $f->eval(x=>$x1) == $f->eval(x=>$x2); - # }; - # . - # . - # . - # ANS($mp->cmp(checker=>~~&check)); - # - ###################################################################### +=head1 DESCRIPTION + +MultiAnswer objects let you tie several answer blanks to a single +answer checker, so you can have the answer in one blank influence +the answer in another. The MultiAnswer can produce either a single +result in the answer results area, or a separate result for each +blank. + +To create a MultiAnswer pass a list of answers to MultiAnswer() in the +order they will appear in the problem. For example: + + $mp = MultiAnswer("x^2",-1,1); + +or + + $mp = MultiAnswer(Vector(1,1,1),Vector(2,2,2))->with(singleResult=>1); + +Then, use $mp->ans_rule to create answer blanks for the various parts +just as you would ans_rule. You can pass the width of the blank, which +defaults to 20 otherwise. For example: + + BEGIN_TEXT + \(f(x)\) = \{$mp->ans_rule(20)\} produces the same value + at \(x\) = \{$mp->ans_rule(10)\} as it does at \(x\) = \{$mp->ans_rule(10)\}. + END_TEXT + +Finally, call $mp->cmp to produce the answer checker(s) used in the MultiAnswer. +You need to provide a checker routine that will be called to determine if the +answers are correct or not. The checker will only be called if the student +answers have no syntax errors and their types match the types of the professor's +answers, so you don't have to worry about handling bad data from the student +(at least as far as typechecking goes). + +The checker routine should accept four parameters: a reference to the array +of correct answers, a reference to the array of student answers, a reference +to the MultiAnswer itself, and a reference to the answer hash. It should do +whatever checking it needs to do and then return a score for the MultiAnswer +as a whole (every answer blank will be given the same score), or a reference +to an array of scores, one for each blank. The routine can set error messages +via the MultiAnswer's setMessage() method (e.g., + + $mp->setMessage(1,"The function can't be the identity"); + +would set the message for the first answer blank of the MultiAnswer), or can +call Value::Error() to generate an error and die. + +The checker routine can be supplied either when the MultiAnswer is created, or +when the cmp() method is called. For example: + + $mp = MultiAnswer("x^2",1,-1)->with( + singleResult => 1, + checker => sub { + my ($correct,$student,$self) = @_; # get the parameters + my ($f,$x1,$x2) = @{$student}; # extract the student answers + Value::Error("Function can't be the identity") if ($f == 'x'); + Value::Error("Function can't be constant") if ($f->isConstant); + return $f->eval(x=>$x1) == $f->eval(x=>$x2); + }, + ); + ANS($mp->cmp); + +or + + $mp = MultiAnswer("x^2",1,-1)->with(singleResult=>1); + sub check { + my ($correct,$student,$self) = @_; # get the parameters + my ($f,$x1,$x2) = @{$student}; # extract the student answers + Value::Error("Function can't be the identity") if ($f == 'x'); + Value::Error("Function can't be constant") if ($f->isConstant); + return $f->eval(x=>$x1) == $f->eval(x=>$x2); + }; + ANS($mp->cmp(checker=>~~&check)); =cut +loadMacros("MathObjects.pl"); + sub _parserMultiAnswer_init { main::PG_restricted_eval('sub MultiAnswer {MultiAnswer->new(@_)}'); } |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 23:05:02
|
Log Message: ----------- changed name message Modified Files: -------------- pg/macros: contextPeriodic.pl Revision Data ------------- Index: contextPeriodic.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPeriodic.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/contextPeriodic.pl -Lmacros/contextPeriodic.pl -u -r1.9 -r1.10 --- macros/contextPeriodic.pl +++ macros/contextPeriodic.pl @@ -1,6 +1,7 @@ =head1 NAME -contextPeriodic.pl - Allow for specifying periodic functions. [DEPRECATED] +contextPeriodic.pl - [DEPRECATED] Features added to Real and Complex +MathObjects classes. =head1 DESCRIPTION |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 20:55:52
|
Log Message: ----------- improved formatting for docs -- these were in pod sections but were all formatted as verbatim sections, and i moved them into normal paragraphs, lists, etc. should make things more readable from the web. Modified Files: -------------- pg/macros: answerComposition.pl answerCustom.pl answerVariableList.pl contextABCD.pl contextCurrency.pl contextInequalities.pl contextIntegerFunctions.pl contextLimitedComplex.pl contextLimitedNumeric.pl contextLimitedPoint.pl contextLimitedPolynomial.pl contextLimitedPowers.pl contextLimitedVector.pl contextPeriodic.pl contextPiecewiseFunction.pl contextScientificNotation.pl contextString.pl contextTF.pl parserAutoStrings.pl parserDifferenceQuotient.pl parserFormulaUpToConstant.pl parserFormulaWithUnits.pl parserFunction.pl Revision Data ------------- Index: contextLimitedPoint.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPoint.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextLimitedPoint.pl -Lmacros/contextLimitedPoint.pl -u -r1.10 -r1.11 --- macros/contextLimitedPoint.pl +++ macros/contextLimitedPoint.pl @@ -1,20 +1,22 @@ +=head1 NAME -loadMacros("MathObjects.pl"); +contextLimitedPoint.pl - Allow point entry but no point operations. -sub _contextLimitedPoint_init {LimitedPoint::Init()}; # don't load it again +=head1 DESCRIPTION -=head3 Context("LimitedPoint") +Implements a context in which points can be entered, +but no operations are permitted between points. So +students will be able to perform operations within the +coordinates of the points, but not between points. - ########################################################## - # - # Implements a context in which points can be entered, - # but no operations are permitted between points. So - # students will be able to perform operations within the - # coordinates of the points, but not between points. - # + Context("LimitedPoint") =cut +loadMacros("MathObjects.pl"); + +sub _contextLimitedPoint_init {LimitedPoint::Init()}; # don't load it again + ################################################## # # Handle common checking for BOPs Index: contextString.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextString.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/contextString.pl -Lmacros/contextString.pl -u -r1.11 -r1.12 --- macros/contextString.pl +++ macros/contextString.pl @@ -1,26 +1,27 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _contextString_init {context::String::Init()}; # don't load it again +contextString.pl - Allow string-valued answers. + +=head1 DESCRIPTION + +Implements contexts for string-valued answers. + +You can add new strings to the context as needed +via the Context()->strings->add() method. E.g., -=head3 Context("String") + Context("String")->strings->add(Foo=>{}, Bar=>{alias=>"Foo"}); - ########################################################## - # - # Implements contexts for string-valued answers. - # - # You can add new strings to the context as needed - # via the Context()->strings->add() method. E.g., - # - # Context("String")->strings->add(Foo=>{}, Bar=>{alias=>"Foo"}); - # - # Use string_cmp() to produce the answer checker(s) for your - # correct values. Eg. - # - # ANS(string_cmp("Foo")); - # +Use string_cmp() to produce the answer checker(s) for your +correct values. Eg. + + ANS(string_cmp("Foo")); =cut +loadMacros("MathObjects.pl"); + +sub _contextString_init {context::String::Init()}; # don't load it again + ################################################## package context::String::Variable; Index: contextLimitedNumeric.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedNumeric.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/contextLimitedNumeric.pl -Lmacros/contextLimitedNumeric.pl -u -r1.7 -r1.8 --- macros/contextLimitedNumeric.pl +++ macros/contextLimitedNumeric.pl @@ -1,26 +1,25 @@ +=head1 NAME -loadMacros("MathObjects.pl"); +contextLimitedNumeric.pl - Allows numeric entry but no operations. + +=head1 DESCRIPTION + +Implements a context in which numbers can be entered, +but no operations are permitted between them. -=head3 Context("LimitedNumeric") +There are two versions: one for lists of numbers +and one for a single number. Select them using +one of the following commands: - ########################################################## - # - # Implements a context in which numbers can be entered, - # but no operations are permitted between them. - # - # There are two versions: one for lists of numbers - # and one for a single number. Select them using - # one of the following commands: - # - # Context("LimitedNumeric-list"); - # Context("LimiteNumeric"); - # - # (Now uses Parcer::Legacy::LimitedNumeric to implement - # these contexts.) + Context("LimitedNumeric-List"); + Context("LimiteNumeric"); + +(Now uses Parcer::Legacy::LimitedNumeric to implement +these contexts.) =cut -################################################## +loadMacros("MathObjects.pl"); sub _contextLimitedNumeric_init { Index: parserDifferenceQuotient.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserDifferenceQuotient.pl,v retrieving revision 1.11 retrieving revision 1.12 diff -Lmacros/parserDifferenceQuotient.pl -Lmacros/parserDifferenceQuotient.pl -u -r1.11 -r1.12 --- macros/parserDifferenceQuotient.pl +++ macros/parserDifferenceQuotient.pl @@ -1,41 +1,41 @@ +=head1 NAME -loadMacros('MathObjects.pl'); - -sub _parserDifferenceQuotient_init {DifferenceQuotient::Init()}; # don't reload this file +parserDifferenceQuotient.pl - An answer checker for difference quotients. =head1 DESCRIPTION - ###################################################################### - # - # This is a Parser class that implements an answer checker for - # difference quotients as a subclass of the Formula class. The - # standard ->cmp routine will work for this. The difference quotient - # is just a special type of formula with a special variable - # for 'dx'. The checker will give an error message if the - # student's result contains a dx in the denominator, meaning it - # is not fully reduced. - # - # Use DifferenceQuotient(formula) to create a difference equation - # object. If the context has more than one variable, the last one - # alphabetically is used to form the dx. Otherwise, you can specify - # the variable used for dx as the second argument to - # DifferenceQuotient(). You could use a variable like h instead of - # dx if you prefer. - # - # Usage examples: - # - # $df = DifferenceQuotient("2x+dx"); - # ANS($df->cmp); - # - # $df = DifferenceQuotient("2x+h","h"); - # ANS($df->cmp); - # - # Context()->variables->are(t=>'Real',a=>'Real'); - # ANS(DifferenceQuotient("-a/[t(t+dt)]","dt")->cmp); - # +This is a Parser class that implements an answer checker for +difference quotients as a subclass of the Formula class. The +standard ->cmp routine will work for this. The difference quotient +is just a special type of formula with a special variable +for 'dx'. The checker will give an error message if the +student's result contains a dx in the denominator, meaning it +is not fully reduced. + +Use DifferenceQuotient(formula) to create a difference equation +object. If the context has more than one variable, the last one +alphabetically is used to form the dx. Otherwise, you can specify +the variable used for dx as the second argument to +DifferenceQuotient(). You could use a variable like h instead of +dx if you prefer. + +Usage examples: + + $df = DifferenceQuotient("2x+dx"); + ANS($df->cmp); + + $df = DifferenceQuotient("2x+h","h"); + ANS($df->cmp); + + Context()->variables->are(t=>'Real',a=>'Real'); + ANS(DifferenceQuotient("-a/[t(t+dt)]","dt")->cmp); =cut +loadMacros('MathObjects.pl'); + +sub _parserDifferenceQuotient_init {DifferenceQuotient::Init()}; # don't reload this file + package DifferenceQuotient; our @ISA = qw(Value::Formula); Index: contextLimitedVector.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedVector.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/contextLimitedVector.pl -Lmacros/contextLimitedVector.pl -u -r1.9 -r1.10 --- macros/contextLimitedVector.pl +++ macros/contextLimitedVector.pl @@ -1,34 +1,35 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _contextLimitedVector_init {LimitedVector::Init()}; # don't load it again +contextLimitedVector.pl - Allow vector entry but now vector operations. -=head3 Context("LimitedVector") +=head1 DESCRIPTION - ########################################################## - # - # Implements a context in which vectors can be entered, - # but no vector operations are permitted. So students will - # be able to perform operations within the coordinates - # of the vectors, but not between vectors. - # - # Vectors can still be entered either in < , , > or ijk format. - # Most of the complication here is to handle ijk format - # properly. Each coordinate vector is allowed to appear - # only once, so we have to keep track of that, and allow - # SOME vector operations, but only when one term is - # one of the coordinate constants, or one of the formulas - # we've already OKed. - # - # You control which format to use by setting the context - # to one of the following: - # - # Context("LimitedVector-coordinate"); - # Context("LimitedVector-ijk"); - # Context("LimitedVector"); # either one - # +Implements a context in which vectors can be entered, +but no vector operations are permitted. So students will +be able to perform operations within the coordinates +of the vectors, but not between vectors. + +Vectors can still be entered either in < , , > or ijk format. +Most of the complication here is to handle ijk format +properly. Each coordinate vector is allowed to appear +only once, so we have to keep track of that, and allow +SOME vector operations, but only when one term is +one of the coordinate constants, or one of the formulas +we've already OKed. + +You control which format to use by setting the context +to one of the following: + + Context("LimitedVector-coordinate"); + Context("LimitedVector-ijk"); + Context("LimitedVector"); # either one =cut +loadMacros("MathObjects.pl"); + +sub _contextLimitedVector_init {LimitedVector::Init()}; # don't load it again + ################################################## # # Handle common checking for BOPs Index: parserFormulaWithUnits.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/parserFormulaWithUnits.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/parserFormulaWithUnits.pl -Lmacros/parserFormulaWithUnits.pl -u -r1.7 -r1.8 --- macros/parserFormulaWithUnits.pl +++ macros/parserFormulaWithUnits.pl @@ -1,38 +1,36 @@ +=head1 NAME -loadMacros('MathObjects.pl'); +parserFormulaWithUnits.pl - Implements a formula with units. =head1 DESCRIPTION - ###################################################################### - # - # This is a Parser class that implements a formula with units. - # It is a temporary version until the Parser can handle it - # directly. - # - # Use FormulaWithUnits("num units") or FormulaWithUnits(formula,"units") - # to generate a FormulaWithUnits object, and then call its cmp() method - # to get an answer checker for your formula with units. - # - # Usage examples: - # - # ANS(FormulaWithUnits("3x+1 ft")->cmp); - # ANS(FormulaWithUnits("$a*x+1 ft")->cmp); - # - # $x = Formula("x"); - # ANS(FormulaWithUnits($a*$x+1,"ft")->cmp); - # - ###################################################################### +This is a Parser class that implements a formula with units. +It is a temporary version until the Parser can handle it +directly. + +Use FormulaWithUnits("num units") or FormulaWithUnits(formula,"units") +to generate a FormulaWithUnits object, and then call its cmp() method +to get an answer checker for your formula with units. + +Usage examples: + + ANS(FormulaWithUnits("3x+1 ft")->cmp); + ANS(FormulaWithUnits("$a*x+1 ft")->cmp); + + $x = Formula("x"); + ANS(FormulaWithUnits($a*$x+1,"ft")->cmp); + +=cut + +loadMacros('MathObjects.pl'); # # Now uses the version in Parser::Legacy::NumberWithUnits # to avoid duplication of common code. # -=cut - sub _parserFormulaWithUnits_init { main::PG_restricted_eval('sub FormulaWithUnits {Parser::Legacy::FormulaWithUnits->new(@_)}'); } 1; - Index: answerComposition.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerComposition.pl,v retrieving revision 1.4 retrieving revision 1.5 diff -Lmacros/answerComposition.pl -Lmacros/answerComposition.pl -u -r1.4 -r1.5 --- macros/answerComposition.pl +++ macros/answerComposition.pl @@ -1,47 +1,44 @@ +=head1 NAME +answerComposition.pl - An answer checker that determines if two functions +compose to form a given function. =head1 DESCRIPTION - ###################################################################### - # - # An answer checker that determines if two functions compose - # to form a given function. (For use in problems where you ask - # a student to break a given function into a composition of two - # simpler functions, neither of which is allowed to be the identity - # function.) - # +answerComposition.pl provides an answer checker that determines if two functions +compose to form a given function. This can be used in problems where you ask a +student to break a given function into a composition of two simpler functions, +neither of which is allowed to be the identity function. =cut sub _answerComposition_init {}; # don't reload this file -=head3 COMPOSITION_ANS($fn_f,$fn_g) +=head1 MACROS - ###################################################################### - # - # An answer checked to see if f composed with g matches a given function. - # - # Usage: COMPOSITION_ANS(f,g,options) - # - # where f and g are one possible decomposition of the target function - # (these are used to display the "correct" answer, and the composition - # is computed from them) and options are any of the options allowed - # by composition_ans_list() below. - # - # This function actually supplies TWO answer checkers, for the two - # previous answer blanks. So be sure to call it immediately after - # the answer blanks have been supplied. (It may be best to use the - # NAMED_COMPOSITION_ANS checker below, which specifies the answer - # blanks explicitly.) - # - # Example: - # - # BEGIN_TEXT - # \(f\circ g = (1+x)^2\) when - # \(f(x)\) = \{ans_rule(20)\} and \(g(x)\) = \{ans_rule(20)\} - # END_TEXT - # COMPOSITION_ANS("x^2","1+x"); - # +=head2 COMPOSITION_ANS + + COMPOSITION_ANS($f, $g, %options) + +An answer checked to see if $f composed with $g matches a given function,where +$f and $g are one possible decomposition of the target function, and options are +any of the options allowed by composition_ans_list() below. + +$f and $g are used to display the "correct" answer, and the composition is +computed from them. + +This function actually supplies TWO answer checkers, for the two previous answer +blanks. So be sure to call it immediately after the answer blanks have been +supplied. (It may be best to use the NAMED_COMPOSITION_ANS checker below, which +specifies the answer blanks explicitly.) + +Example: + + BEGIN_TEXT + \(f\circ g = (1+x)^2\) when + \(f(x)\) = \{ans_rule(20)\} and \(g(x)\) = \{ans_rule(20)\} + END_TEXT + COMPOSITION_ANS("x^2","1+x"); =cut @@ -53,56 +50,57 @@ ANS($ans{$fID},$ans{$gID}); } -=head3 NAMED_COMPOSITION_ANS(fID=>f,gID=>g,options) +=head2 NAMED_COMPOSITION_ANS + + NAMED_COMPOSITION_ANS($fID=>$f, $gID=>$g, %options) - ###################################################################### - # - # An answer checked to see if f composed with g matches a given function. - # - # Usage: NAMED_COMPOSITION_ANS(fID=>f,gID=>g,options) - # - # where fID and gID are the names of the answer rules for the functions - # f and g, and f and g are the answers for the functions. Options are - # any of the options allowed by composition_ans_list() below. - # - # This routine allows you to put the f and g answer blanks at any - # location in the problem, and in any order. - # - # Example: - # - # BEGIN_TEXT - # \(g\circ f = (1+x)^2\) when - # \(f(x)\) = \{NAMED_ANS('f',20)\} and \(g(x)\) = \{NAMED_ANS('g',20)\} - # END_TEXT - # NAMED_COMPOSITION_ANS(f => "x^2", g => "1+x"); - # +An answer checked to see if $f composed with $g matches a given function, where +$fID and $gID are the names of the answer rules for the functions $f and $g, and +$f and $g are the answers for the functions. %options are any of the options +allowed by composition_ans_list() below. + +This routine allows you to put the answer blanks for $f and $g at any location +in the problem, and in any order. + +Example: + + BEGIN_TEXT + \(g\circ f = (1+x)^2\) when + \(f(x)\) = \{NAMED_ANS('f',20)\} and \(g(x)\) = \{NAMED_ANS('g',20)\} + END_TEXT + NAMED_COMPOSITION_ANS(f => "x^2", g => "1+x"); =cut sub NAMED_COMPOSITION_ANS {NAMED_ANS(composition_ans_list(@_))} -=head3 composition_ans_list(fID=>f,gID=>g,options) +=head2 composition_ans_list + + composition_ans_list($fID=>$f, $gID=>$g, %options) + +This is an internal routine that returns the named answer checkers +used by COMPOSITION_ANS and NAMED_COMPOSITION_ANS above. + +$fID and $gID are the names of the answer rules for the functions and $f and $g +are the answers for these functions. %options are from among: - ###################################################################### - # - # This is an internal routine that returns the named answer checkers - # used by COMPOSITION_ANS and NAMED_COMPOSITION_ANS above. - # - # Usage: composition_ans_list(fID=>f,gID=>g,options) - # - # where fID and gID are the names of the answer rules for the functions - # and f and g are the answers for these functions. Options are from - # among: - # - # var => 'x' the name of the variable to use when - # both functions use the same one - # - # vars => ['x','t'] the names of the variables for f and g - # - # showVariableHints => 1 or 0 - # do/don't show errors when the variable - # used by the student is incorrect - # +=over + +=item S<C<< var => 'x' >>> + +the name of the variable to use when +both functions use the same one + +=item S<C<< vars => ['x','t'] >>> + +the names of the variables for $f and $g + +=item S<C<< showVariableHints => 1 or 0 >>> + +do/don't show errors when the variable +used by the student is incorrect + +=back =cut @@ -197,12 +195,16 @@ return (%ans); } -###################################################################### -# -# Evaluator that always returns incorrect, with a given error -# message. Used by COMPOSITION_ANS to produce "dummy" answer -# checkers for the two parts of the composition. -# +=head2 message_cmp + + message_cmp($correct) + +Returns an answer evaluator that always returns incorrect, with a given error +message. Used by COMPOSITION_ANS to produce "dummy" answer checkers for the two +parts of the composition. + +=cut + sub message_cmp { my $correct = shift; my $answerEvaluator = new AnswerEvaluator; @@ -216,3 +218,4 @@ } 1; + Index: answerVariableList.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/answerVariableList.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/answerVariableList.pl -Lmacros/answerVariableList.pl -u -r1.9 -r1.10 --- macros/answerVariableList.pl +++ macros/answerVariableList.pl @@ -1,36 +1,12 @@ -loadMacros('MathObjects.pl'); - -=head1 DESCRIPTION +=head1 NAME - ###################################################################### - # - # This answer checker compares the student answer to a list of - # variable names (so, for example, you can ask for what values a - # given function depends on). - # - # Use addVariables() to create the list of variables that from which - # the student can choose, and then use variable_cmp() to generate the - # answer checker. If the formula passed to variable_cmp contains - # parentheses around the list, then the student's answer must as - # well. - # - # You can also include additional parameters to variable_cmp. These - # can be any of the flags appropriate for List() answer checker. - # - # Usage examples: - # - # addVariables('x','y','z'); - # ANS(variable_cmp("(x,y)")); - # - # addVariables('x','y','z','s','t,); - # ANS(variable_cmp("s,t")); - # - # addVariables('x','y','z'); - # ANS(variable_cmp("(x)",showHints=>0,showLengthHints=>0)); - # +answerVariableList.pl - Creates answer checkers that compare the student's +answer to a list of variable names. =cut +loadMacros('MathObjects.pl'); + sub _answerVariableList_init { # # A new context for variable lists @@ -54,10 +30,38 @@ main::Context("VariableList"); ### FIXME: probably should require author to set this explicitly. } +=head1 MACROS + +=head2 variable_cmp + + ANS(variable_cmp($var_string, %options)) + +This answer checker compares the student answer to a list of +variable names (so, for example, you can ask for what values a +given function depends on). + +Use addVariables() to create the list of variables that from which +the student can choose, and then use variable_cmp() to generate the +answer checker. If the formula passed to variable_cmp contains +parentheses around the list, then the student's answer must as +well. + +You can also include additional parameters to variable_cmp. These +can be any of the flags appropriate for List() answer checker. + +Usage examples: + + addVariables('x','y','z'); + ANS(variable_cmp("(x,y)")); + + addVariables('x','y','z','s','t,); + ANS(variable_cmp("s,t")); + + addVariables('x','y','z'); + ANS(variable_cmp("(x)",showHints=>0,showLengthHints=>0)); + +=cut -# -# A shell that calls Formula()->cmp with the right defaults -# sub variable_cmp { Value->Package("Formula")->new(shift)->cmp( ordered => 1, @@ -68,12 +72,18 @@ ); } -# -# Handy routine to set up variables -# +=head2 addVariables + + addVariables(@vars) + +Adds each string in @vars as a varible to the current context. + +=cut + sub addVariables { my $context = Context(); foreach my $v (@_) {$context->variables->add($v=>'Real')} } 1; + Index: contextLimitedComplex.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedComplex.pl,v retrieving revision 1.9 retrieving revision 1.10 diff -Lmacros/contextLimitedComplex.pl -Lmacros/contextLimitedComplex.pl -u -r1.9 -r1.10 --- macros/contextLimitedComplex.pl +++ macros/contextLimitedComplex.pl @@ -1,51 +1,53 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _contextLimitedComplex_init {LimitedComplex::Init()}; # don't load it again +contextLimitedComplex.pl - Allow complex numbers but not complex operations. + +=head1 DESCRIPTION + +Implements a context in which complex numbers can be entered, +but no complex operations are permitted. So students will +be able to perform operations within the real and imaginary +parts of the complex numbers, but not between complex numbers. + + Context("LimitedComplex") + +Complex Numbers can still be entered in a+bi or a*e^(bt) form. +The e and i are allowed to be entered only once, so we have +to keep track of that, and allow SOME complex operations, +but only when one term is one of these constants (or an expression +involving it that we've already OKed). + +You control which format to use by setting the complex_format +context flag to 'cartesian', 'polar' or 'either'. E.g., + + Context()->flags->set(complex_format => 'polar'); -=head3 Context("LimitedComplex") +The default is 'either'. There are predefined contexts that +already have these values set: - ########################################################## - # - # Implements a context in which complex numbers can be entered, - # but no complex operations are permitted. So students will - # be able to perform operations within the real and imaginary - # parts of the complex numbers, but not between complex numbers. - # - # - # Complex Numbers can still be entered in a+bi or a*e^(bt) form. - # The e and i are allowed to be entered only once, so we have - # to keep track of that, and allow SOME complex operations, - # but only when one term is one of these constants (or an expression - # involving it that we've already OKed). - # - # You control which format to use by setting the complex_format - # context flag to 'cartesian', 'polar' or 'either'. E.g., - # - # Context()->flags->set(complex_format => 'polar'); - # - # The default is 'either'. There are predefined contexts that - # already have these values set: - # - # Context("LimitedComplex-cartesian"); - # Context("LimitedComplex-polar"); - # - # You can require that the a and b used in these forms be strictly - # numbers (not expressions) by setting the strict_numeric flag and - # disabling all the functions: - # - # Context()->flags->set(strict_numeric=>1); - # Context()->functions->disable('All'); - # - # There are predefined contexts that already have these values - # set: - # - # Context("LimitedComplex-cartesian-strict"); - # Context("LimitedComplex-polar-strict"); - # Context("LimitedComplex-strict"); - # + Context("LimitedComplex-cartesian"); + Context("LimitedComplex-polar"); + +You can require that the a and b used in these forms be strictly +numbers (not expressions) by setting the strict_numeric flag and +disabling all the functions: + + Context()->flags->set(strict_numeric=>1); + Context()->functions->disable('All'); + +There are predefined contexts that already have these values +set: + + Context("LimitedComplex-cartesian-strict"); + Context("LimitedComplex-polar-strict"); + Context("LimitedComplex-strict"); =cut +loadMacros("MathObjects.pl"); + +sub _contextLimitedComplex_init {LimitedComplex::Init()}; # don't load it again + ################################################## # # Handle common checking for BOPs Index: contextPeriodic.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPeriodic.pl,v retrieving revision 1.8 retrieving revision 1.9 diff -Lmacros/contextPeriodic.pl -Lmacros/contextPeriodic.pl -u -r1.8 -r1.9 --- macros/contextPeriodic.pl +++ macros/contextPeriodic.pl @@ -1,23 +1,23 @@ +=head1 NAME -=head1 contextPeriodic.pl +contextPeriodic.pl - Allow for specifying periodic functions. [DEPRECATED] - ###################################################################### - # - # This file is no longer needed, as these features have been added to the - # Real and Complex MathObject classes. - # - # Usage: - # Context("Numeric"); - # $a = Real("pi/2")->with(period=>pi); - # $a->cmp # will match pi/2, 3pi/2 etc. - # - # Usage: - # Context("Complex"); - # $z0 = Real("i^i")->with(period=>2pi, logPeriodic=>1); - # $z0->cmp # will match exp(i*(ln(1) + Arg(pi/2) + 2k pi)) - # - ###################################################################### +=head1 DESCRIPTION + +This file is no longer needed, as these features have been added to the +Real and Complex MathObject classes. + +=head1 USAGE + + Context("Numeric"); + $a = Real("pi/2")->with(period=>pi); + $a->cmp # will match pi/2, 3pi/2 etc. + + Context("Complex"); + $z0 = Real("i^i")->with(period=>2pi, logPeriodic=>1); + $z0->cmp # will match exp(i*(ln(1) + Arg(pi/2) + 2k pi)) =cut 1; + Index: contextPiecewiseFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPiecewiseFunction.pl,v retrieving revision 1.4 retrieving revision 1.5 diff -Lmacros/contextPiecewiseFunction.pl -Lmacros/contextPiecewiseFunction.pl -u -r1.4 -r1.5 --- macros/contextPiecewiseFunction.pl +++ macros/contextPiecewiseFunction.pl @@ -1,66 +1,66 @@ -loadMacros("MathObjects.pl"); -loadMacros("contextInequalities.pl"); +=head1 NAME -sub _contextPiecewiseFunction_init {PiecewiseFunction::Init()} +contextPiecewiseFunction.pl - Allow usage of piecewise functions. -=head1 Context("PiecewiseFunction"); +=head1 DESCRIPTION - ###################################################################### - # - # This file implements a context in which piecewise-defined functions - # can be specified by students and problem authors. To use it, add - # - # loadMacros("contextPiecewieFunction.pl"); - # - # and then use - # - # Context("PiecewiseFuntion"); - # - # to select the context for piecewise functions. There are several - # ways to produce a piecewise function. For example: - # - # $f = Compute("x if x >= 0 else -x"); - # $f = Compute("x if x >= 0 else -x if x < 0"); - # $f = Formula("x+1 if x > 2 else 4 if x = 2 else 1-x"); - # $f = PiecewiseFunction("x^2 if 1 < x <= 2 else 2x+1"); - # $f = PiecewiseFunction("1 < x <= 2" => "x^2", "2x+1"); - # $f = PiecewiseFunction("(1,2]" => "x^2", "2x+1"); - # $f = PiecewiseFunction(Interval("(1,2]") => "x^2", "2x+1"); - # - # You can use either Compute() or Formula() interchangeably to - # convert a string containing "if" and "else" to the corresponding - # PiecewiseFunction. The PiecewiseFunction() constructor can - # also do this, or you can pass it a list of interval=>formula - # pairs that specify the various branches. If there is an - # unpaired final formula, it represents the "otherwise" portion - # of the function (the formula to use of the input is not in - # any of the given intervals). - # - # Note that you can use Inveral, Set, or Union objects in place of - # the intervals in the specification of a piecewise function. - # - # The PiecewiseFunction object TeXifies using a LaTeX "cases" - # environment, so you can use these objects to produce nice - # output even if you are not asking a student to enter one. - # For example: - # - # Context("PiecewiseFunction"); - # - # $f = Formula("1-x if x > 0 else 4 if x = 0 else 1+x if x < 0"); - # $a = random(-2,2,.1); - # - # Context()->texStrings; - # BEGIN_TEXT - # Suppose \(f(x)=$f\). Then \(f($a)\) = \{ans_rule(20)\}. - # END_TEXT - # Context()->normalStrings; - # - # ANS($f->eval(x=>$a)->cmp); - # - ###################################################################### +This file implements a context in which piecewise-defined functions +can be specified by students and problem authors. To use it, add + + loadMacros("contextPiecewiseFunction.pl"); + +and then use + + Context("PiecewiseFuntion"); + +to select the context for piecewise functions. There are several +ways to produce a piecewise function. For example: + + $f = Compute("x if x >= 0 else -x"); + $f = Compute("x if x >= 0 else -x if x < 0"); + $f = Formula("x+1 if x > 2 else 4 if x = 2 else 1-x"); + $f = PiecewiseFunction("x^2 if 1 < x <= 2 else 2x+1"); + $f = PiecewiseFunction("1 < x <= 2" => "x^2", "2x+1"); + $f = PiecewiseFunction("(1,2]" => "x^2", "2x+1"); + $f = PiecewiseFunction(Interval("(1,2]") => "x^2", "2x+1"); + +You can use either Compute() or Formula() interchangeably to +convert a string containing "if" and "else" to the corresponding +PiecewiseFunction. The PiecewiseFunction() constructor can +also do this, or you can pass it a list of interval=>formula +pairs that specify the various branches. If there is an +unpaired final formula, it represents the "otherwise" portion +of the function (the formula to use of the input is not in +any of the given intervals). + +Note that you can use Inveral, Set, or Union objects in place of +the intervals in the specification of a piecewise function. + +The PiecewiseFunction object TeXifies using a LaTeX "cases" +environment, so you can use these objects to produce nice +output even if you are not asking a student to enter one. +For example: + + Context("PiecewiseFunction"); + + $f = Formula("1-x if x > 0 else 4 if x = 0 else 1+x if x < 0"); + $a = random(-2,2,.1); + + Context()->texStrings; + BEGIN_TEXT + Suppose \(f(x)=$f\). Then \(f($a)\) = \{ans_rule(20)\}. + END_TEXT + Context()->normalStrings; + + ANS($f->eval(x=>$a)->cmp); =cut +loadMacros("MathObjects.pl"); +loadMacros("contextInequalities.pl"); + +sub _contextPiecewiseFunction_init {PiecewiseFunction::Init()} + package PiecewiseFunction; # Index: contextInequalities.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextInequalities.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lmacros/contextInequalities.pl -Lmacros/contextInequalities.pl -u -r1.13 -r1.14 --- macros/contextInequalities.pl +++ macros/contextInequalities.pl @@ -1,63 +1,66 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _contextInequalities_init {Inequalities::Init()} +Context("Inequalities"), Context("Inequalities-Only") - Provides contexts that +allow intervals to be specified as inequalities. -=head1 Context("Inequalities"), Context("Inequalities-Only") +=head1 DESCRIPTION - ######################################################################### - # - # Implements contexts that provides for inequalities that produce - # the cooresponding Interval, Set or Union MathObjects. There are - # two such contexts: Context("Inequalities"), in which both - # intervals and inequalities are defined, and Context("Inequalities-Only"), - # which allows only inequalities as a means of producing intervals. - # - # Usage: loadMacros("contextInequalities.pl"); - # - # Context("Inequalities"); - # $S1 = Compute("1 < x <= 4"); - # $S2 = Inequality("(1,4]"); # force interval to be inequality - # - # Context("Inequalities-Only"); - # $S1 = Compute("1 < x <= 4"); - # $S2 = Inequality("(1,4]"); # generates an error - # - # $S3 = Compute("x < -2 or x > 2"); # forms a Union - # $S4 = Compute("x = 1"); # forms a Set - # - # You can set the "noneWord" flag to specify the string to - # use when the inequalities specify the empty set. By default, - # it is "NONE", but you can change it to other strings. Be sure - # that you use a string that is defined in the Context, however, - # if you expect the student to be able to enter it. For example - # - # Context("Inequalities"); - # Context()->constants->add(EmptySet => Set()); - # Context()->flags->set(noneWord=>"EmptySet"); - # - # creates an empty set as a named constant and uses that name. - # - # Inequalities and interval notation both can coexist side by - # side, but you may wish to convert from one to the other. - # Use Inequality() to convert from an Interval, Set or Union - # to an Inequality, and use Interval(), Set(), or Union() to - # convert from an Inequality object to one in interval notation. - # For example: - # - # $I0 = Compute("(1,2]"); # the interval (1,2] - # $I1 = Inequality($I); # the inequality 1 < x <= 2 - # - # $I0 = Compute("1 < x <= 2"); # the inequality 1 < x <= 2 - # $I1 = Interval($I0); # the interval (1,2] - # - # Note that ineqaulities and inervals can be compared and combined - # regardless of the format, so $I0 == $I1 is true in either example - # above. - # - ###################################################################### +Implements contexts that provides for inequalities that produce +the cooresponding Interval, Set or Union MathObjects. There are +two such contexts: Context("Inequalities"), in which both +intervals and inequalities are defined, and Context("Inequalities-Only"), +which allows only inequalities as a means of producing intervals. + +=head1 USAGE + + loadMacros("contextInequalities.pl"); + + Context("Inequalities"); + $S1 = Compute("1 < x <= 4"); + $S2 = Inequality("(1,4]"); # force interval to be inequality + + Context("Inequalities-Only"); + $S1 = Compute("1 < x <= 4"); + $S2 = Inequality("(1,4]"); # generates an error + + $S3 = Compute("x < -2 or x > 2"); # forms a Union + $S4 = Compute("x = 1"); # forms a Set + +You can set the "noneWord" flag to specify the string to +use when the inequalities specify the empty set. By default, +it is "NONE", but you can change it to other strings. Be sure +that you use a string that is defined in the Context, however, +if you expect the student to be able to enter it. For example + + Context("Inequalities"); + Context()->constants->add(EmptySet => Set()); + Context()->flags->set(noneWord=>"EmptySet"); + +creates an empty set as a named constant and uses that name. + +Inequalities and interval notation both can coexist side by +side, but you may wish to convert from one to the other. +Use Inequality() to convert from an Interval, Set or Union +to an Inequality, and use Interval(), Set(), or Union() to +convert from an Inequality object to one in interval notation. +For example: + + $I0 = Compute("(1,2]"); # the interval (1,2] + $I1 = Inequality($I); # the inequality 1 < x <= 2 + + $I0 = Compute("1 < x <= 2"); # the inequality 1 < x <= 2 + $I1 = Interval($I0); # the interval (1,2] + +Note that ineqaulities and inervals can be compared and combined +regardless of the format, so $I0 == $I1 is true in either example +above. =cut +loadMacros("MathObjects.pl"); + +sub _contextInequalities_init {Inequalities::Init()} + package Inequalities; # Index: contextScientificNotation.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextScientificNotation.pl,v retrieving revision 1.7 retrieving revision 1.8 diff -Lmacros/contextScientificNotation.pl -Lmacros/contextScientificNotation.pl -u -r1.7 -r1.8 --- macros/contextScientificNotation.pl +++ macros/contextScientificNotation.pl @@ -1,98 +1,99 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _contextScientificNotation_init {ScientificNotation::Init()} +contextScientificNotation.pl - Allows entry of scientific notation. + +=head1 DESCRIPTION + +This file implements a context in which students can enter +answers in scientific notation. It tries hard to report +useful error messages when the student's answer is not +in the proper format, and it also allows you to control +how many decimal digits they are allowed/required to +enter, and how many the system will display. + +This probably should be called LimitedScientificNotation +since it does not allow any operations other than the ones +needed in Scientific notation. In the future it may be +renamed if we produce a computational scientific notation +context. + +To use this context, add + + loadMacros("contextScientificNotation.pl"); + +to the top of your problem file, and then use + + Context("ScientificNotation"); + +to select the contxt and make it active. You can create +values in scientific notation in two ways: + + $n1 = Compute("1.23 x 10^3"); + +or + + $n2 = ScientificNotation(1.23 * 10**3); + +(or even $n2 = ScientificNotation(1230), and it will be converted). + +You can control how many digits are displayed by setting the +snDigits flag in the context. For example, -=head1 Context("ScientificNotation"); + Context()->flags->set(snDigits=>2); - ######################################################################### - # - # This file implements a context in which students can enter - # answers in scientific notation. It tries hard to report - # useful error messages when the student's answer is not - # in the proper format, and it also allows you to control - # how many decimal digits they are allowed/required to - # enter, and how many the system will display. - # - # This probably should be called LimitedScientificNotation - # since it does not allow any operations other than the ones - # needed in Scientific notation. In the future it may be - # renamed if we produce a computational scientific notation - # context. - # - # To use this context, add - # - # loadMacros("contextScientificNotation.pl"); - # - # to the top of your problem file, and then use - # - # Context("ScientificNotation"); - # - # to select the contxt and make it active. You can create - # values in scientific notation in two ways: - # - # $n1 = Compute("1.23 x 10^3"); - # - # or - # - # $n2 = ScientificNotation(1.23 * 10**3); - # - # (or even $n2 = ScientificNotation(1230), and it will be converted). - # - # You can control how many digits are displayed by setting the - # snDigits flag in the context. For example, - # - # Context()->flags->set(snDigits=>2); - # - # sets the context to display at most 2 digits. The default is 6. - # By default, trailing zeros are removed, but you can ask that - # they be retained by issuing the command - # - # Context()->flags->set(snTrimZeros=>0); - # - # It is also possible to specify how many decimal digits the - # student must enter. For example, - # - # Context()->flags->set(snMinDigits=>3); - # - # would require the student to enter at least 3 digits past - # the decimal place (for a total of 4 significant digits, - # including the one to the left of the decimal). The default - # is 1 digit beyond the decimal. A value of 0 means that - # a decimal point and decimal values is optional. - # - # Similarly, - # - # Context()->flags->set(snMaxDigits=>6); - # - # sets the maximum number to 6, so the student can't enter - # more than that. Setting this to 0 means no decimal places - # are allowed, effectively meaning students can only enter - # the numbers 0 through 9 (times a power of 10). Setting - # this to a negative number means that there is no upper - # limit on the number of digits the student may enter (this - # is the default). - # - # As an example, in order to force a fixed precision of - # three digits of precision, use - # - # Context()->flags->set( - # snDigits => 3, - # snTrimZeros => 0, - # snMinDigits => 3, - # snMaxDigits => 3, - # ); - # - # Note that if you restrict the number of digits, you may - # need to adjust the tolerance values since the student - # may not be allowed to enter a more precise answer. In - # the example above, it would be appropriate to set the - # tolerance to .0001 and the tolType to "relative" in - # order to require the answers to be correct to the three - # digits that are shown. - # +sets the context to display at most 2 digits. The default is 6. +By default, trailing zeros are removed, but you can ask that +they be retained by issuing the command + + Context()->flags->set(snTrimZeros=>0); + +It is also possible to specify how many decimal digits the +student must enter. For example, + + Context()->flags->set(snMinDigits=>3); + +would require the student to enter at least 3 digits past +the decimal place (for a total of 4 significant digits, +including the one to the left of the decimal). The default +is 1 digit beyond the decimal. A value of 0 means that +a decimal point and decimal values is optional. + +Similarly, + + Context()->flags->set(snMaxDigits=>6); + +sets the maximum number to 6, so the student can't enter +more than that. Setting this to 0 means no decimal places +are allowed, effectively meaning students can only enter +the numbers 0 through 9 (times a power of 10). Setting +this to a negative number means that there is no upper +limit on the number of digits the student may enter (this +is the default). + +As an example, in order to force a fixed precision of +three digits of precision, use + + Context()->flags->set( + snDigits => 3, + snTrimZeros => 0, + snMinDigits => 3, + snMaxDigits => 3, + ); + +Note that if you restrict the number of digits, you may +need to adjust the tolerance values since the student +may not be allowed to enter a more precise answer. In +the example above, it would be appropriate to set the +tolerance to .0001 and the tolType to "relative" in +order to require the answers to be correct to the three +digits that are shown. =cut +loadMacros("MathObjects.pl"); + +sub _contextScientificNotation_init {ScientificNotation::Init()} + package ScientificNotation; # Index: contextCurrency.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextCurrency.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextCurrency.pl -Lmacros/contextCurrency.pl -u -r1.10 -r1.11 --- macros/contextCurrency.pl +++ macros/contextCurrency.pl @@ -1,129 +1,126 @@ -loadMacros("MathObjects.pl"); -loadMacros("problemPreserveAnswers.pl"); # needed to preserve $ in answers +=head1 Context("Currency"); -sub _contextCurrency_init {Currency::Init()} +##################################################################### -=head1 Context("Currency"); +This file implements a context in which students can enter currency +values that include a currency symbol and commas every three digits. +You can specify what the currency symbol is, as well as what gets +used for commas and decimals. + +To use the context, put + + loadMacros("contextCurrency.pl"); + +at the top of your problem file, and then issue the + + Context("Currency"); + +command to select the context. You can set the currency symbol +and the comma or decimal values as in the following examples + + Context()->currency->set(symbol=>'#'); + Context()->currency->set(symbol=>'euro'); # accepts '12 euro' + Context()->currency->set(comma=>'.',decimal=>','); # accepts '10.000,00' + +You can add additional symbols (in case you want to allow +more than one way to write the currency). For example: + + Context("Currency")->currency->addSymbol("dollars","dollar"); + +would accept '$12,345.67' or '12.50 dollars' or '1 dollar' as +acceptable values. Note that if the symbol cantains any +alphabetic characters, it is expected to come at the end of the +number (as in the examples above) and if the symbol has only +non-alphabetic characters, it comes before it. You can change +this as in these examples: + + Context()->currency->setSymbol(euro=>{associativity=>"left"}); + Context()->currency->setSymbol('#'=>{associativity=>"right"}); + +You can remove a symbol as follows: + + Context()->currency->removeSymbol('dollar'); + +To create a currency value, use + + $m = Currency(10.99); + +or + + $m1 = Compute('$10.99'); + $m2 = Compute('$10,000.00'); + +and so on. Be careful, however, that you do not put dollar signs +inside double quotes, as this refers to variable substitution. +For example, + + $m = Compute("$10.99"); - ###################################################################### - # - # This file implements a context in which students can enter currency - # values that include a currency symbol and commas every three digits. - # You can specify what the currency symbol is, as well as what gets - # used for commas and decimals. - # - # To use the context, put - # - # loadMacros("contextCurrency.pl"); - # - # at the top of your problem file, and then issue the - # - # Context("Currency"); - # - # command to select the context. You can set the currency symbol - # and the comma or decimal values as in the following examples - # - # Context()->currency->set(symbol=>'#'); - # Context()->currency->set(symbol=>'euro'); # accepts '12 euro' - # Context()->currency->set(comma=>'.',decimal=>','); # accepts '10.000,00' - # - # You can add additional symbols (in case you want to allow - # more than one way to write the currency). For example: - # - # Context("Currency")->currency->addSymbol("dollars","dollar"); - # - # would accept '$12,345.67' or '12.50 dollars' or '1 dollar' as - # acceptable values. Note that if the symbol cantains any - # alphabetic characters, it is expected to come at the end of the - # number (as in the examples above) and if the symbol has only - # non-alphabetic characters, it comes before it. You can change - # this as in these examples: - # - # Context()->currency->setSymbol(euro=>{associativity=>"left"}); - # Context()->currency->setSymbol('#'=>{associativity=>"right"}); - # - # You can remove a symbol as follows: - # - # Context()->currency->removeSymbol('dollar'); - # - # To create a currency value, use - # - # $m = Currency(10.99); - # - # or - # - # $m1 = Compute('$10.99'); - # $m2 = Compute('$10,000.00'); - # - # and so on. Be careful, however, that you do not put dollar signs - # inside double quotes, as this refers to variable substitution. - # For example, - # - # $m = Compute("$10.99"); - # - # will most likely set $m to the Real value .99 rather than the - # monitary value of $10.99, since perl thinks $10 is the name of - # a variable, and will substitute that into the string before - # processing it. Since that variable is most likely empty, the - # result will be the same as $m = Compute(".99"); - # - # You can use monitary values within computations, as in - # - # $m1 = Compute('$10.00'); - # $m2 = 3*$m1; $m3 = $m2 + .5; - # $m4 = Compute('$10.00 + $2.59'); - # - # so that $m2 will be $30.00, $m3 will be $30.50, and $m4 will - # be $12.59. Students can perform computations within their - # answers unless you disable the operators and functions as well. - # - # The tolerance for this context is set initially to .005 and the - # tolType to 'absolute' so that monitary values will have to match - # to the nearest penny. You can change that on a global basis - # using - # - # Context()->flags->set(tolerance=>.0001,tolType=>"relative"); - # - # for example. You can also change the tolerance on an individual - # currency value as follows: - # - # $m = Compute('$1,250,000.00')-> - # with(tolerance=>.0001,tolType=>'relative'); - # - # By default, the answer checker for Currency values requires - # the student to enter the currency symbol, not just a real number. - # You can relax that condition by including the promoteReals=>1 - # option to the cmp() method of the Currency value. For example, - # - # ANS(Compute('$150')->cmp(promoteReals=>1)); - # - # would allow the student to enter just 150 rather than $150. - # - # By default, the students may omit the commas, but you can - # force them to supply the commas using forceCommas=>1 in - # your cmp() call. - # - # ANS(Compute('$10,000.00')->cmp(forceCommas=>1)); - # - # By default, students need not enter decimal digits, so could use - # $100 or $1,000. as valid entries. You can require that the cents - # be provided using the forceDecimals=>1 flag. - # - # ANS(Compute('$10.95')->cmp(forceDecimals=>1)); - # - # By default, if the monitary value includes decimals digits, it - # must have exactly two. You can weaken this requirement to all - # any number of decimals by using noExtraDecimals=>0. - # - # ANS(Compute('$10.23372')->cmp(noExtraDecimals=>0); - # - # If forceDecimals is set to 1 at the same time, then they must - # have 2 or more decimals, otherwise any number is OK. - # - ###################################################################### +will most likely set $m to the Real value .99 rather than the +monitary value of $10.99, since perl thinks $10 is the name of +a variable, and will substitute that into the string before +processing it. Since that variable is most likely empty, the +result will be the same as $m = Compute(".99"); + +You can use monitary values within computations, as in + + $m1 = Compute('$10.00'); + $m2 = 3*$m1; $m3 = $m2 + .5; + $m4 = Compute('$10.00 + $2.59'); + +so that $m2 will be $30.00, $m3 will be $30.50, and $m4 will +be $12.59. Students can perform computations within their +answers unless you disable the operators and functions as well. + +The tolerance for this context is set initially to .005 and the +tolType to 'absolute' so that monitary values will have to match +to the nearest penny. You can change that on a global basis +using + + Context()->flags->set(tolerance=>.0001,tolType=>"relative"); + +for example. You can also change the tolerance on an individual +currency value as follows: + + $m = Compute('$1,250,000.00')->with(tolerance=>.0001,tolType=>'relative'); + +By default, the answer checker for Currency values requires +the student to enter the currency symbol, not just a real number. +You can relax that condition by including the promoteReals=>1 +option to the cmp() method of the Currency value. For example, + + ANS(Compute('$150')->cmp(promoteReals=>1)); + +would allow the student to enter just 150 rather than $150. + +By default, the students may omit the commas, but you can +force them to supply the commas using forceCommas=>1 in +your cmp() call. + + ANS(Compute('$10,000.00')->cmp(forceCommas=>1)); + +By default, students need not enter decimal digits, so could use +$100 or $1,000. as valid entries. You can require that the cents +be provided using the forceDecimals=>1 flag. + + ANS(Compute('$10.95')->cmp(forceDecimals=>1)); + +By default, if the monitary value includes decimals digits, it +must have exactly two. You can weaken this requirement to all +any number of decimals by using noExtraDecimals=>0. + + ANS(Compute('$10.23372')->cmp(noExtraDecimals=>0); + +If forceDecimals is set to 1 at the same time, then they must +have 2 or more decimals, otherwise any number is OK. =cut +loadMacros("MathObjects.pl"); +loadMacros("problemPreserveAnswers.pl"); # needed to preserve $ in answers + +sub _contextCurrency_init {Currency::Init()} + package Currency; # Index: contextABCD.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextABCD.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextABCD.pl -Lmacros/contextABCD.pl -u -r1.10 -r1.11 --- macros/contextABCD.pl +++ macros/contextABCD.pl @@ -1,37 +1,38 @@ -loadMacros("MathObjects.pl","contextString.pl"); +=head1 NAME + +contextABCD.pl - Contexts for matching problems. =head1 DESCRIPTION - ########################################################## - # - # Implements contexts for string-valued answers especially - # for matching problems (where you match against A, B, C, D, - # and so on). - # - # There are two contexts defined here, - # - # Context("ABCD"); - # Context("ABCD-List"); - # - # The second allows the students to enter lists of strings, - # while the first does not. - # - # You can add new strings to the context as needed (or remove old ones) - # via the Context()->strings->add() and Context()-strings->remove() - # methods, eg. - # - # Context("ABCD-List")->strings->add(E=>{},e=>{alias=>"E"}); - # - # Use string_cmp() to produce the answer checker(s) for your - # correct values. Eg. - # - # ANS(string_cmp("A","B")); - # - # when there are two answers, the first being "A" and the second being "B". - # +Implements contexts for string-valued answers especially +for matching problems (where you match against A, B, C, D, +and so on). + +There are two contexts defined here, + + Context("ABCD"); + Context("ABCD-List"); + +The second allows the students to enter lists of strings, +while the first does not. + +You can add new strings to the context as needed (or remove old ones) +via the Context()->strings->add() and Context()-strings->remove() +methods, eg. + + Context("ABCD-List")->strings->add(E=>{},e=>{alias=>"E"}); + +Use string_cmp() to produce the answer checker(s) for your +correct values. Eg. + + ANS(string_cmp("A","B")); + +when there are two answers, the first being "A" and the second being "B". =cut +loadMacros("MathObjects.pl","contextString.pl"); + sub _contextABCD_init { my $context = $main::context{ABCD} = Parser::Context->getCopy("String"); $context->{name} = "ABCD"; Index: contextLimitedPowers.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextLimitedPowers.pl,v retrieving revision 1.10 retrieving revision 1.11 diff -Lmacros/contextLimitedPowers.pl -Lmacros/contextLimitedPowers.pl -u -r1.10 -r1.11 --- macros/contextLimitedPowers.pl +++ macros/contextLimitedPowers.pl @@ -1,89 +1,93 @@ -loadMacros("MathObjects.pl"); +=head1 NAME -sub _contextLimitedPowers_init {}; # don't load it again +contextLimitedPowers.pl - Restrict the base or power allowed in exponentials. + +=head1 DESCRIPTION + +Implements subclasses of the "^" operator that restrict +the base or power that is allowed. There are four +available restrictions: + + No raising e to a power + Only allowing integer powers (positive or negative) + Only allowing positive interger powers + Only allowing positive interger powers (and 0) + +You install these via one of the commands: + + LimitedPowers::NoBaseE(); + LimitedPowers::OnlyIntegers(); + LimitedPowers::OnlyPositiveIntegers(); + LimitedPowers::OnlyNonNegativeIntegers(); + +Only one of the three can be in effect at a time; setting +a second one overrides the first. + +These function affect the current context, or you can pass +a context reference, as in + + $context = Context("Numeric")->copy; + LimitedPowers::OnlyIntegers($context); + +For the Interger power functions, you can pass additional +parameters that control the range of values that are allowed +for the powers. The oprtions include: + +=over + +=item S<C<< minPower => m >>> -=head3 LimitedPowers::NoBaseE(); +only integer powers bigger than or equal +to m are allowed. (If m is undef, then +there is no minimum power.) -=head3 LimitedPowers::OnlyIntegers(); +=item S<C<< maxPower => M >>> -=head3 LimitedPowers::OnlyNonNegativeIntegers(); +only integer powers less than or equal +to M are allowed. (If M is undef, then +there is no maximum power.) -=head3 LimitedPowers::OnlyPositiveIntegers(); +=item S<C<< message => "text" >>> -=head3 LimitedPowers::OnlyNonTrivialPositiveIntegers(); - - ########################################################## - # - # Implements subclasses of the "^" operator that restrict - # the base or power that is allowed. There are four - # available restrictions: - # - # No raising e to a power - # Only allowing integer powers (positive or negative) - # Only allowing positive interger powers - # Only allowing positive interger powers (and 0) - # - # You install these via one of the commands: - # - # LimitedPowers::NoBaseE(); - # LimitedPowers::OnlyIntegers(); - # LimitedPowers::OnlyPositiveIntegers(); - # LimitedPowers::OnlyNonNegativeIntegers(); - # - # Only one of the three can be in effect at a time; setting - # a second one overrides the first. - # - # These function affect the current context, or you can pass - # a context reference, as in - # - # $context = Context("Numeric")->copy; - # LimitedPowers::OnlyIntegers($context); - # - # For the Interger power functions, you can pass additional - # parameters that control the range of values that are allowed - # for the powers. The oprtions include: - # - # minPower => m only integer powers bigger than or equal - # to m are allowed. (If m is undef, then - # there is no minimum power.) - # - # maxPower => M only integer powers l... [truncated message content] |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 20:36:46
|
Log Message: ----------- remove each dest dir before regenerating docs Modified Files: -------------- admintools: ww-make-docs-from-cvs Revision Data ------------- Index: ww-make-docs-from-cvs =================================================================== RCS file: /webwork/cvs/system/admintools/ww-make-docs-from-cvs,v retrieving revision 1.4 retrieving revision 1.5 diff -Lww-make-docs-from-cvs -Lww-make-docs-from-cvs -u -r1.4 -r1.5 --- ww-make-docs-from-cvs +++ ww-make-docs-from-cvs @@ -35,6 +35,7 @@ our $CVS = "/usr/bin/cvs"; our $MKDIR = "/bin/mkdir"; +our $RM = "/bin/rm"; our $WW_MAKE_DOCS = '/home/sh002i/work/admintools/ww-make-docs'; #our $WW_MAKE_DOCS = '/home/sam/work/admintools/ww-make-docs'; @@ -76,6 +77,7 @@ my $dest_dir = $source_dir; $dest_dir =~ s/^$CHECKOUT_DIR/$DOC_DIR/; + system $RM, '-rf', $dest_dir; system $MKDIR, '-p', $dest_dir; if ($?) { my $exit = $? >> 8; |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 20:18:22
|
Log Message: ----------- uncommented things that were commented out for debugging Modified Files: -------------- admintools: ww-make-docs-from-cvs Revision Data ------------- Index: ww-make-docs-from-cvs =================================================================== RCS file: /webwork/cvs/system/admintools/ww-make-docs-from-cvs,v retrieving revision 1.3 retrieving revision 1.4 diff -Lww-make-docs-from-cvs -Lww-make-docs-from-cvs -u -r1.3 -r1.4 --- ww-make-docs-from-cvs +++ ww-make-docs-from-cvs @@ -53,8 +53,8 @@ next unless -d $dir; if ($dir =~ m/^([^\!\$\^\&\*\(\)\~\[\]\|\{\}\'\"\;\<\>\?]+)$/) { print "\n-----> $dir <-----\n\n" if $v; - #update_cvs($1); - #process_dir($1); + update_cvs($1); + process_dir($1); update_index($1); } else { warn "'$dir' insecure.\n"; |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 20:17:15
|
Log Message: ----------- added master index for all modules/versions Modified Files: -------------- admintools: ww-make-docs-from-cvs Revision Data ------------- Index: ww-make-docs-from-cvs =================================================================== RCS file: /webwork/cvs/system/admintools/ww-make-docs-from-cvs,v retrieving revision 1.2 retrieving revision 1.3 diff -Lww-make-docs-from-cvs -Lww-make-docs-from-cvs -u -r1.2 -r1.3 --- ww-make-docs-from-cvs +++ ww-make-docs-from-cvs @@ -23,20 +23,25 @@ use strict; use warnings; +use IO::File; $ENV{PATH} = ""; $ENV{ENV} = ""; our $CHECKOUT_DIR = '/webwork/docs2html'; our $DOC_DIR = '/webwork/www/main/doc/cvs'; +#our $CHECKOUT_DIR = '/home/sam/work/admintools/checkoutdir'; +#our $DOC_DIR = '/home/sam/work/admintools/docdir'; our $CVS = "/usr/bin/cvs"; our $MKDIR = "/bin/mkdir"; our $WW_MAKE_DOCS = '/home/sh002i/work/admintools/ww-make-docs'; +#our $WW_MAKE_DOCS = '/home/sam/work/admintools/ww-make-docs'; our $v; # for verbose switch my @dirs; +my %index; if (@ARGV) { @dirs = map "$CHECKOUT_DIR/$_", @ARGV; @@ -48,13 +53,18 @@ next unless -d $dir; if ($dir =~ m/^([^\!\$\^\&\*\(\)\~\[\]\|\{\}\'\"\;\<\>\?]+)$/) { print "\n-----> $dir <-----\n\n" if $v; - update_cvs($1); - process_dir($1); + #update_cvs($1); + #process_dir($1); + update_index($1); } else { warn "'$dir' insecure.\n"; } } +my $fh = new IO::File("$DOC_DIR/index.html", 'w') + or die "failed to open '$DOC_DIR/index.html' for writing: $!\n"; +write_index($fh); + sub update_cvs { my ($dir) = @_; @@ -83,3 +93,62 @@ } } +sub update_index { + my $dir = shift; + $dir =~ s/^.*\///; + if ($dir =~ /^(.+)_(.+?)(?:--(.*))?$/) { + my ($module, $version, $extra) = ($1, $2, $3); + if ($version =~ /^rel-(\d+)-(\d+)(?:-(\d+))?$/) { + my ($major, $minor, $patch) = ($1, $2, $3); + if (defined $patch) { + $version = "$major.$minor.$patch"; + } else { + $version = "$major.$minor.0"; + } + } elsif ($version =~ /^rel-(\d+)-(\d)-(?:patches|dev)$/) { + my ($major, $minor) = ($1, $2); + $version = "$major.$minor.x (bugfixes)"; + } elsif ($version eq "HEAD") { + $version = 'HEAD (development)'; + } else { + warn "unfamiliar version string '$version' for dir '$dir' -- not adding to index.\n"; + return; + } + $module =~ s/^pg$/PG/; + $module =~ s/^webwork2$/WeBWorK/; + if (defined $extra) { + $index{$module}{$version}{$extra} = $dir; + } else { + $index{$module}{$version} = $dir; + } + } else { + warn "unfamiliary dir format '$dir' -- not adding to index.\n"; + } +} + +sub write_index { + my $fh = shift; + print $fh "<html><head><title>WeBWorK Documentation from CVS</title></head><body>\n"; + print $fh "<h1>WeBWorK Documentation from CVS</h1>\n"; + print $fh "<ul>\n"; + print $fh map { "<li><a href=\"#$_\">$_</a></li>\n" } sort keys %index; + print $fh "</ul>\n"; + for my $module (sort keys %index) { + print $fh "<hr/>\n"; + print $fh "<h2><a name=\"$module\">$module</a></h2>\n"; + print $fh "<ul>\n"; + for my $version (sort keys %{$index{$module}}) { + if (ref $index{$module}{$version}) { + print $fh "<li>$version<ul>\n"; + for my $extra (sort keys %{$index{$module}{$version}}) { + print $fh "<li><a href=\"$index{$module}{$version}{$extra}\">$extra</a></li>\n"; + } + print $fh "</ul></li>\n"; + } else { + print $fh "<li><a href=\"$index{$module}{$version}\">$version</a></li>\n"; + } + } + print $fh "</ul>\n"; + print $fh "</body></html>\n"; + } +} |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 18:56:17
|
Log Message: ----------- ...but don't require podpp Modified Files: -------------- admintools: ww-make-docs Revision Data ------------- Index: ww-make-docs =================================================================== RCS file: /webwork/cvs/system/admintools/ww-make-docs,v retrieving revision 1.5 retrieving revision 1.6 diff -Lww-make-docs -Lww-make-docs -u -r1.5 -r1.6 --- ww-make-docs +++ ww-make-docs @@ -10,7 +10,7 @@ use IO::File; use Pod::Find qw(pod_find simplify_name contains_pod); use Pod::Html; -use Pod::PP; +#use Pod::PP; use POSIX qw(strftime); use Data::Dumper; |
From: Sam H. v. a. <we...@ma...> - 2007-10-02 18:54:58
|
Log Message: ----------- improve subdir handling, code to call podpp, maybe other things Modified Files: -------------- admintools: ww-make-docs Revision Data ------------- Index: ww-make-docs =================================================================== RCS file: /webwork/cvs/system/admintools/ww-make-docs,v retrieving revision 1.4 retrieving revision 1.5 diff -Lww-make-docs -Lww-make-docs -u -r1.4 -r1.5 --- ww-make-docs +++ ww-make-docs @@ -6,9 +6,11 @@ package WeBWorK::Utils::HTMLDocs; use File::Find; +use File::Temp qw(tempfile); use IO::File; -use Pod::Find qw(pod_find simplify_name); +use Pod::Find qw(pod_find simplify_name contains_pod); use Pod::Html; +use Pod::PP; use POSIX qw(strftime); use Data::Dumper; @@ -35,7 +37,6 @@ section_hash => $section_hash, section_order => $section_order, }; - #print Dumper($self); return bless $self, $class; } @@ -43,44 +44,71 @@ my $self = shift; my $source_root = $self->{source_root}; my $dest_root = $self->{dest_root}; - my @subdirs = do { + my $subdirs = do { my $dh; opendir $dh, $source_root; - grep { not (/^\./ or /^(CVS|.svn)$/) and -d "$source_root/$_" } - readdir $dh; - }; - my $subdirs = join(':', @subdirs); - - my %pods = pod_find({}, $source_root); - while (my ($pod_path, $pod_name) = each %pods) { - $self->process_pod($subdirs, $pod_path, $pod_name); - } + join ':', + grep { not (/^\./ or /^(CVS|.svn)$/) and -d "$source_root/$_" } + readdir $dh; + }; + $self->{subdirs} = $subdirs; + + find({wanted => $self->gen_pod_wanted, no_chdir => 1}, $source_root); $self->write_index("$dest_root/index.html"); } +sub gen_pod_wanted { + my $self = shift; + return sub { + my $path = $File::Find::name; + my $dir = $File::Find::dir; + my ($name) = $path =~ m|^$dir(?:/(.*))?$|; + $name = '' unless defined $name; + + if ($name =~ /^\./) { + $File::Find::prune = 1; + return; + } + unless (-f $path or -d $path) { + $File::Find::prune = 1; + return; + } + if (-d _ and $name =~ /^(CVS|RCS|.svn)$/) { + $File::Find::prune = 1; + return; + } + + return if -d _; + return unless contains_pod($path); + $self->process_pod($path); + }; +} + sub process_pod { - my ($self, $subdirs, $pod_path) = @_; + my ($self, $pod_path) = @_; my $source_root = $self->{source_root}; my $dest_root = $self->{dest_root}; my $dest_url = $self->{dest_url}; + my $subdirs = $self->{subdirs}; my $pod_name; my ($subdir, $filename) = $pod_path =~ m|^$source_root/(?:(.*)/)?(.*)$|; - my $subdir_rest; - if (defined $subdir and $subdir =~ m|/|) { - ($subdir_rest) = $subdir =~ m|^[^/]*/(.*)|; + my ($subdir_first, $subdir_rest); + if (defined $subdir) { + if ($subdir =~ m|/|) { + ($subdir_first, $subdir_rest) = $subdir =~ m|^([^/]*)/(.*)|; + } else { + $subdir_first = $subdir; + } } - if ($filename =~ /\.plx?$/ or $filename !~ /\./) { - $pod_name = $filename; + $pod_name = (defined $subdir_rest ? "$subdir_rest/" : "") . $filename; + if ($filename =~ /\.(plx?|pg)$/ or $filename !~ /\./) { $filename .= '.html'; } elsif ($filename =~ /\.pod$/) { - $pod_name = $filename; $pod_name =~ s/\.pod$//; $filename =~ s/\.pod$/.html/; } elsif ($filename =~ /\.pm$/) { - $pod_name = defined $subdir_rest ? "$subdir_rest/" : ""; - $pod_name .= $filename; $pod_name =~ s/\.pm$//; $pod_name =~ s|/+|::|g; $filename =~ s/\.pm$/.html/; @@ -91,6 +119,7 @@ #print "$pod_path - $pod_name\n"; $self->update_index($subdir, $html_rel_path, $pod_name); + #my $podpp_path = do_podpp($pod_path); do_mkdir($html_dir); do_pod2html( subdirs => $subdirs, @@ -100,6 +129,7 @@ pod_path => $pod_path, html_path => $html_path, ); + #unlink $podpp_path; } sub update_index { @@ -150,6 +180,18 @@ print $fh $header, $content_start, $content, $content_end, $footer; } +sub do_podpp { + my $in_path = shift; + my $pp = make Pod::PP(-incpath=>[],-symbols=>{}); + #my ($out_fh, $out_path) = tempfile('ww-make-docs-podpp.XXXXXX'); + #local *STDOUT = $out_fh; + my $out_path = "$in_path.podpp"; + local *STDOUT; + open STDOUT, '>', $out_path or die "can't redirect STDOUT to $out_path: $!"; + $pp->parse_from_file($in_path); + return $out_path; +} + sub do_mkdir { my $dir = shift; system '/bin/mkdir', '-p', $dir; |
From: dpvc v. a. <we...@ma...> - 2007-09-30 11:26:03
|
Log Message: ----------- Don't use dollar signs in the TeX output, since BEGIN_TEXT/END_TEX does command substitution then variable substitution then math, so \{$f->TeX\} would insert dollars, which would then be substituted as variables. Modified Files: -------------- pg/macros: contextPiecewiseFunction.pl Revision Data ------------- Index: contextPiecewiseFunction.pl =================================================================== RCS file: /webwork/cvs/system/pg/macros/contextPiecewiseFunction.pl,v retrieving revision 1.3 retrieving revision 1.4 diff -Lmacros/contextPiecewiseFunction.pl -Lmacros/contextPiecewiseFunction.pl -u -r1.3 -r1.4 --- macros/contextPiecewiseFunction.pl +++ macros/contextPiecewiseFunction.pl @@ -740,7 +740,7 @@ my $self = shift; my @cases = (); foreach my $If (@{$self->{data}}) { my ($I,$f) = @{$If}; - push(@cases,'\displaystyle{'.$f->TeX."}&\\text{if \$".$I->TeX."\$}"); + push(@cases,'\displaystyle{'.$f->TeX."}&\\text{if}\\ ".$I->TeX); } if (scalar(@cases)) { push(@cases,'\displaystyle{'.$self->{otherwise}->TeX.'}&\text{otherwise}') if defined $self->{otherwise}; |
From: dpvc v. a. <we...@ma...> - 2007-09-30 01:47:50
|
Log Message: ----------- Bring jsMath to version 3.4e: * Added ability for the tex2math to find LaTeX environments of the form \begin{xxx}...\end{xxx} outside of math mode. This is enabled by default for jsMath.ConvertLaTeX(), and can be enabled in the easy/load.js by setting the processLaTeXenvironments value to 1 (now the default). * Fixed issues with loading a local copy of jsMath in MSIE. Apparently, MSIE considers xmlHttpRequest calls for local files to be access violations, even when the calling file is also local, and so MSIE needs to use the non-xmlHttpRequest fallback method when loading jsMath locally. * Worked around a long-standing issue with MSIE where elements that are positioned using backwards skips could be clipped in some circumstances. In particular, the Chapter 18 commutative diagram now displays correctly, as do exponents that have been adjusted to the left. This was a vexing MSIE bug that is good to finally have worked around. * Fixed a problem with placement of accents in some situations (the italic correction was not being applied properly). * Worked around bug in MSIE where the \vec vector arrow was being clipped at the right. * Worked around bug in MSIE where \mapsto and \longmapsto were displayed incorrectly (space appeared between the arrow and the tail). Modified Files: -------------- webwork-modperl/htdocs/jsMath: jsMath-easy-load.js jsMath.js webwork-modperl/htdocs/jsMath/easy: load.js webwork-modperl/htdocs/jsMath/plugins: autoload.js tex2math.js webwork-modperl/htdocs/jsMath/uncompressed: jsMath.js Added Files: ----------- webwork-modperl/htdocs/jsMath/extensions: AMSmath.js Revision Data ------------- Index: jsMath-easy-load.js =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/jsMath-easy-load.js,v retrieving revision 1.2 retrieving revision 1.3 diff -Lhtdocs/jsMath/jsMath-easy-load.js -Lhtdocs/jsMath/jsMath-easy-load.js -u -r1.2 -r1.3 --- htdocs/jsMath/jsMath-easy-load.js +++ htdocs/jsMath/jsMath-easy-load.js @@ -71,11 +71,12 @@ jsMath.Easy.fixEscapedDollars) { jsMath.Easy.findCustomSettings = { - processSingleDollars: jsMath.Easy.processSingleDollars, - processDoubleDollars: jsMath.Easy.processDoubleDollars, - processSlashParens: jsMath.Easy.processSlashParens, - processSlashBrackets: jsMath.Easy.processSlashBrackets, - fixEscapedDollars: jsMath.Easy.fixEscapedDollars, + processSingleDollars: jsMath.Easy.processSingleDollars, + processDoubleDollars: jsMath.Easy.processDoubleDollars, + processSlashParens: jsMath.Easy.processSlashParens, + processSlashBrackets: jsMath.Easy.processSlashBrackets, + processLaTeXenvironments: jsMath.Easy.processLaTeXenvironments, + fixEscapedDollars: jsMath.Easy.fixEscapedDollars, custom: 0 } } @@ -101,6 +102,7 @@ jsMath.Easy.processDoubleDollars || jsMath.Easy.processSlashParens || jsMath.Easy.processSlashBrackets || + jsMath.Easy.processLaTeXenvironments || jsMath.Easy.fixEscapedDollars || jsMath.Easy.customDelimiters); Index: jsMath.js =================================================================== RCS file: /webwork/cvs/system/webwork-modperl/htdocs/jsMath/jsMath.js,v retrieving revision 1.38 retrieving revision 1.39 diff -Lhtdocs/jsMath/jsMath.js -Lhtdocs/jsMath/jsMath.js -u -r1.38 -r1.39 --- htdocs/jsMath/jsMath.js +++ htdocs/jsMath/jsMath.js @@ -40,11 +40,11 @@ //start = new Date().getTime(); jsMath.Script.Uncompress([ - ['if(!','window','.','jsMath','||!',1,'.','jsMath.','loaded','){var ','jsMath_old','=',1,'.',3,';',0,'document.','getElementById','||!',17,'childNodes||!',17,'createElement','){','alert("','The',' mathematics ','on this page requires W3C DOM support in its JavaScript. "+"Unfortunately, your ','browser',' doesn\'t seem to have this.")}','else{',1,'.',3,'={version:"3.4d",document:document,',1,':',1,',','platform',':(','navigator.',40,'.match(/','Mac/)?"mac":',42,40,44,'Win/)?"pc":"unix"),','sizes',':[50,60,70,85,100,120,144,173,207,249],','styles',':{".math','":"font-family',':serif; font-style:normal; font-weight:normal','",".typeset',54,55,'; ','line-height:normal','","div.','typeset','":"text-align',':center; margin:1em 0px;","span.',62,63,':left',56,' span',63,67,'; border:','0px; margin:0px; ','padding:0px','",".typeset .','normal',54,55,75,'size0','":"font-size:','50','%",".typeset .','size1',81,'60',83,'size2',81,'70',83,'size3',81,'85',83,'size4',81,'100',83,'size5'! ,81,'120',83,'size6',81,'144',83,'size7',81,'173',83,'size8',81,'207',83,'size9',81,'249',83,'cmr10',54,':',3,'-cmr10',', serif',75,'cmbx10',54,':',3,'-',127,', ',3,124,75,'cmti10',54,':',3,'-',137,', ',3,124,75,'cmmi10',54,':',3,'-',147,75,'cmsy10',54,':',3,'-',154,75,'cmex10',54,':',3,'-',161,75,'textit',54,':serif; ','font-style:italic',75,'textbf',54,':serif; font-weight:bold',75,'link":"','text-decoration:none',75,'error',81,'10pt; ',171,'; "+"','background-color',':#FFFFCC; padding:1px',184,'border:','1px solid',' #CC0000',75,'blank','":"','display:inline-block','; ','overflow:hidden',72,'0px none; width:0px','; height:','0px;",".',62,' .','spacer','":"',194,'","#jsMath_hiddenSpan":"','visibility',':','hidden','; ','position:absolute','; top:0px',';left:0px',184,60,'; text-indent:0px","#','jsMath_message','":"','position:fixed','; bottom:','1px; left:2px; ',185,':#E6E6E6','; "+"border:solid 1px #959595; margin:0px; padding:','1px 8px','; "+"z-index:102; color',': blac! k','; font-size:','small; ','width:auto',';","#','jsMath_panel! ','":"', 219,220,'1.5em; right:1.5em','; padding:.8em 1.6em',184,185,':#DDDDDD',72,'outset 2px',184,'z-index:103; ',230,'; color:black',228,'10pt; font-style:normal","#',232,' .disabled":"color:#888888","#',232,' .infoLink',81,'85%","#',232,' *":"','font-size:inherit; font-style:inherit; font-family:inherit','; ',60,'","#',232,' div":"',185,':inherit; color:inherit;","#',232,' span":"',185,264,232,' td','":"border:0px; padding:0px; margin:0px; background-color:inherit; color:inherit;","#',232,' tr',271,232,' table',271,'jsMath_button','":"',219,220,'1px; right:2px; ',185,':white',224,'0px 3px 1px 3px',226,':black; ',178,228,'x-small',184,230,'; cursor:hand;","#',278,256,74,72,73,60,184,257,'","#jsMath_global":"',171,';","#jsMath_float','":"',211,212,'; left:0px; max-width:80%; "+"z-index:101; ',230,'; height:auto',305,' .drag":"',185,':#DDDDDD',72,'outset 1px',199,'12px',228,'1px',305,' .close":"',185,223,72,'inset 1px; width:8px',199,'8px; margin:1px 2px',305,' .source":"',185,':#E2! E2E2',72,317,184,230,311,'; padding:8px 15px',184,'font-family:courier, fixed',228,'90%","#jsMath_noFont .message',63,': center',237,72,'3px solid #DD0000',184,185,':#FFF8F8; color: #AA0000',228,229,230,231,'jsMath_noFont .link','":"',74,' 5px 2px 5px',72,'2px outset; ',185,':#E8E8E8',184,'color:black',228,'80%; ',230,294,'jsMath_PrintWarning',' .message',63,':center',237,72,'3px solid #DD0000',184,185,': #FFF8F8; color: #AA0000',228,'x-',229,230,';","@media print":"#',278,' {display:none','}\\n"+"#jsMath_Warning',386,'}","@media screen":"#',370,386,'}"},Element',':function(','A){return ',7,17,18,'("jsMath_"+A)},','BBoxFor',393,'A){this.','hidden.innerHTML','="<nobr><','span class=\\"',62,'\\"><',404,'scale\\">"+A+"</span></span></nobr>";var B={w:this.',209,'.offsetWidth',',h:this.',209,'.offsetHeight','};this.',402,'="";return B},EmBoxFor',393,'B){var A=',7,'Global.cache.R;if(!A[this.em]){A[this.em]={}}if(!A[this.em][B]){var C=this.BBoxFor(B);','A[this.em][B]={w:C.w/this.e! m,h:C.h/this.em}}return A[this.em][B]},','EmBoxForItalics',393! ,418,7,4 20,'if(B.match(/<i>|class=\\"(icm|italic|igreek|iaccent)/i)){C.w','=this.BBoxFor','(B+',7,'Browser.','italicString',').w-',7,431,'italicCorrection','}',421,'Init',':function(){','if(',7,'Setup.inited','!=1){',0,7,443,'){',7,'Setup.','Body()}if(',7,443,'!=1){if(',7,443,'==-100','){return }',25,'It looks like ',3,' failed to set up properly (error code "+',7,443,'+"). "+"I will try to keep going, but it could get ugly.");',7,443,'=1}}this.em',428,'("<span style=\\""+',7,431,'block+";','width:13em;height:1em','\\"></span','>").w/13;if(this.em==0','){this.','em',428,'("<img src=\\""+',7,192,'+"\\" style=\\"',474,'\\"/>").w/13}','var A=',7,'Global.cache','.B;',0,'A[this.em]){A[this.em]={};','A[this.em].','bb',428,'("x");','var C=',492,'bb.h;',492,'d',428,'("x"+',7,'HTML.Rule(1,','C/',7,'em)).h-C;if(',7,431,432,'){',492,'ic=',7,399,'(',7,431,432,').w}}',7,431,436,'=',492,'ic;var F=',492,'bb;var D=F.h;var E=',492,'d;this.h=(D-E)/this.em;this.d=E/this.em;this.hd=this.h+this.d;this.! xWidth=F.w;this.',450,'TeXfonts','();var B=this.EmBoxFor("<',404,120,'\\">M</span>").w/2;this.TeX.M_height=B*(26/14);this.TeX.h=this.h;this.TeX.d=this.d;this.TeX.hd=this.hd;this.Img.Scale();',0,'this.initialized',477,450,'Sizes','();this.','Img.UpdateFonts()}this.p_height=(','this.TeX.cmex10[0].','h+',544,'d)/0.85;',538,'=1},ReInit',440,'var A',428,'("x").w;if(A!=this.xWidth',477,'Init()}},Loaded',440,'if(',10,9,'B=["Process","ProcessBeforeShowing","ConvertTeX","ConvertTeX2","ConvertLaTeX","ConvertCustom","CustomSearch","Synchronize","Macro","document"];','for(var A=0;A<','B','.length;A++){','if(',10,'[B[A]]){delete ',10,'[B[A]]}}}if(',10,'){this.Insert(',3,',',10,')}',10,'=null;',7,8,'=1},Add',393,'C,A){for(var B in A){','C[B]=A[B]}},Insert',393,581,'if(C[B]&&typeof (A[B])=="object"&&(','typeof (C[B])=="','object"||',586,'function")){this.Insert(C[B],A[B])}',31,'C[B]=A[B]}}},Package',393,'B,A',570,'B.prototype,A)}};',7,'Global={isLocal:1,cache:{','T:{},D:{},R:{},B',':{}},C! learCache',440,7,488,'={',598,':{}}},GoGlobal',393,418,'String! (',7,1,' .','location);','var C=(',7,'isCHMmode','?"#":"?");if(B){A=A.replace(/\\?.*/,"")+"?"+B}',7,'Controls.','Reload(',7,'root+"',3,'-global.html"+C+escape(A))},Init',440,'if(',7,'Controls.cookie.','global=="always"&&!',7,'noGoGlobal','){','if(navigator.','accentColorName',458,0,7,1,'){',7,1,'=',1,'}',7,618,8,'=1;',7,618,'defaults.hiddenGlobal',576,'this.GoGlobal(',7,618,'SetCookie(2))}},Register',440,486,7,1,'.parent;',0,7,'isCHMode){',7,615,'=(',7,1,'.','location.protocol','=="mk:")}try{',0,7,615,477,'Domain()}if(A.',3,'&&A.',7,'isGlobal){A.',7,'Register(',7,1,')}}catch(B){',7,630,'=1}},Domain',440,632,'appName=="Microsoft Internet Explorer"&&',7,40,'=="mac"&&',42,'userProfile','!=null',458,'if(',1,'==parent',458,'var B=',7,17,'domain;try{while(true){try{if(parent.',17,'title',697,'){return }}','catch(A){}',0,17,'domain.match(/\\..*\\./)){break}',7,17,'domain=',7,17,'domain.replace(/^[^.]*\\./,"")}}',711,7,17,717,'B}};',7,'Script={request:null,Init',440,'if(!(',7,627,'asynch&&',! 7,627,'progress',')){if(',1,'.XMLHttpRequest','){try{','this.request','=new XMLHttpRequest}catch(C){}}',0,740,'&&',1,'.','ActiveXObject',9,'A=["MSXML2.XMLHTTP.5','.0","MSXML2.XMLHTTP','.4',750,'.3',750,'","Microsoft.XMLHTTP"];','for(var B=0;B<','A.length&&!',740,';B++){try{',740,'=new ',747,'(A[B])}catch(C){}}}}',0,740,'||',7,450,'domainChanged',477,'Load=this.delayedLoad;this.needsBody=1}},Load',393,'B,A){if(A){',7,'Message.Set("Loading "+','B);',7,'Script.','Delay(1);',7,'Script.Push(','this,"xmlRequest",B',');',7,781,7,'Message',',"Clear")}',31,7,781,782,')}},xmlRequest',393,'url){','this.blocking','=1;try{',740,'.open("GET",url,false);',740,'.send(null)}catch(err){',796,'=0;if(',7,'Translate.','restart&&',7,'Translate.asynchronous){return""}throw"jsMath can\'t load the file \'"+url+"\'\\n"+"',787,': "+err.message}if(',740,'.status','&&',740,812,'>=400){',796,803,7,805,'restart&&',7,808,'Error status: "+',740,812,'}',0,'url','.match(/\\.js$/)){','return(',740,'.responseT! ext',')}var tmpQueue','=this.queue;this.queue','=[];',7,1,'.ev! al(',740 ,833,');',796,'=0;','this.queue=this.queue.','concat(','tmpQueue);this.Process();return""},cancelTimeout:30*1000,iframe:null,blocking:0,cancelTimer:null,needsBody:0,queue:[],Synchronize',393,'A,B){','if(typeof (','A)!="string"){',7,781,'null,A,B)}',31,7,781,7,1,',"eval",A)}},Push',393,'A,C,B',477,'queue[','this.queue.length',']=[A,C,B];if(!(',796,'||(this.needsBody&&!',7,17,'body))){this.Process()}},Process',440,'while(',865,'&&!',796,9,'C=this.queue[0];',845,'slice(1);',486,'this.SaveQueue();var B=C[0];var E=C[1];var D=C[2];if(B){B[E](D)}',31,'if(E){E(D)}}this.','RestoreQueue','(A)}},SaveQueue',440,'var A',835,'=[];return A},',885,393,'A){',845,846,'A)},delayedLoad',393,401,'Push(this,"startLoad",A)},startLoad',393,'A){','this.iframe','=',7,17,23,'("iframe");','this.iframe.style.',207,'="',209,'";',908,'position="absolute";',908,'width="0px";',908,'height="0px";if(',7,17,'body.firstChild','){',7,17,'body.insertBefore(',902,',',7,17,921,')}',31,7,17,'body','.appendChild(',90! 2,')}',796,'=1;this.','url=A;',0,'A',830,902,'.src=A}',31,902,'.src=',7,621,3,'-loader.html"}if(A.substr(0,',7,'root.length',')==',7,'root){A=A.substr(',7,955,')}',7,775,'A);','this.cancelTimer','=setTimeout("',7,778,'cancelLoad','()",this.cancelTimeout)},endLoad',393,'A){if(',965,'){clearTimeout(',965,');',965,'=null}',7,787,'.Clear();if(A!="cancel"){',796,'=0;this.Process','()}},Start',440,'this.tmpQueue',835,'=[]},End',440,845,846,986,');delete ',986,'},',969,440,965,576,7,787,'.Set("Can\'t load file");this.endLoad("cancel")},Delay',393,'A){',796,'=1;setTimeout("',7,778,'endDelay','()",A)},',1009,440,796,983,'()},','imageCount',':0,WaitForImage',393,'B){',796,940,1016,'++;if(this.img==null',477,'img=[]}',486,'new Image',542,'img[this.img.length]=A;A.onload=function(){if(--',7,778,1016,'==0){',7,778,1009,'()}};A.onerror=A.onload;A.onabort=A.onload;A.src=B},Uncompress',393,'data){for(var k=0;k<data.length;k++){var d=data[k];var n=d.length;for(var i=0;i<n;i++){',850,'d[i])=! ="number"){d[i]=d[d[i]]}}data[k]=d.join("")}',1,839,'data.join! (""))}}; ',7,787,'={',192,':null,message:null,text:null,clear:null,Init',440,0,7,17,'body||!',7,627,735,458,'if(',7,450,'stylesReady){','this.message','=',7,'Setup.DIV("message",{visibility:"hidden','"})}',31,1063,'=',7,1066,'",position:"absolute",','bottom:"1px",left:"2px",','backgroundColor',':"#E6E6E6",border:"solid 1px #959595",margin:"0px",padding:"1px 8px",zIndex:102,color:"black",fontSize:"small",width:"auto"})}','this.text','=',7,17,'createTextNode','("");',1063,936,1077,');',1063,'.onmousedown=',7,805,'Cancel},Set',393,'B,A){','if(this.clear){clearTimeout(this.clear',');','this.clear',978,'if(',7,627,735,'){',0,1077,477,'Init();',0,1077,710,'if(',7,431,'textNodeBug','){',1063,'.innerHTML','=B}',31,1077,'.nodeValue','=B}','this.message.style.',207,'="visible";if(A){',1122,'cursor="pointer";',0,1122,'cursor){',1122,'cursor="hand"}',1063,'.title=" Cancel Processing of Math "}',31,1122,'cursor="";',1063,'.title=""}}',31,'if(B.substr(0,8)!="Loading "){',7,1,812,'=B}}},Clear',440,! 1094,')}',1096,'=setTimeout("',7,787,'.doClear()",1000)},doClear',440,'if(',1096,'){',1096,576,7,1,812,'="";if(',1077,'){',1077,1120,'=""}if(',1063,'){',1122,207,'="',209,'"}}},Blank',440,'if(','this.blank','||!',7,17,'body',458,1177,'=',7,450,'DIV("',192,'",{position:(',7,431,'msiePositionFixedBug','?"absolute":"fixed"),top:"0px",left:"0px",bottom:"0px",right:"0px",zIndex:101,',1075,':"white"});if(',7,431,'msieBlankBug','){',1177,1116,'=" ";',1177,'.style.width="110%";',1177,'.style.height="110%"}},UnBlank',440,'if(',1177,'){',7,17,'body.removeChild(',1177,')}',1177,'=null}};',7,'Setup={',8,':[],DIV',393,'D,B',9,'C=',7,17,23,'("div");C.id="jsMath_"+D;','for(var A in ','B){C.style[A]=B[A]}',0,7,17,'body.hasChildNodes){',7,17,'body',936,'C)}',31,7,17,925,'C,',7,17,921,')}return C},Script',393,'B,A){if(this.',8,'[B]){return }',31,'this.',8,'[B]=1}',0,'B.match("^([a-zA-Z]+:/?)?/")){B=',7,'root+B}',7,778,'Load(B,A)},Hidden',440,7,209,'=this.DIV("Hidden",{',207,':"',209,107! 3,'top:0,left:0,border:0,padding:0,margin:0});',7,'hiddenTop='! ,7,209,' ;return },Source',440,'if(',7,'Autoload&&',7,'Autoload.root','){',7,'root=',7,1284,'}',31,7,'root="";',486,7,17,'getElementsByTagName("','script");if(A){',756,'A.','length;B++){',496,'A[B].src;if(C&&C.match("(^|/)',7,'js$")){',7,1287,'C.','replace(/',7,'js$/,"");B=A.length}}}}if(',7,'root.charAt(0)=="/"){',7,1287,7,17,670,'+"//"+',7,17,'location.host+',7,'root}',31,0,7,'root.match','(/^[a-z]+:/i)){C=','new String(',7,17,612,7,1287,'C','.replace(new RegExp','("[^/]*$"),"")+',7,'root;while(',7,1328,'("/[^/]*/\\\\.\\\\./")){',7,1287,7,'root',1337,'("/[^/]*/\\\\.\\\\./"),"/")}}}',7,'Img.',1287,7,621,'fonts/";',7,192,'=',7,621,192,'.gif";this.Domain()},Domain',440,'try{',7,17,'domain}catch(D',458,'var C="";',486,7,17,'domain;if(',7,1328,'("://([^/]*)/")){C=RegExp.$1}C=C.replace(/:\\d+$/,"");if(C==""||C==A',458,632,'appName=="Microsoft Internet Explorer"&&',7,40,'=="mac"&&',42,'onLine&&',42,696,'&&',7,17,'all',458,'C=C.split(/\\./);A=A.split(/\\./);if(C.length<2||A.length<2||','C[! C.length-','1',']!=A[A.length-','1]||',1393,'2',1395,'2]){this.','DomainWarning','();return }var E=',1393,'2]+"."+',1393,'1];for(var B=3;B<=C.length&&B<=A.',1301,'if(',1393,'B',1395,'B]){break}E=',1393,'B]+"."+E}',7,17,717,'E;this.',769,'=1},',1401,440,25,'In order for ',3,' to be able to load the additional "+"components that it may need, the ',7,'js file must be "+"',8,' from a server in the same domain as the page that "+"contains it. Because that is not the case for this page, "+"the',27,'displayed here may not appear correctly.")},','EncodeFont',393,'C',9,'B=',7,'TeX[C];if(B','[0].c',697,458,561,'128;A++){var D=B[A];B[A]=D[3];if(B[A]==null){B[A]={}}B[A].w=D[0];B[A].h=D[1];if(D[2]!=null){B[A].d=D[2]}B[A].c=',7,'TeX.encoding[A]}},Fonts',440,756,7,'TeX.fam.length;','B++){',486,7,'TeX.fam[','B];if(',401,1433,'(A)}}},TeXfont',393,'C',9,'B=',7,1439,'==null',458,486,7,'EmBoxFor("<span class=\\""+C+"\\">"+B[65].c','+"</span>");B.hd=A.h;B.dh=0.05;B.d=',7,1469,'+',7,504,'B.hd)+! "</span>").h-B.hd;B.h=B.hd-B.d;','if(C=="',147,'"){B.skewchar=! ','127}' ,31,1477,154,1479,'48}}},',532,440,561,7,1450,'A++){if(',7,1454,'A]){this.TeXfont(',7,1454,'A])}}},Sizes',440,7,'TeXparams','=[];var B;var A;for(A=0;A<',7,50,563,7,1500,'[A]={}}for(B in ',7,'TeX){',850,7,'TeX[B])!="object"){for(A=0;A<',7,50,563,7,1500,'[A][B]=',7,50,'[A]*',7,'TeX[B]/100}}}},Styles',393,'A){',0,'A){A=',7,52,';A[".',62,' .scale"]="font-size:"+',7,627,'scale+"%";this.stylesReady=1}',7,781,'this,"','AddStyleSheet','",A);if(',7,431,'styleChangeDelay','){',7,781,7,'Script,"Delay",1)}},',1539,393,'D',9,'B=',7,17,1297,'head")[0];var A="";for(var E in D){A+=E+" {"+D[E]+"}\\n"}if(',7,17,'createStyleSheet){B.insertAdjacentHTML("beforeEnd","<','span style=\\"','display:none\\">x</span>"+"<style type=\\"text/css\\">"+A+"</style>")}',31,496,7,17,23,'("style");C.type="text/css";C',936,7,17,1081,'(A));B',936,'C)}},Body',440,'if(this.inited',458,'this.inited=-','1;',7,450,'Hidden();',1579,'2;',7,431,1106,1579,'3;if(',7,627,192,'){',7,787,'.Blank()}',1579,'4;',7,450,'Styles()! ;',1579,'5;',7,618,1106,1579,'6;',7,781,7,'Setup,"User","pre-font");',1579,'7;',7,781,7,'Font,"Check");if(',7,'Font.register.length){',7,781,7,'Font,"LoadRegistered")}this.inited=1},User',393,'A){if(',7,'Setup.UserEvent[A',']){(',7,1629,'])()}},UserEvent:{"pre-font":null,"onload":null}};',7,'Update={',532,393,'D){',1230,'D){for(var B in D[A]){for(var C in D[A][B]){',7,'TeX[A][B][C]=D[A][B][C]}}}},TeXfontCodes',393,'C){',1230,'C){',756,'C[A].',1301,7,'TeX[A][B].c=C[A][B]}}}};',7,'Browser={allowAbsolute:1,allowAbsoluteDelim:0,separateSkips:0,valignBug:0,operaHiddenFix:"",','msieCenterBugFix',':"",','msieInlineBlockFix',':"",','msieSpaceFix',':"",imgScale:1,renameOK:1,',1543,':0,delay:1,version:0,','TestSpanHeight',440,7,402,'="<span','><','span style=\\""+this.block+";','height:2em;width:','1px',475,'></span>";var B=',7,'hidden.firstChild;',486,'B.firstChild;','this.spanHeightVaries','=(B',413,'>=A',413,'&&B',413,'>0);','this.spanHeightTooBig','=(B',413,'>A',413,');',7,402,'=! ""},','TestInlineBlock',440,'this.block','="display:-moz-inlin! e-box";' ,'this.hasInlineBlock','=',7,'BBoxFor("<span style=\\""+this.block+";','width:10px;height:5px\\"></span>").w>0;if','(',1698,'){',7,'styles[".typeset .',192,'"]=',7,1707,192,'"].replace(/',194,'/,',1696,');',7,1707,203,'"]=',7,1707,203,1713,194,'/,"")}',31,1696,'="',194,'";',1698,'=',7,1701,1702,'(!',1698,710,1696,'+=";',196,'";',486,7,399,'("x").h;this.mozInlineBlockBug=',7,1701,'height:"+A+"px;width:1px',475,'>x"+"<',1668,1751,';vertical-align:-"+A+"px',475,'>").h>2*A;this.widthAddsBorder=',7,1701,196,';height:1px;width:10px',';border-left:','10px solid',475,'>").w>10;','this.msieBorderBug','=',7,1701,1751,475,'>x").h!=',7,1701,1751,1763,189,475,'>x").h;this.blankWidthBug=',1767,'||',7,1701,1669,'0px',475,'>").h==0},','TestRenameOK',440,7,402,1666,'></span>";',486,7,1674,'A.setAttribute("name","','jsMath_test','");this.renameOK=(',7,17,'getElementsByName("',1799,'").length>0);',7,402,1693,'TestStyleChange',440,7,402,1666,' ID=\\"',1799,'\\">x</span>";var B=',7,1674,486,'B',! 410,';',7,450,1539,'({"#',1799,81,'200%"});this.',1543,'=(B',410,'==A);',7,402,1693,'VersionAtLeast',393,418,1330,'this.version',').split(".");','B=',1330,'B',1842,'if(B[1]==null){B[1]="0"}return A[0]>B[0]||(A[0]==B[0]&&A[1]>=B[1])},Init',440,7,29,'="unknown";this.',1694,542,1662,542,1789,542,1809,542,'MSIE',542,'Mozilla',542,'Opera',542,'OmniWeb',542,'Safari',542,'Konqueror','();if(','this.allowAbsoluteDelim','){',7,'Box.DelimExtend=',7,'Box.DelimExtendAbsolute;',7,'Box.Layout=',7,'Box.LayoutAbsolute}',31,7,'Box.DelimExtend=',7,'Box.DelimExtendRelative;',7,'Box.Layout=',7,'Box.LayoutRelative}if(','this.separateSkips','){',7,'HTML.Place=',7,'HTML.','PlaceSeparateSkips',';',7,'Typeset.prototype.','Place=',7,1900,1897,'}},MSIE',440,'if(',1677,'&&!',1685,'){',7,29,'="MSIE";if(',7,40,'=="pc"){this.','IE7=(',1,738,697,');this.quirks=(',7,17,'compatMode=="BackCompat");this.msieStandard6=!this.quirks&&!','this.IE7',';',1872,'=1;',1891,'=1',';this.buttonCheck=1;this.',1198,'=1;this! .msieDivWidthBug=1;this.',1192,940,'msieIntegralBug',940,'wait! ForImage s',940,'msieAlphaBug=!',1926,';this.','alphaPrintBug','=!',1926,';this.',1654,'="position:relative; ";this.',1656,'=" ',194,';";this.msieTeXfontBaselineBug=!',7,431,'quirks;',7,627,'font=="tex";',0,1926,477,1658,'="<',1561,194,475,'>"}',7,'Macro("joinrel","\\\\mathrel{\\\\kern-5mu}"),',7,1707,'arial"]="font-family: \'Arial unicode MS\'";',0,1926,'||this.quirks){',7,'styles["#',217,'"]=',7,1978,217,1713,219,'/,"',211,'").',1309,230,'/,"");',7,1978,232,'"]=',7,1978,232,1713,219,'/,"',211,'").',1309,230,'/,"");',7,1978,278,'"]="width:','1px; "+',7,1978,278,1713,219,'/,"',211,'").',1309,230,'/,"");',7,1,'.attachEvent("','onscroll",',7,618,'MoveButton',');if(',1926,'){',7,1,2025,'onresize",',7,618,2029,')}this.msieMoveButtonHack=',1926,'}',7,1978,356,'"]+=" ','display: inline-block',';";',7,1707,203,'"]=',7,1707,203,1713,194,'/,"");',7,52,'[".tex2math_div"]=',7,52,'["div.',62,'"]+"; width: 100%; ',2047,'";if(','screen.deviceXDPI','&&','screen.logicalXDPI','&&',2069,'!=',2071,477,! 'imgScale*=',2071,'/',2069,';',7,627,'alpha=0}this.',432,'="<i>x</i>";',7,'EmBoxFor=',7,422,'}',31,'if(',7,40,'=="mac"){this.msieAbsoluteBug',940,'msieButtonBug',1934,1198,940,'quirks=1;',7,450,'Script("',3,'-msie-mac.js");',7,'Parser.prototype.macros.angle=["Replace","ord","<font face=\\"Symbol\\">‹</font>","normal"];',7,1978,232,2010,'42em; "+',7,1978,232,1713,230,'/,"");',7,627,'printwarn=0}}',7,'Macro("not","\\\\mathrel{\\\\rlap{\\\\kern3mu','/}}")}},',1862,440,'if(',7,209,'.ATTRIBUTE_NODE){',7,29,'="',1862,'";if(',7,40,1917,1944,'=1}',1872,'=1;',7,1978,278,'"]=',7,1978,278,1713,'cursor:hand','/,"cursor:pointer");',7,1978,356,'"]=',7,1978,356,1713,2153,'/,"cursor:pointer");',7,2125,'/}}");',632,'vendor=="Firefox"){',1841,'=',42,'vendorSub}',31,632,'userAgent.match','(" Firefox/([0-9.]+)( |$)")){',1841,'=RegExp.$1}}}},',1866,440,632,'accentColorName){',7,29,'="',1866,'";','this.allowAbsolute','=',1698,';',1872,'=',2189,';this.valignBug=!',2189,1932,1113,'=1;',7,'noC! hangeGlobal=1;',0,1698,'){',7,'Setup.Script("jsMath-old-browse! rs.js',' ")}}},Opera',440,'if(',1685,'){',7,29,'="Opera";',486,42,2176,'("Opera 7");',2189,'=0;this.delay=10;this.operaHiddenFix="[Processing]";if(A){',7,2207,'")}}},Safari',440,632,'appVersion',44,'Safari\\//)){',7,29,'="Safari";',486,42,2176,'("Safari/([0-9]+)");A=(A)?A[1]:400;',756,7,1450,'B++){if(',7,1454,'B]&&',7,'TeX[',7,1454,'B]]){',7,'TeX[',7,1454,'B]].dh=0.1}}',7,'TeX.axis_height+=0.05;',7,'TeX.default_rule_thickness+=0.025;',1872,'=A>=125;this.safariIFRAMEbug=A>=312&&A<412;this.safariButtonBug=A<412;this.safariImgBug',940,1113,'=1',1932,1543,'=1}},',1870,440,632,'product&&',42,'product.match("',1870,'")){',7,29,'="',1870,'";',2189,'=0;',1872,'=0;',632,2176,'(/',1870,'\\/(\\d+)\\.(\\d+)/)){if(RegExp.$1<3||(RegExp.$1==3&&RegExp.$2<3)){',1891,940,'valignBug=1;',7,2207,'")}}',7,'Add(',7,52,',{".',62,' .',120,54,': ','jsMath-cmr10, jsMath cmr10',', serif',75,127,54,': ',3,'-',127,', ',3,' ',127,', ',2304,75,137,54,': ',3,'-',137,', ',3,' ',137,', ',2304,75,147,54,': ',3,'-',147,! ', ',3,' ',147,75,154,54,': ',3,'-',154,', jsMath'], - [' ','cmsy10','",".typeset .','cmex10','":"font-family: ','jsMath-cmex10, jsMath cmex10','"});','jsMath.','Font.testFont','="',5,'"}}};',7,'Font={testFont:"jsMath-',3,'",','fallback',':"symbol",register:[],','message',':"<b>No jsMath TeX fonts found</b> -- using',' image fonts instead','.<br/>\\n"+"These',' may be slow and might not print well.<br/>\\n"+"Use the jsMath control panel to get additional information.",','extra_message',':"Extra TeX fonts not found: <b><span id=\\"jsMath_ExtraFonts\\"></span></b><br/>"+"Using',20,'. This',22,'print_message',':"To print higher-resolution math symbols, click the<br/>\\n"+"<b>Hi-Res Fonts for Printing</b> button on',' the jsMath control panel.<br/>\\n",','alpha_message',':"If the math symbols print as black boxes, turn off <b>image alpha channels</b><br/>\\n"+"using the <B>Options</B> pane of',30,'Test1',':function(','C',',F,D,E){if(F==null){F=124}if(D==null){D=2}if(E==null){E=""}var B=jsMath.BBoxFor("<span style=\\"font-family:! "+E+C+", serif\\">"+jsMath.TeX[C][F].c+"</span>");var A=jsMath.BBoxFor("<span style=\\"font-family: serif\\">"+jsMath.TeX[C][F].c+"</span>");return','(B.w>D*A.w&&B.h!=0)},Test2',35,'C',37,'(A.w>D*B.w&&B.h!=0)},CheckTeX',':function(){var A=',7,'BBoxFor("<span style=\\"font-family',': "+',7,8,'+", serif\\">"+',7,'TeX.',3,'[1','].c+"</span>");',7,'nofonts=((A.w*3>A.h||A.h==0)&&!this.Test1("cmr10','",null,null,"jsMath-"));if(',7,'nofonts&&(',7,'platform','!="mac"||',7,'browser!="Mozilla"||!',7,'Browser.','VersionAtLeast(1.5))){A=',7,45,': ',3,', serif\\">"+',7,51,3,'[1',54,7,56,'"));if(!',7,'nofonts){',7,'Setup.Script("jsMath-','BaKoMa-fonts.js")}}},Check',43,7,'Controls.','cookie;this.CheckTeX();if(',7,82,'if(A.autofont','||A','.font=="tex"){','A.font=this.',16,';if(A.warn){',7,'nofontMessage=1;A.warn=0;',7,88,'SetCookie(0);if','(',7,'window.NoFontMessage','){',7,105,'()}else{','this.Message(this.',18,')}}}}else{',92,'){A.font="tex"}if(A',94,'return }}if(',7,'noImgFonts){','A! .font="unicode"}if(A','.font=="unicode','"){',7,84,16,'-"+',7,! 61,'+".j s");',7,'Box.TeXnonfallback=',7,'Box.TeX',';',7,132,'=',7,'Box.TeXfallback;return }','if(!A.print&&A.printwarn){this.','PrintMessage','((',7,66,'alphaPrintBug&&',7,88,'cookie.alpha)?this.',28,'+this.',31,':this.',28,')}if(',7,66,'waitForImages){',7,'Script.','Push(',7,'Script,"WaitForImage",',7,'blank)}if(A.font=="symbol"){',7,84,16,'-symbols.js");',7,'Box.TeXnonfallback=',7,132,';',7,132,'=',7,138,7,'Img.SetFont','({cmr10',':["all"],','cmmi10',181,1,181,3,181,'cmbx10',181,'cmti10:["all"]});',7,'Img.LoadFont','("cm-fonts")},Message',35,'A){if(',7,'Element("Warning','")){','return }var ','B=',7,'Setup.DIV("','Warning','",{});B.innerHTML="<center><table><tr><td>"+"<div ','id=\\"jsMath_noFont\\"><div ','class=\\"message\\">"+A','+"<div style=\\"text-align:left\\"><span style=\\"float:left; margin: 8px 0px 0px 20px\\">"+"<span onclick=\\"',7,88,'Panel','()\\" title=\\" ','Open the ','jsMath Control Panel',' \\" class=\\"link\\">',213,'</span>"+"</span','><span style=\\"margin: 8! px 20px 0px 0px; float:right\\">"+"<span onclick=\\"',7,'Font.','HideMessage',211,'Remove this font warning ',18,214,'Hide this Message',216,'></div><div style=\\"height:6px\\"></div><br clear=\\"all\\"/></div></','div>"+"<div style=\\"width:22em; height:1px\\"></div>"+"</td></tr></table></center><hr/>"},',220,43,7,197,'");if(A','){A.style.display="none"}},',140,35,195,7,'Element("','PrintWarning',198,199,'B=',7,202,240,204,206,'+"</',228,'Register',35,'H,B){if(typeof (H)=="string"){H={name:H}}if(!',7,'Setup.inited','&&!B){','this.register','[',257,'.length]=H;',199,'I=H.name;var A=I.replace(/10$/,"");var F=',7,51,'fam.length;if(H.prefix==null){H.prefix=""}if(!H.style){H.style="font-family: "+H.prefix+I+", serif"}if(!H.styles){H.styles={}}if(!H.macros){H.macros={}}',7,51,'fam[F]=I;',7,51,'famName[I]=F;H.macros[A]=["HandleFont",F];',7,'Add(',7,'Parser.prototype.macros,H.macros);H.styles[".typeset ."+I]=H.style;',7,'Setup.Styles(H.styles);if(',7,'initialized){',7,158,'Push(',! 7,'Setup,"TeXfont",I)}var C=',7,88,'cookie;var E=!',7,'nofonts! &&H.test (I,H.testChar,H.testFactor,H.prefix);if(E&&C',94,'if(H.tex){H.tex(I,F,H)}return }if(!E&&C.warn&&C.font=="tex"&&!',7,82,'if(!C.fonts.match("/"+I+"/")){C.fonts+=I+"/";',7,88,102,'(!',7,197,198,110,23,')}var G=',7,239,'ExtraFonts");if(G){if(G','.innerHTML','!=""){G',308,'+=","}G',308,'+=" "+H.prefix+I}}}if(C',120,'"||',7,118,'if(H.',16,'){H.',16,'(I,F,H)}',199,'D={};D[I]=["all"];',7,179,'(D);',7,192,'(I);if(',7,'initialized){',7,158,'Push(',7,'Img,"Scale");',7,158,'Push(',7,'Img,"UpdateFonts")}},LoadRegistered',43,'0;while(A<',257,'.length){this.Register(',257,'[A++],1)}',257,'=[]},Load',35,'A){',7,'Setup.Script(this.URL(A))},URL',35,'A){','return ',7,'Img.root+A+"/def.js"}};',7,'Controls={cookie:{scale:100,font:"tex",autofont:1,scaleImg:0,alpha:1,warn:1,fonts:"/",printwarn:1,stayhires:0,button:1,progress:1,asynch:0,blank:0,print:0,keep:"0D",global:"auto",hiddenGlobal:1},cookiePath:"/",','noCookiePattern',':/^(file|mk):$/,Init',':function(){','this.panel=',7,202,'panel",{displa! y:"none"});if(!',7,66,'msieButtonBug){this.Button',109,'setTimeout("',7,88,'Button()",500)}},Panel',364,7,'Translate.Cancel();if(this.loaded){this.Main',109,7,158,'delayedLoad(',7,'root+"jsMath-controls.html")}},Button',43,7,202,'button",{});A.title=" Open ',213,' ";A',308,'="<span onclick=\\"',7,88,'Panel()\\">jsMath</span>";if(!',7,'Global.','isLocal&&!',7,'noShowGlobal){A',308,'+="<span id=\\"jsMath_global\\" title=\\" Open jsMath Global Panel \\" "+"onclick=\\"',7,398,'Show(1)\\">Global </span>"}if(A.offsetWidth<30){A.style.width="auto"}if(!','this.cookie','.button',234,'MoveButton',364,'var C=',7,'Controls;if(!C.button){C.button=',7,239,'button")}if(C.button','){C.MoveElement(C.','button,3,2)}var B=20;var A=20;if(C.button){A=C.button.offsetHeight+6;B=A+5}if(C.panel',418,'panel,B,A)}},MoveElement',35,'D,C,B){if(',7,66,'IE7){var A=document.body;D.style.right','="auto";D.style.','bottom',427,'left=A.clientWidth+A.scrollLeft-D.offsetWidth-C+"px";D.style.top=A.clientHe! ight+A.scrollTop-D.offsetHeight-B+"px"}else{','D.style.visibil! ity="',' hidden";',431,'visible"}},GetCookie',364,'if(','this.defaults','==null){',437,'={}}',7,273,437,',',407,');this.userSet={};var C=',7,'document.cookie',';if(',7,'window.location','.protocol.match(this.',362,')){C=this.','localGetCookie','();','this.isLocalCookie','=1}if(','C.match(/jsMath','=([^;]+)/)){var D=unescape(RegExp.$1).split(/,/);for(var B=0;B<D.length;B++){var A=D[B].match(/(.*):(.*)/);if(A[2].match(/^\\d+$/)){A[2]=1*A[2]}',407,'[A[1]]=A[2];this.userSet[A[1]]=1}}},',455,364,357,7,451,'.search.substr(1)},SetCookie',35,'F){var B=[];for(var E in ',407,'){if(',437,'[E]==null||',407,'[E]!=',437,'[E]){B[B.length]=E+":"+',407,'[E]}}B=B.join(",");if(',457,'){if(F==2){return"','jsMath="+escape(B)}','this.','localSetCookie','(B,F)}else{B=escape(B);if(B==""){F=0}if(','this.cookiePath','){B+="; path="+',487,'}if(','this.cookieDomain','){B+="; domain="+',491,'}if(',407,'.keep!="0D"){var A={D',':1000*60*60*24',',W',497,'*7,M',497,'*30,Y',497,'*365};var D=new Date;D.setTime(D.getTi! me()+',407,'.keep.substr(','0,1)*A[',407,506,'1,1)]);B+="; expires="+D.toGMTString()}if(B!=""){',7,448,'="jsMath="+B;var C=',7,448,';if(F&&!',459,'=/)){alert("Cookies must be enabled in order to save jsMath options")}}}',357,'null},',485,35,'B,C){if(!C){',199,'A=String(',7,451,').replace(/\\?.*/,"");if(B!=""){A+="?',483,'if(A!=',7,451,'.href){this.Reload(A)}},Reload',35,'A){if(!this.loaded){return }this.loaded=0;',7,255,'=-100;',7,398,'ClearCache();if(A){',7,451,'.replace(A)}else{',7,451,'.reload()}}};',7,'Click={CheckClick',35,'A){if(!A){A=',7,'window.event}if','(A.altKey){',7,88,'Panel()}},CheckDblClick',35,'B){if(!B){B=',7,553,'(!',7,'Click.DblClick){',7,'Extension.Require("double-click",1);var A=B;B={};for(var C in A){B[C]=A[C]}}',7,158,'Push(',7,'Click,"DblClick",[B,this.alt])}};',7,'TeX={thinmuskip:3/18,medmuskip:4/18,thickmuskip:5/18,x_height:0.430554,quad:1,num1:0.676508,num2:0.393732,num3:0.44373,denom1:0.685951,denom2:0.344841,sup1:0.412892,sup2:0.362892,sup3:0.28! 8888,sub1:0.15,sub2:0.247217,sup_drop:0.386108,sub_drop:0.05,d! elim1:2. 39,delim2:1,axis_height:0.25,default_rule_thickness:0.06,big_op_spacing1:0.111111,big_op_spacing2:0.166666,big_op_spacing3:0.2,big_op_spacing4:0.6,big_op_spacing5:0.1,integer:6553.6,scriptspace:0.05,nulldelimiterspace:0.12,delimiterfactor:901,delimitershortfall:0.5,scale:1,atom:["ord","op","bin","rel","open","close","punct","ord"],fam:["cmr10","cmmi10","',1,'","',3,'","cmti10","","cmbx10",""],famName:{cmr10:0,cmmi10:1,',1,':2,',3,':3,cmti10:4,cmbx10:6},encoding:["À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï","°","Ñ","Ò","Ó","Ô","Õ","Ö","·","Ø","Ù","Ú","Û","Ü","µ","¶","ß","ï","!",""","#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R",! "S","T","U","V","W","X","Y","Z","[","\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~","ÿ"],cmr10:[[0.625',',0.683],[0.','833',582,'778',582,'694',582,'667',582,'75',582,'722',582,'778',582,'722',582,'778',582,'722',582,'583',',0.694,0,{ic:0.0778,krn:{"39":0.0778,"63":0.0778,"33":0.0778,"41":0.0778,"93":0.0778},lig:{"105":','14,"108":15}}],[0.556',',0.694],[0.','556',606,'833',606,'833',606,'278',',0.431],[0.','306',',0.431,0.194],[0.','5',606,'5',606,'5,0.628],[0.5',606,'5,0.568],[0.75',606,'444,0,0.17],[0.5',606,'722',614,'778',614,'5,0.528,0.0972],[0.903,0.683],[1.01',582,'778,0.732,0.0486],[0.278',',0.431,0,{','krn:{"108":-0.278,"76":-0.319}}],[0.278',',0.694,0,{','lig:{"96":','60}}],[0.5',606,'833',',0.694,0.194],[','0.5',',0.75,0.0556],[0.','833',643,'778',606,'278',636,'krn:{"63":0.111,"33":0.111},lig:{"39":34}}],[0.389',',0.75,0.25],[0.','389',651,'5,0.75],[','0.7! 78,0.583,0.0833],[','0.278,0.106',',0.194],[0.','333',634,'lig! :{"45":' ,'123}}],[',656,'],[0.5',651,'5,0.644','],[0.5,0.644],[0.5,0.','644',666,'644',666,'644',666,'644],[0.5,0.644],[0.278',614,'278',616,'278,0.5',657,'778',',0.367,-0.133],[','0.472,0.5',657,'472',636,637,'62}}],[0.778',606,'75',',0.683,0,{krn:{"','116','":-0.0278,"','67',691,'79',691,'71',691,'85',691,'81',691,'84":-0.0833,"89":-0.0833,"86":-0.111,"87":-0.111}}],[0.','708',582,'722',582,'764',689,'88',691,'87',691,'65',691,'86',691,'89":-','0.0278}}],[0.','681',582,'653',',0.683,0,{','krn:{"111":-0.0833,"101":-0.0833,"117":-0.0833,"114":-0.0833,"97":-0.0833,"65":-0.111,"79":-0.0278,"67":-0.0278,"71":-0.0278,"81":-0.0278}}],[','0.785',582,'75',582,'361',689,'73":',718,'514',582,'778',689,'79',691,'67',691,'71',691,'81":-',718,'625',689,702,'917',582,'75',582,'778',689,'88',691,'87',691,'65',691,'86',691,'89":-',718,'681',689,'65','":-0.0833,"','111',691,'101',691,'97',691,'46',766,'44":-0.','0833}}],[0.','778,0.683',657,'736',689,'116',691,'67',691,'79',691,'71',691,'85',691,'8! 1',691,702,'556',582,'722',689,'121',691,'101',766,'111',766,'114',766,'97',766,'65',766,'117":-0.',776,'75',582,'75',',0.683,0,{ic:0.','0139,',723,'1.03',815,'0139,',723,'0.75',689,'79',691,'67',691,'71',691,'81":-',718,'75',815,'025,krn:{"101',766,'111',766,'114',766,'97',766,'65',766,810,776,'611',582,'278',651,'5',606,'278',651,'5',606,'278,0.668],[0.','278',636,637,'92}}],[0.5',634,'krn:{"118',691,'106":0.0556,"121',691,'119":-',718,'556,0.','694,0',',{krn:{"101":0.0278,"111":0.0278,"120":-0.0278,"100":0.0278,"99":0.0278,"113":0.0278,"118":-0.0278,"106":0.0556,"121":-0.0278,"119":-0.0278}}],[0.','444',634,'krn:{"104',691,'107":-',718,'556',606,'444',614,'306',604,'12,"102":11,"108":13}}],[0.5',',0.431,0.194,{','ic:0.','0139,krn:{"','106":',718,'556',636,'krn:{"116',691,'117',691,'98',691,'121',691,'118',691,'119":-',718,856,'306,0.668',657,'528',636,'krn:{"97','":-0.0556,"','101',691,'97',691,'111',691,'99":-',718,'278',606,'833',634,'krn:{"116',691,'117',691,'98',691,! '121',691,'118',691,'119":-',718,'556',634,'krn:{"116',691,'11! 7',691,' 98',691,'121',691,'118',691,'119":-',718,'5,0.431,0',870,868,'431,0.194',870,'528',616,'392',614,'394',614,'389,0.615,0,{krn:{"121',691,'119":-',718,'556',634,'krn:{"119":-',718,'528',',0.431,0,{ic:0.',886,'97',909,'101',691,'97',691,'111',691,'99":-',718,'722',968,886,'101',691,'97',691,'111',691,'99":-',718,'528',614,'528',884,'ic:0.',886,'111',691,'101',691,'97',691,'46',766,'44":-0.',776,'444',614,'5',968,'0278,',660,'124}}],[1',968,'0278}],[0.','5',606,'5,0.668],[0.5,0.668]],cmmi10:[[0.615',815,'139',',krn:{"61":-0.0556,"59":-0.111,"58":-0.111,"127":0.',776,'833',689,'127":0.167}}],[0.','763',815,1011,'krn:{"127":0.0833}}],[0.','694',689,1025,'742',815,'0757,',1029,'831',815,'0812,krn:{"61',909,'59":-0.0556,"58":-0.0556,"127":0.','0556}}],[0.','78',815,'0576,',1029,'583',815,'139',1021,1042,'667',722,1029,'612',815,'11,krn:{"61',909,1041,1042,'772',815,'0502,',1029,'64',968,'0037,','krn:{"127":',718,'566',',0.694,0.194,{ic:0.','0528,',1029,'518',884,'ic:0.0556','}],[0.4! 44',636,'ic:0.0378,krn:{"',1041,1042,'406',634,'krn:{"127":0.0556}}],[0.','438',1071,'0738,',1029,'497',884,'ic:0.0359',',',1084,'469',636,'ic:0.',1011,1029,'354',634,1084,'576',614,'583',606,'603',884,1068,718,'494',968,'0637,krn:{"',1041,'0278}}],[0.','438',1071,'046,',1068,'0.111}}],[0.','57',968,'0359}],[0.','517',884,1029,'571',968,'0359,krn:{"59',909,'58":-0.',1042,'437',968,'113,krn:{"',1041,1114,'54',968,'0359,',1068,718,'596,0.694,0.194,{',1029,'626',884,1084,'651',1071,'0359,',1068,1119,'622',968,1122,'466',634,1029,'591',636,1029,'828',968,1015,'517',884,1029,'363,0.431,0.0972,{ic:0.0799,',1029,'654',884,1068,'0.0833}}],[1',680,'1',680,'1',680,'1',680,'0.278',',0.464,-0.0363],[','0.278',1181,'0.5,0.465,-0.0347],[',1184,'0.5',614,'5',614,'5',614,'5',616,'5',616,'5,0.',951,666,951,666,'431',657,'278,0.106],[',656,657,'778',',0.539,0.0391],[','0.5,0.75,0.25,{krn:{"1',909,'65',909,'77',909,'78',909,'89":0.0556,"90":-0.',1042,'778',1207,1184,'0.531',636,1076,',',1029,! '75',689,'127":','0.','139}}],[0.','759',815,'0502,',1029,'715! ',815,'0 715,krn:{"61',691,1041,776,'828',815,1011,1084,'738',815,'0576,',1029,'643',815,'139',1021,776,'786',722,1029,'831',815,'0812,krn:{"61',909,1041,1042,'44',815,'0785,',1068,1119,'555',815,'0962',1021,'167}}],[0.','849',815,'0715,krn:{"61',909,1041,1042,'681',689,1228,718,'97',815,'109,krn:{"','61',909,1041,776,'803',815,1285,'61',766,'61',691,1041,776,'763',815,1011,1029,'642',815,'139',1021,776,'791,0.683,0.194,{',1029,'759',815,'00773,',1029,'613',815,'0576,krn:{"61',909,1041,776,'584',815,'139,krn:{"61',691,1041,776,'683',815,1285,'59":-0.111,"',1130,'111,"61',909,1228,718,'583',815,'222',',krn:{"59":-0.167,"58":-0.167,"61":-0.111}}],[0.','944',815,'139',1338,'828',815,'0785,krn:{"61',766,'61',691,1041,776,'581',815,'222',1338,'683',815,'0715,krn:{"61',909,1041,776,'389,0.75],[0.389',641,'0.389',641,'1,0.358,-0.142],[',1365,'0.417',636,1068,1119,'529',614,'429',606,'433',634,1084,'52',636,'krn:{"89":0.0556,"90',909,'106":-0.111,"102":-0.167,"',1025,'466',634,1084,'49',1071! ,'108,krn:{"',1041,1272,'477',884,1091,',',1068,718,'576',636,'krn:{"127":-',718,'345,0.66],[0.412,0.66,0.194,{ic:0.0572,krn:{"59',909,1130,1042,'521',636,'ic:0.0315}],[0.298',636,'ic:0.0197,',1029,'878',614,'6',614,'485',634,1084,'503',884,1029,'446',884,1091,',',1029,'451',968,1011,'krn:{"',1041,1042,'469',634,1084,'361,0.615,0,{',1029,'572',634,1068,718,'485',968,'0359,',1068,718,'716',968,'0269,',1029,'572',634,1068,718,'49',884,1091,',',1084,'465',968,'044,',1084,'322',634,1068,718,'384',884,1029,'636',884,1068,1119,'5,0.714,0,{ic:0.154}],[0.278',636,'ic:0.399}]],',1,':[[',655,'0.278,0.444,-0.0556],[',655,1184,655,'0.5,0.444,-0.0556],[',655,655,655,655,655,655,655,'1',641,1485,1485,'0.778',1181,'0.778,0.464,-0.0363','],[0.778,0.636,0.136',1500,1500,1500,1500,1500,'],[0.778',680,'0.778,0.483,-0.0169],[0.778',1207,'0.778',1207,'1',1207,'1',1207,'0.778',1207,'0.778',1207,'1',680,'1',680,'0.5',641,'0.5',641,'1',680,'1',641,'1',641,'0.778',1181,'1',680,'1',680,'0.611',641,'! 0.611',641,'1',680,'1',641,'1',641,'0.778',614,'275,0.556],[1'! ,614,'66 7',1207,'0.667',1207,'0.889',641,'0.889',641,'0',641,'0',680,'0.556',606,'556',606,'667',614,'5',643,'722',606,'722',606,'778',606,'778',606,'611',606,'798',689,'48":0.','194}}],[0.657',815,'0304',',krn:{"48":0.',1230,'527',815,'0583',1590,1230,'771',815,'0278',1590,776,'528',815,'0894',1590,'111}}],[0.','719',815,'0993',1590,1606,'595',',0.683,0.0972,{ic:0.','0593',1590,1606,'845',815,'00965',1590,1606,'545',815,'0738,krn:{"48":',718,'678',1613,'185',1590,1272,'762',815,'0144',1590,1042,'69',689,1586,'139}}],[1.2',689,1586,1230,'82',815,'147',1590,776,'796',815,1599,1590,1606,'696',815,'0822',1590,776,'817,0.683,0.0972,{krn:{"48":',1119,'848',689,1586,776,'606',815,'075',1590,1230,'545',815,'254,krn:{"48":',718,'626',815,'0993',1590,776,'613',815,'0822,krn:{"48":',718,'988',815,'0822',1590,776,'713',815,'146',1590,1230,'668',1613,'0822',1590,776,'725',815,'0794',1590,1230,'667,0.556],[0.',1702,1702,1702,1702,'611',606,'611',606,'444',651,'444',651,'444',651,'444',651,'5',65! 1,'5',651,'389',651,'389',651,'278',651,'5',651,'5',651,'611',651,'5',651,'278',641,'0.833,0.04,0.96],[0.75',582,'833',582,'417',1071,'111}],[0.',1702,'667,0.556',1500,1500,'],[0.444',641,'0.444',641,'0.444',641,'0.611',641,'0.778,0.694,0.13','],[',1758,'],[',1758,'],[',1758,']],',3,':[[0.458',',0.04,1.16,{n:','16}],[0.458',1768,'17}],[0.417',1768,'104}],[0.417',1768,'105','}],[0.472,0.04,1.16,{n:','106',1776,'107',1776,'108',1776,'109}],[0.583',1768,'110}],[0.583',1768,'111',1776,'68',1776,'69}],[0.333',',0,0.6,{delim:{rep:','12}}],[0.556',1792,'13}}],[0.578',1768,'46}],[0.578',1768,'47}],[0.597',',0.04,1.76,{n:','18}],[0.597',1800,'19}],[0.736',',0.04,2.36,{n:','32}],[0.736',1804,'33}],[0.528',1804,'34}],[0.528',1804,'35}],[0.583',1804,'36}],[0.583',1804,'37}],[0.583',1804,'38}],[0.583',1804,'39}],[0.75',1804,'40}],[0.75',1804,'41}],[0.75',1804,'42}],[0.75',1804,'43}],[1.04',1804,'44}],[1.04',1804,'45}],[0.792',',0.04,2.96,{n:','48}],[0.792',1832,'49}],[0.583',1832,'50}],! [0.583',1832,'51}],[0.639',1832,'52}],[0.639',1832,'53}],[0.63! 9',1832, '54}],[0.639',1832,'55}],[0.806',1832,'56}],[0.806',1832,'57}],[0.806',',0.04,2.96],[','0.806',1852,'1.28',1852,'1.28',1852,'0.811',1800,'30}],[0.811',1800,'31}],[0.875',',0.04,1.76,{delim:{top:','48,bot:64,rep:66}}],[0.875',1864,'49,bot:65,rep:67}}],[0.667',1864,'50,bot:52,rep:54}}],[0.667',1864,'51,bot:53,rep:55','}}],[0.667,0.04,1.76,{delim:{bot:','52,rep:54',1872,'53,rep:55','}}],[0.667,0,0.6,{delim:{top:','50,rep:54',1876,'51,rep:55','}}],[0.889,0,0.9,{delim:{top:','56,mid:60,bot:58,rep:62',1880,'57,mid:61,bot:59,rep:62',1880,'56,bot:58,rep:62',1880,'57,bot:59,rep:62','}}],[0.889,0,1.8,{delim:{rep:','63',1888,'119}}],[0.889,0,0.3,{delim:{rep:62',1876,'120,bot:121,rep:63}}],[0.875',1864,'56,bot:59,rep:62}}],[0.875',1864,'57,bot:58,rep:62}}],[0.875',1792,'66}}],[0.875',1792,'67}}],[0.611',1800,'28}],[0.611',1800,'29','}],[0.833,0,1,{n:','71}],[1.11',',0.1,1.5],[','0.472,0,1.11,{ic:0.194,n:','73}],[','0.556,0,2.22,{ic:0.444}],[1.11,0',',1,{n:75}],[1.51,0','.1,1.5],[1.11,0'! ,',1,{n:77}],[1.51,0',1913,',1,{n:79}],[1.51',1908,'1.06,0,1,{n:88}],[0.944,0,1,{n:89}],[',1909,'90',1906,'91',1906,'92',1906,'93',1906,'94',1906,'95}],[1.44',1908,'1.28',1908,1911,1913,1913,1913,1913,'.1,1.5],[0.944,0,1,{n:97}],[1.28',1908,'0.556,0.722,0,{n:','99','}],[1,0.75,0,{n:','100}],[1.44,0.75],[',1941,'102',1943,'103}],[1.44,0.75],[0.472',1800,'20}],[0.472',1800,'21}],[0.528',1800,'22}],[0.528',1800,'23}],[0.528',1800,'24}],[0.528',1800,'25}],[0.667',1800,'26}],[0.667',1800,'27}],[1',1768,'113}],[1',1800,'114}],[1',1804,'115}],[1',1832,'116}],[1.06,0,1.8,{delim:{top:118,bot:116,rep:117}}],[1.06,0,0.6],[1.06,0.04,0.56],'], - ['[0.778',',0,0.6,{delim:{','top:126,','bot:127,rep:119','}}],[0.','667',1,'top:120,rep:63',4,'667',1,'bot:121,rep:63',4,'45,0.12],[0.',13,13,13,'778',1,2,'rep:119',4,'778',1,3,'}}]],cmti10:[[0.627',',0.683,0,{ic:0.','133}],[0.818,0.683],[0.767',26,'094}],[0.','692,0.683],[0.664',26,'153}],[0.743',26,'164}],[0.','716',26,'12}],[0.','767',26,'111}],[0.716',26,'0599}],[0.767',26,'111}],[0.716',26,'103}],[0.','613',',0.694',',0.194,{ic:0.','212,krn:{"39":0.104,"63":0.104,"33":0.104,"41":0.104,"93":0.104},lig:{"105":','14,"108":15',4,'562',48,49,46,'588',48,49,46,'882',48,49,46,'894',48,49,46,'307',',0.431,0,{ic:0.','0767}],[0.','332,0.431',49,'0374}],[0.511',',0.694],[0.','511',',0.694,0,{ic:0.','0969','}],[0.511,0.','628',',0,{ic:0.','083}],[0.511',77,'108',79,'562',81,46,'831',75,'46,0,0.17],[0.537',48,49,'105}],[0.','716',70,'0751','}],[0.716',70,97,79,'528,0.0972,{ic:0.0919}],[0.883',26,37,'985',26,37,'767,0.732,0.0486,{ic:0.',29,'256,0.431,0,{krn:{"108":-0.256,"76":-0.3! 21',4,'307',77,'124,lig:{"96":','60',4,'514',77,'0696}],[0.818',48,49,'0662}],[0.769',75,'818',',0.75,0.0556',',{ic:0.136}],[0.','767',77,'0969}],[0.307',77,'124',',krn:{"','63":0.102,"33":0.102},lig:{"39":34',4,'409',',0.75,0.25,{ic:0.','162}],[0.409',136,'0369',79,'75',81,'149}],[0.767,0.562,0.0567,{ic:0.0369','}],[0.307,0.','106',',0.194],[0.','358',70,'0283,lig:{"45":123',4,'307,0.106],[0.511',136,'162',79,'644,0',',{ic:0.136}],[0.511,0.644,0',156,156,156,'.194',156,156,156,160,156,156,126,'307',70,'0582',144,'431',49,'0582',144,'5',49,'0756}],[0.767,0.367,-0.133,{ic:0.0662',79,'5',146,'511',77,'122,lig:{"96":62',4,'767',77,'096}],[0.743,0.683,0,{','krn:{"110":-0.0256,"108":-0.0256,"114":-0.0256,"117":-0.0256,"109":-0.0256,"116":-0.0256,"105":-0.0256,"67":-0.0256,"79":-0.0256,"71":-0.0256,"104":-0.0256,"98":-0.0256,"85":-0.0256,"107":-0.0256,"118":-0.0256,"119":-0.0256,"81":-','0.0256,"84','":-0.0767,"','89',191,'86','":-0.102,"','87',195,'101":-0.0511,"97":-0.0511,"111! ":-0.0511,"100":-0.0511,"99":-0.0511,"103":-0.0511,"113":-0.05! 11}}],[0 .','704',26,46,'716',26,'145}],[0.','755',26,'094',132,'88','":-0.0256,"','87',210,'65',210,'86',210,'89','":-0.0256',4,'678',26,37,'653',26,'133',132,'111',191,'101',191,'117','":-0.0767,"114":-0.0767,"97":-0.0767,"','65',195,'79":-0.0256,"67":-0.0256,"71":-0.0256,"81":-0.0256}}],[0.','774',26,'0872}],[0.743',26,34,'386',26,'158}],[0.525',26,'14}],[0.769',26,'145',132,235,'627,0.683,0,{krn:{"84',191,'89',191,'86',195,'87',195,198,'897',26,34,'743',26,34,'767',26,'094',132,'88',210,'87',210,'65',210,'86',210,'89',218,4,'678',26,'103',132,'65":-0.0767}}],[0.','767,0.683',49,29,'729',26,'0387,',189,'0.0256,"84',191,'89',191,'86',195,'87',195,198,'562',26,37,'716',26,'133',132,'121',191,'101',191,'111',232,'117',191,284,'743',26,34,'743',26,'184',132,'111',191,'101',191,'117',232,'65',195,235,'999',26,'184',132,284,'743',26,'158',132,235,'743',26,'194',132,'101',191,'111',232,'117',191,284,'613',26,204,'307',136,'188}],[0.514',77,'169}],[0.307',136,94,'511',77,'0665',144,'668',! 81,'118}],[0.307',77,114,'92',4,'511',70,71,'46',77,'0631',132,198,'46',70,'0565',132,198,'511',77,'103',',krn:{"108":0.0511}}],[0.','46',70,97,132,198,'307',48,49,50,'12,"102":11,"108":13}}],[0.','46,0.431',49,'0885}],[0.','511',77,71,'307,0.655',81,'102',144,'655',49,204,'46',77,'108}],[0.','256',77,'103',391,'818',70,71,'562',70,'0767',132,'39":-0.102',4,'511',70,'0631',132,198,'511,0.431',49,'0631',132,198,'46,0.431',49,404,'422',70,'108',132,198,'409',70,'0821}],[0.332,0.615',81,'0949}],[0.537',70,71,'46',70,417,'664',70,'108',391,'464',70,37,'486,0.431',49,404,'409',70,'123}],[0.511',70,'0921',',lig:{"45":124}}],[1.','02',70,'0921}],[0.511',77,'122',79,'668',81,'116',79,'668',81,'105}]],cmbx10:[[0.692',',0.686],[0.','958',488,'894',488,'806',488,'767',488,'9',488,'831',488,'894',488,'831',488,'894',488,'831',488,'671',77,'109,krn:{"39":0.109,"63":0.109,"33":0.109,"41":0.109,"93":0.109},lig:{"105":','14,"108":15',4,'639',75,'639',75,'958',75,'958',75,'319',',0.444],[0.! ','351,0.444',146,'575',75,'575',75,'575,0.','632],[0.575',75,! 530,'596 ],[0.869',75,'511,0,0.17],[0.597',75,'831',523,'894',523,530,'542,0.0972],[1.04,0.686],[1.17',488,'894,0.735,0.0486],[0.319',',0.444,0,{krn:{"','108":-0.319,"76":-0.378',4,'35',',0.694,0,{lig:{"96":','60',4,'603',75,'958',48,146,'575',125,'],[0.958',125,'],[0.894',75,'319',',0.694,0,{krn:{"','63":0.128,"33":0.128},lig:{"39":34',4,'447',',0.75,0.25],[0.','447',569,530,'75],[0.894,0.633,0.133],[0.','319,0.156',146,'383,0.444,0,{lig:{"45":123',4,574,'],[0.575',569,530,'644],[','0.575,0.644],[0.575,0.644],[',583,583,583,'0.',530,'644],[0.319',523,'319,0.444',146,'35,0.5',146,'894,0.391,-0.109],[0.543,0.5',146,'543',550,'62',4,'894',75,'869',',0.686,0,{krn:{"','116','":-0.0319,"','67',606,'79',606,'71',606,'85',606,'81',606,'84":-0.0958,"89":-0.0958,"86":-0.128,"87":-0.128}}],[','0.818',488,'831',488,'882',604,'88',606,'87',606,'65',606,'86',606,'89','":-0.0319}}],[0.','756',488,'724,0.686,0,{','krn:{"111":-0.0958,"101":-0.0958,"117":-0.0958,"114":-0.0958,"97":-0.0958,"65":-0.128! ,"79":-0.0319,"67":-0.0319,"71":-0.0319,"81":-0.0319}}],[','0.904',488,'9',488,'436',604,'73":0.0319',4,'594',488,'901',604,'79',606,'67',606,'71',606,'81',633,'692',604,617,'1.09',488,'9',488,'864',604,'88',606,'87',606,'65',606,'86',606,'89',633,'786',604,'65":-0.0958,"111',606,'101',606,'97',606,'46":-0.0958,"44":-0.0958}}],[0.','864,0.686',146,'862',604,'116',606,'67',606,'79',606,'71',606,'85',606,'81',606,617,'0.639',488,'8',604,'121',606,'101":-0.0958,"111":-0.0958,"114":-0.0958,"97":-0.0958,"65":-0.0958,"117":-0.0958}}],[0.','885',488,'869,0.686',81,'016,',637,'1.19,0.686',81,'016,',637,'0.869',604,'79',606,'67',606,'71',606,'81',633,'869,0.686',81,'0287',132,709,'703',488,'319',569,'603',75,'319',569,'575',75,'319',75,'319',550,'92',4,'559',546,'118',606,'106":0.0639,"121',606,'119',633,'639',48,',0',',{krn:{"101":0.0319,"111":0.0319,"120":-0.0319,"100":0.0319,"99":0.0319,"113":0.0319,"118":-0.0319,"106":0.0639,"121":-0.0319,"119":-0.0319}}],[0.','511',546,'104',60! 6,'107',633,'639',75,'527',523,'351',77,511,401,530,'444',49,'! 016',132 ,'106":0.0319',4,'639',565,'116',606,'117',606,'98',606,'121',606,'118',606,'119',633,'319',75,'351',48,146,'607',565,'97":-0.0639,"101',606,'97',606,'111',606,'99',633,'319',75,'958',546,'116',606,'117',606,'98',606,'121',606,'118',606,'119',633,'639',546,'116',606,'117',606,'98',606,'121',606,'118',606,'119',633,530,'444,0',762,'639,0.444,0',160,762,'607,0.444',146,'474',523,'454',523,'447,0.635,0,{krn:{"121',606,'119',633,'639',546,'119',633,849,81,'016',132,'97":-0.0639,"101',606,'97',606,'111',606,'99',633,'831,0.444',81,'016',132,'101',606,'97',606,'111',606,'99',633,'607',523,849,49,'016',132,'111',606,'101',606,'97',606,685,'511',523,530,'444',81,'0319',474,'15,0.444',81,'0319}],[0.575',75,'575',75,'575',48,']]};','jsMath.Img','={fonts:[50,60,70,85,100,120,144,173,207,249,298,358,430],w:{"50":6.9,"60":8.3,"70":9.7,"85":11.8,"100":13.9,"120":16.7,"144":20,"173":24,"207":28.8,"249":34.6,"298":41.4,"358":49.8,"430":59.8},best:4,update:{},factor:1,loaded:0,SetFont',':fun! ction(','B){for(var A in B){if(!','this.update[A',']){',920,']=[]}',920,']=',920,'].concat(B[A])}},AddFont',918,'A,B){if(!',916,'[A]){',916,'[A]={}}jsMath.Add(',916,'[A],B)},UpdateFonts',':function(){','var D=this.update;','if(!this.loaded){','return }for(var A in D){for(var B=0;B<D[A].length;B++){var C=D[A][B];if(C=="all"){for(C in ','jsMath.TeX[','A]){',940,'A][C].img','={}}}else{',940,943,'={}}}}this.update={}},BestSize',936,'var B=jsMath.em*this.factor;var A=','this.w[this.fonts[','0]];for(var C=1;C<this.fonts.length;C++){if(B<(',950,'C]]+2*A)/3){return C-1}A=',950,'C]]}return C-1},Scale',936,938,'return }this.best=this.BestSize();this.em=',916,'.w[this.fonts[this.best]];','this.scale','=(jsMath.em/this.em);','if(Math.abs(',961,'-1)<0.12){',961,'=1}},URL',918,'A,B,E){var D=(','jsMath.Controls.cookie.','alpha)?"/alpha/":"/plain/";','if(E==null','){E="def.js"}else{E="char"+E+".png"}if(B!=""){B+="/"}','return this.','root+A+D+B+E},LoadFont',918,'A){',938,'this.Init()}jsMat! h.Setup.Script(this.URL(A,""))},Init',936,'if(',970,'print||',! 970,'sta yhires','){',970,'print=',970,985,';this.factor*=3;if(!','jsMath.Controls.','isLocalCookie||!jsMath.Global.isLocal){',992,'SetCookie(0)}if(','jsMath.Browser.','alphaPrintBug){',970,'alpha=0}}var B="0123456789ABCDEF";this.HexCode=[];for(var C=0;C<128;C++){var D=Math.floor(C/16);var A=C-16*D;this.HexCode[C]=B.charAt(D)+B.charAt(A)}this.loaded=1}};jsMath.HTML={Em',918,'A){var C=','5;if(A<0){C++}',963,'A)<0.000001){A=0}var B=String(A);B=B.replace(/(\\.\\d\\d\\d).+/,"$1");return B+"em"},Spacer',918,'A){if(A==0){return""}return ',996,'msieSpaceFix+"<','span class=\\"spacer\\" style=\\"margin-','left:"+this.Em(','A)+"\\"></span>"},Blank',918,'B,E,G,F){var A="";var D="";if(F){D+="border-',1010,'B)+" solid;";if(',996,'widthAddsBorder){B=0}}if(B==0){if(',996,'blankWidthBug){D+="width:1px;";A="<',1009,'right:-1px\\"></span>"}}else{D+="width:"+this.Em(B)+";"}if(G==null){G=0}if(E){var C=this.Em(E+G);if(F&&E*jsMath.em<1.5){C="1px";E=1/jsMath.em}D+="height:"+C+";"}if(',996,'mozInlineBlockB! ug){G=-E}if(',996,'msieBorderBug&&!F){G-=jsMath.d}if(G){D+="','vertical-align:"+','this.Em(-G)}return A+"<span class=\\"blank\\" ','style=\\""+','D+"\\"></span>"},Rule',918,'A,B){if(B==null){B','=jsMath.TeX.default_rule_thickness}',974,'Blank(A,B,0,1)},Class',918,'A,B){return"<span class=\\""+A+"\\">"+B+"</span>"},Place',918,'B,A,D','){if(Math.abs(A)<0.0001){A=0}if(Math.abs(','D)<0.0001){D=0}if(A||D){var C','="<span style=\\"position',': relative',';";if(A){C+=" margin-',1010,'A)+";"}if(D){C+=" ','top:"+this.Em','(-D)+";"}B=C+"\\">"+B','+"</span>"}','return B},','PlaceSeparateSkips',918,'B,A,C',1039,'C)<0.0001){C=0}','if(C){B',1041,1042,'; ',1046,'(-C)+";"+"\\">"+B',1048,'if(A){B=this.Spacer(A)+B}',1049,'PlaceAbsolute',918,'B,A,C',1039,1054,'B',1041,':absolute','; ',1010,'A)+"; "+"',1046,'(C)+";\\">"+B+" </span>";',1049,'Absolute',918,'C,A,D,E,F,B){if(F!="none"){',963,'F)<0.0001){F=0}C',1041,1071,'; "+"top:"+','jsMath.HTML.','Em(F)+"; left:0em;\\">"+C+" "+"</span>! "}if(E=="none"){E=0}C+=this.Blank(A,D-E,E);if(',996,'msieAbsol! uteBug){ C',1041,':relative',';\\">"+C',1048,'if(',996,'spanHeightVaries){','C',1041,1091,';"+" width:"+',1086,'Em(A)+";"+" height:"+',1086,'Em(B)+";"+',996,'msieInlineBlockFix+"\\">"+C',1048,'else{C',1041,1091,'\\">"+C',1048,'return C}};','jsMath.Box','=function(C,E,A,B,D){if(D==null){D=jsMath.d}this.type="typeset";this.w=A;this.h=B;this.d=D;this.bh=B;this.bd=D;this.x=0;this.y=0;this.html=E;this.format=C};jsMath.Add(',1114,',{defaultH:0,Null',936,'return new ',1114,'("null","",0,0,0)},Text',918,'J,I,A,K,H,G){var E=','jsMath.Typeset.AddClass(','I,J);E=','jsMath.Typeset.','AddStyle(','A,K,E);var B','=jsMath.EmBoxFor(','E);var C=',1126,'TeX(A,K);var F=((I=="cmsy10"||I=="cmex10")?B.h-C.h:C.d*B.h/C.hd);var D=new ',1114,'("text",J,B.w,B.h-F,F);D.style=A;D.size=K;D.tclass=I;if(G!=null){D.d=G*C.scale}else{D.d=0}if(H==null||H==1){D.h=0.9*C.M_height}else{D.h=1.1*C.x_height+C.scale*H}return D},TeX',918,'H,A,E,B){var I=',940,'A][H];','if(I.d==null){I.d=0}','if(I.h==null){I.h=','0}if(I.img!=null! &&I.c!=""){this.TeXIMG(A,H,',1126,'StyleSize(E,B))}var G=',1126,'TeX(E,B).scale;var D=I.h+',940,'A].dh;var F=new ',1114,'("text",I.c,I.w*G,D*G,I.d*G);F.style=E;F.size=B;if(I.tclass){F.tclass=I.tclass;if(I.img){F.bh=I.img.bh;F.bd=I.img.bd}else{F.bh=G*jsMath.h;F.bd=G*jsMath.d}}else{F.tclass=A;F.bh=G*',940,'A].h;F.bd=G*',940,'A].d;if(',996,'msieFontBug&&','F','.html.match(/&#/)){','F','.html+="<span style=\\"display:none\\">x</span','>"}}return F},TeXfallback',918,'A,D,B,L){var J=',940,'D][A];if(!J.tclass){J.tclass=D}if(J.img!=null){',974,'TeXnonfallback(A,D,B,L)}if(J.h!=null&&J.a==null){J.a=J.h-1.1*jsMath.TeX.x_height}var K=J.a;var I=J.d;var H=this.Text(J.c,J.tclass,B,L,K,I);var E=',1126,'TeX(B,L).scale;if(J.bh!=null){H.bh=J.bh*E;H.bd=J.bd*E}else{var G=H.bd+H.bh;var F=',1124,'H.tclass,H.html);F=',1126,1127,'B,L,F);H.bd',1129,'F+',1086,'Blank(1,G)).h-G;H.bh=G-H.bd;if(E==1){J.bh=H.bh;J.bd=H.bd}}if(jsMath.',1155,'H',1157,'H',1159,'>"}return H},TeXIMG',918,'E,A,R){var M=',940,'E]! [A];if(M.img.size!=null&&M.img.size==R&&M.img.best!=null&&M.im! g.best== ','jsMath.Img.best','){return }var F=(',916,'.scale!=1);var B=',1188,'+R-4;if(B<0){B=0;F=1','}else{if(','B>=','jsMath.Img.fonts','.length){','B=',1196,'.length-1',';F=1}}var Q=',916,'[',1196,'[B]];var I=Q[E][A];var G=1/',916,'.w[',1196,'[B]];if(B!=',1188,'+R-4){if(M.w!=null){G=M.w/I[0]}else{G*=',1196,'[R]/',1196,'[4]*',1196,'[',1188,']/',1196,'[B]}}var N=I[0]*G;var J=I[1]*G;var L=-I[2]*G;var O;var H=(M.w==null||Math.abs(M.w-N)<0.01)?"":" margin-right:"+',1086,'Em(M.w-N)+";";var D="";A=',916,'.HexCode[A];if(!F&&!',970,'scaleImg){if(2*N<J||(',996,'msieAlphaBug&&',970,'alpha)){D="height',':"+(I[1]*',996,'imgScale',')+"px;"}D+=" width:"+(I[0]*',996,1234,')+"px;";O=-I[2]+"px"}else{if(2*N<J||(',996,'msieAlphaBug&&',970,1231,':"+',1086,'Em(J*',996,1234,')+";"}D+=" width:"+',1086,'Em(N*',996,1234,')+";";O=',1086,'Em(L)}var P=(Math.abs(L)<0.01&&!',996,'valignBug)?"":" ',1026,'O+";";var K=',916,'.URL(E,',1196,'[B],A);if(',996,'msieAlphaBug&&',970,'alpha){','M.c="<img src=\\""+','jsMat! h.blank+"\\" "+"',1028,996,'msieCenterBugFix+D+P+H','+" filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="+"\'"+K+"\', sizingMethod=\'scale\'"+");\\" />"}else{',1268,'K+"\\" ',1028,996,1272,'+"\\" />"}M.tclass="normal";M.img.bh=J+L;M.img.bd=-L;M.img.size=R;M.img.best=',1188,'},Space',918,'A){return ','new jsMath.Box("html",',1086,'Spacer(A),A,0,0)},Rule',918,'A,C){if(C','==null){C',1032,'var B=',1086,'Rule(A,C);return ',1284,'B,A,C,0)},GetChar',918,'B,',1001,940,'A][B];','if(C.img!=null){this.TeXIMG(A,B',',4)}if(C.tclass',1289,'.tclass=A}if(!C.computedW){C.w',1129,1124,'C.tclass,C.c)).w',';if(C.h',1289,'.h=',1114,'.defaultH}if(C.d',1289,'.d=0}C.computedW=1}return C},DelimBestFit',918,'E,J,D,G){if(J==0&&D==0){return null}var I;var F;D','=jsMath.TeX.fam[','D];var A=(G.charAt(1)=="S");var B=(G.charAt(0)=="S");while(J!=null){I=',940,'D][J];',1140,1114,'.defaultH}',1139,'F=I.h+I.d;if(I.delim){return[J,D,"",E]}if(A&&0.5*F>=E','){return[J,D,"','SS",0.5*F]}if(B&&0.7*F>! =E',1326,'S",0.7*F]}if(F>=E||I.n==null',1326,'T",F]}J=I.n}retu! rn null} ,DelimExtendRelative',918,'I,T,O,V,D){var P=',940,'O][T];var N','=this.GetChar(','P.delim.','top?P','.delim.top:','P.delim.rep,O);var ','A',1336,1340,'M',1336,1337,'bot?P','.delim.bot:',1340,'E=',1124,'A.tclass,A.c);','var J=A.w;var S=A.h+A.d;var F;var B;var K;var L;var R;var Q;if(',1337,'mid){var U',1336,1337,'mid,O);Q','=Math.ceil((I-(','N.h+N.d)-(','U.h+U.d)-(M.h+M.d','))/(2*(A.h+A.d',')));I=2*','Q*(A.h+A.d)+(N.h+N.d)+(','U.h+U.d)+(M.h+M.d);if(D){F=0}else{F=I/2+V}B=F;K=',1086,'Place(',1124,'N.tclass,N.c),0,F-N.h',')+',1086,1367,1124,'M.tclass,M.c),-(','N.w+M.w)/2,F-(I-M.d))+',1086,1367,1124,'U.tclass,U.c),-(M.w+U.w)/2,F-(I+U.h-U.d)/2);L=(J-U','.w)/2;if(Math.abs(L)<0.0001){L=0}if(L){K+=jsMath.HTML.Spacer(L)}F-=N.h+N.d+A.h;for(R=0;R<Q;R++){K+=jsMath.HTML.Place(E,-J,F-R*S)}','F-=I/2-A.h/2;for(R=0;R<Q;R++){K+=',1086,1367,'E,-J,F-R*S)}}else{Q',1359,1360,'M.h+M.d))/(A.h+A.d));if(N.h+N.d<0.9*(A.h+A.d)){Q=... [truncated message content] |