You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(16) |
Nov
(10) |
Dec
(4) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(34) |
Feb
(12) |
Mar
(21) |
Apr
|
May
(5) |
Jun
(13) |
Jul
(50) |
Aug
(62) |
Sep
(72) |
Oct
(17) |
Nov
(16) |
Dec
(19) |
2006 |
Jan
(26) |
Feb
(9) |
Mar
|
Apr
(8) |
May
(5) |
Jun
(7) |
Jul
(21) |
Aug
(33) |
Sep
(17) |
Oct
(4) |
Nov
(9) |
Dec
|
2007 |
Jan
|
Feb
(4) |
Mar
|
Apr
|
May
(6) |
Jun
(16) |
Jul
(8) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(2) |
Dec
(2) |
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(4) |
Jul
(11) |
Aug
(6) |
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(4) |
Nov
|
Dec
|
2014 |
Jan
(2) |
Feb
(4) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2016 |
Jan
(4) |
Feb
(4) |
Mar
(3) |
Apr
|
May
(1) |
Jun
(1) |
Jul
(1) |
Aug
(2) |
Sep
(1) |
Oct
(1) |
Nov
(1) |
Dec
|
2017 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
From: P G. L. <gl...@um...> - 2005-10-26 13:04:22
|
Hi all, Here is an issue that has come up in my continued testing of the Gateway module for WeBWorK. Sets currently have a 'published' characteristic, which determines whether (a) students can see the set, and (b) they are allowed to work the set. The distinction is significant because of WeBWorK2's ability to directly go to a set using a URL. In playing with Gateway testing, it occurred to me that I'd rather not have proctored gateway sets (which students have to go to a lab to take) show up in their problem set list. (When they go to the lab, they start from a page that points them directly to the proctored test.) One way of doing this is to make the set unpublished, but then, according to rule (b) above, the students should then also not be able to take it. So I'm curious whether you have an opinion about this: should proctored gateway tests by default be invisible on the problem set list page? Should the gateway test module ignore part (b) of the unpublished description? Should I give up on this and just have the proctored tests show up in the set list? Thanks, Gavin p.s. FYI: currently, the set list for gateway tests appears something like the following: Take new DerivativeGW test open, due 11/16/2005 at 11:59pm EST DerivativeGW (test1) 1/7 Sun Oct 23 21:30:28 2005 DerivativeGW (test2) 0/7 Mon Oct 24 08:15:49 2005 ProctoredDerivGW (test1) 0/7 Mon Oct 24 08:22:38 2005 ProctoredDerivGW (test2) 0/7 Mon Oct 24 08:23:33 2005 The first is a link to take a practice test; the next two are practice tests that have been taken and can be reviewed (and checked, but not resubmitted); the last two are proctored tests that have been taken and can be reviewed (and checked, but not resubmitted). The link that's omitted because the set is unpublished is the "Take new ProctoredDerivGW test". -- P. Gavin LaRose, Ph.D. Program Manager (Instructional Tech.) Math Dept., University of Michigan gl...@um... "There's no use in trying," [Alice] 734.764.6454 said. "One Can't believe impossible http://www.math.lsa.umich.edu/~glarose/ things." "I daresay you haven't had much practice," said the Queen. - Lewis Carrol |
From: Michael G. <ga...@ma...> - 2005-10-26 03:45:06
|
A suggestion from Imre Tuba about safety backups for sets. I'm not sure exactly what happened but the result was the loss of the paths to several files while trying to change the number of answers allowed. We had something like this in WW1.9 since backups of set definition files were automatically saved. Any thoughts on how to implement this? In particular I worry that too frequent automatic backups run the risk of overwriting a good backup with a succession of errors. Thoughts? Take care, Mike Begin forwarded message: > From: Imre Tuba <it...@mo...> > Date: October 25, 2005 11:31:08 PM EDT (CA) > To: Michael Gage <ga...@ma...> > Subject: Re: Corrupted homework set > > > Hi Mike, > > Thanks for the quick help. The log file you sent me must be for my > other class (Math 2111), but I believe I managed to recover the > problems partly from memory, partly based on the answer log. > > I understand that adding an undo feature will take quite some work. > But here is a suggestion that should be easy to implement. Webwork > could just automatically save a backup copy, or several backup > copies of a homework set that is changed in the course directory. > Then it would be quite easy to recover the last version. If you > want to be a little fancier, you can let the user configure whether > they want backups to be saved. > -- > Imre > "Only dead fish swim with the stream." |
From: Sam H. <sh...@ma...> - 2005-10-24 03:58:49
|
On Oct 23, 2005, at 19:44, John Jones wrote: > Making $ce global seems reasonable to me. How would it affect code > which wants to create special special course environments? The > only example I can think of off hand is the Config module, which > produces several. I don't think it'll be a problem, as long as they don't use the variable name "$CE" (which they don't). -sam > Sam Hathaway wrote: > > >> Hi Guys, >> >> I often find I'd like to use values from the course environment >> from places other than content generator classes (where they're >> available via $self->r->ce). For example, the date parsing >> functions in Utils.pm need the timezone, the database record >> classes could benefit from having access to default values, and >> so on. >> >> The current solution seems to be to either pass the entire $ce >> object into the function in question, or grab only the needed >> values from $ce and pass those in. It's somewhat of a hassle in >> the common case, and a big hassle in some cases. >> >> Examples: >> >> * I'd like to add methods to the DB record classes to return >> human- readable versions of database values. To format date >> strings, I need a timezone. So a simple call like >> $GlobalSet->pretty_print; >> becomes >> $GlobalSet->pretty_print($timezone); >> >> * This is also the reason why I put the new status mangling >> functions in CourseEnvironment itself instead of in a database >> class. From CourseEnvironment.pm: >> >> >>> There is a set of operations that require certain data from the >>> course >>> environment. Most of these are un Utils.pm. I've been forced to >>> pass $ce into >>> them, so that they can get their data out. But some things are >>> so intrinsically >>> linked to the course environment that they might as well be >>> methods in this >>> class. >>> >> >> >> * The Utils::CourseManagement functions need $ce values. >> >> * Classes like HTML::ScrollingRecordList and Utils::SortRecords/ >> FormatRecords could benefit from having access to settings in $ce >> -- one could customize the display of lists, add new sort methods >> and format strings, etc. >> >> * I also just noticed the parseDateTime and formatDateTime >> wrappers in ContentGenerator.pm that serve to work around this >> problem by grabbing the timezone from $ce and passing it to the >> real functions in Utils.pm. >> >> >> >> I'm considering making $ce a dynamically scoped variable with a >> line like >> local $CE = $ce; >> in WeBWorK.pm. This would make $CE available from any code called >> by WeBWorK.pm. It would make global.conf function much more like >> Global.pm did in the WW1 days -- you could access it from >> anywhere, and rely on its presence. >> >> The main objection I see is that it would make it harder to pull >> pieces of WW code out and use them in places where a course >> environment is not available. However, the current practice of >> passing $ce in to many functions has the same effect. >> Furthermore, CourseEnvironment.pm itself is failry portable. We >> use it in several command-line scripts without inconvenience. >> >> I'm tempted to make the entire WeBWorK::Request object >> dynamically scoped -- that would give us access to $ce, $db, >> $authz, etc. from anywhere. However, this would be much worse in >> terms of modularity, since we'd also have access to $r->param() >> from anywhere, and I fear that the temptation to check and modify >> params from places that should be request-independent would be >> too great and would lead to spaghetti code. >> >> I don't take a change like this lightly, and I'd like your input >> on possible problems with this approach as well as alternate >> solutions. >> -sam >> > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by the JBoss Inc. > Get Certified Today * Register for a JBoss Training Course > Free Certification Exam for All Training Attendees Through End of 2005 > Visit http://www.jboss.com/services/certification for more information > _______________________________________________ > OpenWeBWorK-Devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/openwebwork-devel > |
From: John J. <jj...@as...> - 2005-10-23 23:44:07
|
Making $ce global seems reasonable to me. How would it affect code which wants to create special special course environments? The only example I can think of off hand is the Config module, which produces several. John Sam Hathaway wrote: > Hi Guys, > > I often find I'd like to use values from the course environment from > places other than content generator classes (where they're available > via $self->r->ce). For example, the date parsing functions in > Utils.pm need the timezone, the database record classes could benefit > from having access to default values, and so on. > > The current solution seems to be to either pass the entire $ce object > into the function in question, or grab only the needed values from > $ce and pass those in. It's somewhat of a hassle in the common case, > and a big hassle in some cases. > > Examples: > > * I'd like to add methods to the DB record classes to return human- > readable versions of database values. To format date strings, I need > a timezone. So a simple call like > $GlobalSet->pretty_print; > becomes > $GlobalSet->pretty_print($timezone); > > * This is also the reason why I put the new status mangling functions > in CourseEnvironment itself instead of in a database class. From > CourseEnvironment.pm: > >> There is a set of operations that require certain data from the course >> environment. Most of these are un Utils.pm. I've been forced to pass >> $ce into >> them, so that they can get their data out. But some things are so >> intrinsically >> linked to the course environment that they might as well be methods >> in this >> class. > > > * The Utils::CourseManagement functions need $ce values. > > * Classes like HTML::ScrollingRecordList and Utils::SortRecords/ > FormatRecords could benefit from having access to settings in $ce -- > one could customize the display of lists, add new sort methods and > format strings, etc. > > * I also just noticed the parseDateTime and formatDateTime wrappers > in ContentGenerator.pm that serve to work around this problem by > grabbing the timezone from $ce and passing it to the real functions > in Utils.pm. > > > > I'm considering making $ce a dynamically scoped variable with a line > like > local $CE = $ce; > in WeBWorK.pm. This would make $CE available from any code called by > WeBWorK.pm. It would make global.conf function much more like > Global.pm did in the WW1 days -- you could access it from anywhere, > and rely on its presence. > > The main objection I see is that it would make it harder to pull > pieces of WW code out and use them in places where a course > environment is not available. However, the current practice of > passing $ce in to many functions has the same effect. Furthermore, > CourseEnvironment.pm itself is failry portable. We use it in several > command-line scripts without inconvenience. > > I'm tempted to make the entire WeBWorK::Request object dynamically > scoped -- that would give us access to $ce, $db, $authz, etc. from > anywhere. However, this would be much worse in terms of modularity, > since we'd also have access to $r->param() from anywhere, and I fear > that the temptation to check and modify params from places that > should be request-independent would be too great and would lead to > spaghetti code. > > I don't take a change like this lightly, and I'd like your input on > possible problems with this approach as well as alternate solutions. > -sam |
From: Davide P.C. <dp...@un...> - 2005-10-20 13:24:56
|
> This is great. Last week I had a problem I was updating, considered > using Multipart, but wanted a pop-up menu as one of the parts. Sorry it came too late. > I don't know if this is documented yet, but could we document an > example of using Mulitpart where computing the result is basically an > AND of cmp methods for the constituant parts of the MuliPart? This is off the top of my head (read "untested"), but it should work: $mp->cmp(checker=>sub { my ($correct,$student) = @_; foreach my $i (0..scalar(@{$correct})-1) { return 0 if $correct->[$i] != $student->[$i]; } return 1; }); |
From: John J. <jj...@as...> - 2005-10-20 02:47:10
|
dpvc via activitymail wrote: >Log Message: >----------- >A new parser object that handles popup menus. Mainly this is so that >you can use them with the MultiPart object, which requires all the >objects to be Value objects. See the comments in the file for >documentation and examples. > > This is great. Last week I had a problem I was updating, considered using Multipart, but wanted a pop-up menu as one of the parts. I don't know if this is documented yet, but could we document an example of using Mulitpart where computing the result is basically an AND of cmp methods for the constituant parts of the MuliPart? John >Added Files: >----------- > pg/macros: > parserPopUp.pl > >Revision Data >------------- >--- /dev/null >+++ macros/parserPopUp.pl >@@ -0,0 +1,70 @@ >+loadMacros('Parser.pl','contextString.pl'); >+ >+Context("Numeric"); >+ >+sub _parserPopUp_init {}; # don't reload this file >+ >+#################################################################### >+# >+# 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). >+# >+ >+sub PopUp {parserPopUp->new(@_)} >+ >+# >+# The package that implements pop-up menus >+# >+package parserPopUp; >+our @ISA = qw(Value::String); >+ >+sub new { >+ my $self = shift; my $class = ref($self) || $self; >+ my $choices = shift; my $value = shift; >+ Value::Error("A PopUp's first argument should be a list of menu items") >+ unless ref($choices) eq 'ARRAY'; >+ Value::Error("A PopUp's second argument should be the correct menu choice") >+ unless defined($value) && $value ne ""; >+ my $oldContext = main::Context(); >+ my $context = $main::context{String}->copy; >+ main::Context($context); >+ $context->strings->add(map {$_=>{}} @{$choices}); >+ my $self = bless Value::String->new($value), $class; >+ $self->{isValue} = 1; $self->{choices} = $choices; >+ $self->{context} = $context; >+ main::Context($oldContext); >+ return $self; >+} >+ >+sub menu { >+ my $self = shift; >+ main::pop_up_list($self->{choices}); >+} >+ >+sub ans_rule {shift->menu(@_)} >+ >+1; > > >------------------------------------------------------- >This SF.Net email is sponsored by: >Power Architecture Resource Center: Free content, downloads, discussions, >and more. http://solutions.newsforge.com/ibmarch.tmpl >_______________________________________________ >Openwebwork-cvs mailing list >Ope...@li... >https://lists.sourceforge.net/lists/listinfo/openwebwork-cvs > > |
From: Michael G. <ga...@ma...> - 2005-10-19 17:29:35
|
here are some suggestions from Imre Tuba about simplifying the reporting of bugs in problems. Take care, mike Begin forwarded message: > From: Imre Tuba <it...@mo...> > Date: October 19, 2005 1:06:56 PM EDT > To: Michael Gage <ga...@ma...> > Subject: Re: Fwd: UMM_math2111_tuba --things should be fixed now > > >> Thanks for the info on isolating the problem. We have it fixed >> for now. >> The change we made in the CSS file was supposed to reduce the >> number of problems listed in the left margin, once that list >> got big. Apparently some browsers can't handle that CSS code. >> We'll try something else. >> > > Thanks. Also thanks for simplifying the procedure of replacing > broken library problems with corrected local copies. > > Here is another suggestion along these lines. Bugs in problems are > typically discovered by students. When a bug is discovered I > usually have to > > 1. Investigate the problem and see if I can fix it. I usually can. > > 2. Fix the problem, make a local copy of the file, and replace the > broken problem in the homework set with the local copy. > > 3. If the problem allowed limited attempts, I need to give students > some extra attempts. I can do this individually for each student, > which is painful. Or I can just increase the number of attempts > allowed for everyone. This is not fair because those students that > have not attempted the problem benefit more than those who have > wasted some of their attempts in diagnosing the problem. It would > be better if the attempt counters could all be reset to 0. > > 4. I need to notify the students that there was a mistake. > > 5. I need to file a bug report on bugzilla. > > Overall, this is a very time consuming process. As mistakes in the > library files are rather common, I've had to go through it many > times this semester. I wish it could be streamlined. Adding the new > option to edit the library file, save a local copy, and replace the > problem in the set with the local copy greatly reduced the workload > in 2. Simplifying the filing of bug reports would be great. The > bugzilla forms are long and awkward, and really do not encourage > people to file bug reports. It would be much easier if there was a > button on the problem edit page which could be clicked to file a > bug report, where a commment can quickly be entered and a corrected > source file can be attached. I am convinced this would greatly > speed up the process of weeding the bugs out of the library problems. > -- > Imre > > |
From: Michael G. <ga...@ma...> - 2005-10-18 02:31:48
|
On Oct 17, 2005, at 4:23 PM, Sam Hathaway wrote: > "warn" doesn't seem quite right to me -- the diagnostics aren't an > indication that something has necessarily gone wrong. Perhaps it > would be appropriate to add a new "slot" in the content that's > passed back from the translator for data such as this. It could > then be displayed conditionally by Problem.pm (i.e. only show it to > professors?). > There is no difficulty in separating out the different types of warnings and passing them out of the problem environment. There is a hash (something like PGflags) where the alert messages could be placed. The WARN messages are already there. We have redefined the perl warn so that warnings for the compiler and so forth are trapped and for debugging purposes it's simply been convenient to use the warn mechanism to pass out debugging info. You could define debug() in the problem environment and have it pass out the messages that it accumulates. You would have to add mechanisms to Problem.pm and/or to the template to grab the debug messages place them somewhere on the page. The transport through the PG interface will be easy. It will be pretty easy to define functions on the PG side which generate messages. The most work will be on the student/ instructor ContentGenerators where you decide how to present the information. Take care, Mike > I've never looked closely at the answer evaluation process, so I > don't know what would be easiest or make the most sense > architecturally, but maybe this could be added as a "diagnostics" > field to the value returned by each answer evaluator (called > rh_ans_evaluation_result in process_answers in Translator.pm). > > Mike may wish to comment further since he is most familiar with > this mechanism. > -sam > "Only dead fish swim with the stream." |
From: Sam H. <sh...@ma...> - 2005-10-17 20:24:59
|
On Oct 16, 2005, at 11:44, Davide P. Cervone wrote: > Folks: > > A few weeks ago, I mentioned an idea for helping problem writers > analyze whether their functions were using good input ranges and > tolerance values. I finally had the chance to put something > together for that, and have updated the Parser package to allow you > to get diagnostic information for the Formula answer checker. > Since this is used by the Parser-based version of fun_cmp(), it is > also available to it. > > The diagnostics include a graph of the student answer and the > correct answer (one one set of axes), plus graphs of the absolute > and relative errors between the two. It also shows the points > actually used for the function comparison and the numeric values of > the functions and errors. Any of these items can be enabled/ > disabled separately. This sounds like a great debugging tool. > [snip log message] > > Note that the diagnostics are added to the page via the "warn" > command, so the screen will show pink when they are enabled. As a > side effect, the diagnostics will go into the httpd error log as > well, and since they are pretty long, this can increase the size of > your log file if you use it a lot. Is there a better way to add > this kind of data to the output? I can't just use TEXT, because it > is generated when the answer checker runs (not when the page is set > up), and I think that it is too late for that (though I didn't > actually try it). "warn" doesn't seem quite right to me -- the diagnostics aren't an indication that something has necessarily gone wrong. Perhaps it would be appropriate to add a new "slot" in the content that's passed back from the translator for data such as this. It could then be displayed conditionally by Problem.pm (i.e. only show it to professors?). I've never looked closely at the answer evaluation process, so I don't know what would be easiest or make the most sense architecturally, but maybe this could be added as a "diagnostics" field to the value returned by each answer evaluator (called rh_ans_evaluation_result in process_answers in Translator.pm). Mike may wish to comment further since he is most familiar with this mechanism. -sam |
From: Sam H. <sh...@ma...> - 2005-10-17 18:18:28
|
Hi Guys, I often find I'd like to use values from the course environment from places other than content generator classes (where they're available via $self->r->ce). For example, the date parsing functions in Utils.pm need the timezone, the database record classes could benefit from having access to default values, and so on. The current solution seems to be to either pass the entire $ce object into the function in question, or grab only the needed values from $ce and pass those in. It's somewhat of a hassle in the common case, and a big hassle in some cases. Examples: * I'd like to add methods to the DB record classes to return human- readable versions of database values. To format date strings, I need a timezone. So a simple call like $GlobalSet->pretty_print; becomes $GlobalSet->pretty_print($timezone); * This is also the reason why I put the new status mangling functions in CourseEnvironment itself instead of in a database class. From CourseEnvironment.pm: > There is a set of operations that require certain data from the course > environment. Most of these are un Utils.pm. I've been forced to > pass $ce into > them, so that they can get their data out. But some things are so > intrinsically > linked to the course environment that they might as well be methods > in this > class. * The Utils::CourseManagement functions need $ce values. * Classes like HTML::ScrollingRecordList and Utils::SortRecords/ FormatRecords could benefit from having access to settings in $ce -- one could customize the display of lists, add new sort methods and format strings, etc. * I also just noticed the parseDateTime and formatDateTime wrappers in ContentGenerator.pm that serve to work around this problem by grabbing the timezone from $ce and passing it to the real functions in Utils.pm. I'm considering making $ce a dynamically scoped variable with a line like local $CE = $ce; in WeBWorK.pm. This would make $CE available from any code called by WeBWorK.pm. It would make global.conf function much more like Global.pm did in the WW1 days -- you could access it from anywhere, and rely on its presence. The main objection I see is that it would make it harder to pull pieces of WW code out and use them in places where a course environment is not available. However, the current practice of passing $ce in to many functions has the same effect. Furthermore, CourseEnvironment.pm itself is failry portable. We use it in several command-line scripts without inconvenience. I'm tempted to make the entire WeBWorK::Request object dynamically scoped -- that would give us access to $ce, $db, $authz, etc. from anywhere. However, this would be much worse in terms of modularity, since we'd also have access to $r->param() from anywhere, and I fear that the temptation to check and modify params from places that should be request-independent would be too great and would lead to spaghetti code. I don't take a change like this lightly, and I'd like your input on possible problems with this approach as well as alternate solutions. -sam |
From: Davide P. C. <dp...@un...> - 2005-10-16 15:44:29
|
Folks: A few weeks ago, I mentioned an idea for helping problem writers analyze whether their functions were using good input ranges and tolerance values. I finally had the chance to put something together for that, and have updated the Parser package to allow you to get diagnostic information for the Formula answer checker. Since this is used by the Parser-based version of fun_cmp(), it is also available to it. The diagnostics include a graph of the student answer and the correct answer (one one set of axes), plus graphs of the absolute and relative errors between the two. It also shows the points actually used for the function comparison and the numeric values of the functions and errors. Any of these items can be enabled/disabled separately. Here is the message from the CVS log that says how to use it: ______________________________________________________________ Added a new experimental diagonstic function for the function answer checker. When enabled, it will produce graphs of the correct answer, the student answer, and the absolute and relative errors, and will list the data points used in the comparison, plus the numerical values of the results and errors. To enable the diagnostic, use ANS(fun_cmp($f,diagnostics=>1)); Note that only single-variable functions can be graphed at the moment, so if you are using a multi-variable check, you need to disable the graphing. To do this use ANS(fun_cmp($f,vars=>['x','y'],diagnostics=>[showGraphs=>0])); The diagnostic mode is only available for the Parser-based versions of the function checker, and (of course) with the native Parser objects as well: ANS(Formula($f)->cmp(diagnostics=>1)); There are now Context settings to control the diagnostics, which can be set through Context()->diagnostics->set(). For example Context()->diagnostics->set(formulas=>{showGraphs=>0}); would turn off graphs for all functions comparisons. Some of the other values you can set are: formulas => { showTestPoints => 1, # show the test points and function values showRelativeErrors => 1, # show the relative errors for the student answer showAbsoluteErrors => 1, # show the absolute errors for the student answer showGraphs => 1, # show the various graphs graphRelativeErrors => 1, # show the relative error graph graphAbsoluteErrors => 1, # show the absolute error graph clipRelativeError => 5, # don't show relative errors above 5 clipAbsoluteError => 5, # don't show absolute errors above 5 plotTestPoints => 1, # include dots at the test points combineGraphs => 1, # show correct and student graphs in one image }, graphs => { divisions => 75, # the number of data points to plot limits => [-2,2], # the lower and upper limit of the plot # (taken from the function limits if not provided) size => 250, # pixel size of the image (could be [width,height]) grid => [10,10], # number of grid lines in each direction axes => [0,0], # where to put axes relative to origin } Any of these can be set in the Context(), or in the answer checker itself. If you set diagnostics to an array reference, the entries in the array refer to element of the formulas hash. If you set diagonstics to a hash reference, then you can set values in either the formulas or graphs hashes, as in: ANS(Formula($f)->cmp(diagnostics=>{ formulas => {showAbsoluteErrors=>0}, graphs => {size=>300, divisions=>100}, })); If you want all function checkers to show diagnostics, use Context()->diagonstics->set(formulas=>{show=>1}); The image file names are modified to include the current time so that the names will be unique. This avoids problems with the browser cache showing a old image when a new one has been generated. But this also means that the temporary image directory will fill up fast, so you may need to empty it if you use the diagnostic images frequently. This is just a first attempt at a diagnostic feature. I think it will help when you are not sure if the tolerances are set properly, or if you think a student answer should be markes correct but isn't, as it will point out which point(s) are not being accepted. ______________________________________________________________ Note that the diagnostics are added to the page via the "warn" command, so the screen will show pink when they are enabled. As a side effect, the diagnostics will go into the httpd error log as well, and since they are pretty long, this can increase the size of your log file if you use it a lot. Is there a better way to add this kind of data to the output? I can't just use TEXT, because it is generated when the answer checker runs (not when the page is set up), and I think that it is too late for that (though I didn't actually try it). Anyway, give it a try and see what you think. It may help diagnose those times when it is not clear why a student's answer is (or is not) being accepted when it shouldn't be. Davide |
From: John J. <jj...@as...> - 2005-10-02 20:00:06
|
Hi all, I just an initial version of the Config module. Based on the earlier suggestions, I used a separate file for the simple config parts; it will not write to course.conf at all. I would not expect it to be too hard to store this information in a database instead. There are tons of variables which can still be added. Most of it can be put right into the variable at the end of Constants.pm (e.g., there are over 40 permissions values and I only did a few of them). Feel free to start adding to it. Other items will require new config-types to be added to the module itself, so naturally it would be simpler to add where one can use an existing type. John Sam Hathaway wrote: > On Sep 30, 2005, at 1:58, John Jones wrote: > > What you propose is probably fine for the kind of customization we > want to allow right now. Here's my thinking, though: > > * I want to be able to use web-based (i.e. non-turing-complete) > configuration for things that site administrators might want to > configure. Look at moodle -- there are many per-course options that > can be configured, but system-wide admin-type options are also exposed. > > * We can't predict what kinds of options administrators (or even > users) are going to want to customize. At first I was thinking of this doing something for global.conf, but then backed off. If someone develops a global.conf analogue, then they will have more complicated issues to deal with. Still, they can probably make life easier for sites by making some things web-configurable. I might still shy away from allowing web-configuration of values which can make the whole system unusable. As far as what users want to configure, I expect that the configurable options will grow over time, partly due to user requests. But, there may be some options users have to configure by hand. > * I want global.conf/course.conf to become more like source and less > like configuration over time. I think this is consistent with the current setup. While the new "simple.conf" is read by perl, it could work in other ways. Read by perl was the simplest way to incorporate it into the current system. > On the other hand, your method is simpler and doesn't have > bootstrapping problems, so I would say that you should go ahead with it. > > On Sep 29, 2005, at 19:11, John Jones wrote: > >> To know what values to write, the module will figure out what the >> system defaults are, the values for this course, and the values for >> "this course minus anything previously set by this module". The >> last one is needed to prevent odd behaviour if course.conf differs >> from the system default in its upper part and the user switches back >> to the system default. This may be a rare occurance, but if we can >> check for it, we might as well. > > > Why not enclose the stuff written by the Config.pm module in a > conditional like > > unless ($skip_config_pm) { > ... > } > > and then call WeBWorK::CourseEnvironment->new(..., skip_config_pm => 1)? > -sam |
From: Sam H. <sh...@ma...> - 2005-10-02 18:06:34
|
On Sep 30, 2005, at 1:58, John Jones wrote: > Sam Hathaway wrote: > >> What do you think of having these values pre-seed the course >> environment, rather than being tacked on at the end? This would >> let us incorporate them into inline logic in global.conf, which >> would be useful in cases where one value is used in several places. > > I guess I haven't run across any places where this savings would > take place. Mostly, we are just assigning to variables, and so the > last assignment wins. Pre-seeding seems like it would be more > complicated since setting the global values would have to check to > see if a course value was pre-seeded set. > >> This would also save you from having to calculate the values for >> "this course minus anything previously set by this module". > > I'm not sure it saves anything. I think the same problem exists if > you pre-seed, and you have the analogous set of solutions (not > worry about user edits in course.conf, just save all values > regardless of whether they seem to differ from system defaults, and > figure out the three values of system, upper-part of course.conf, > and lower-part of course.conf). > >> Also, it would avoid having to rewrite user-editable text files, >> which, while I'm sure it could be done relatively sanely, make me >> nervous. > > I think it would be trouble if Config had to parse course.conf > itself and try to rewrite portions which contain might have > contained tricky things in it. In the current approach, neither of > those things happen. The use of CourseEnvironment means that > values are computed by the existing mechanisms. You can be as > tricky as you want in the top half of course.conf. In will be > rewritten only in the sense of transcribed verbatim. Writing the > bottom half of course.conf would be straight variable assignments, > and it would only write variables it has been taught to write. The > only part of that which makes me nervous is for string values where > you want to protect the user from unbalanced quotes. > >> Dennis's take on the subject: >> >>> You define a limited set of configuration options that most >>> "simple" users will want. Then you develop a simpler config >>> file format for describing those options and put a GUI on it. >>> Then you write a course.conf file that reads that file (or is >>> given the data inside via a stream or something for security >>> reasons) and sets the appropriate values based on it. > > This seems equivalent to the approach I was taking. The only > difference is whether simple settings are in a separate file, or > part 2 of course.conf. The advantage of using course.conf is that > it gets read on every web page webwork renders, so reading one few > file is a fraction of a second faster. > > If you do have a course.simple which gets read after course.conf, > it would still be helpful to have a mechanism to say: make a > CourseEnvironment object where you do not read course.simple. This > seems to be pretty similar to: make a CourseEnvironment with this > file as course.conf. > >>> For the things that involve the setting of a string and then the >>> subsequent using it all over, you could just define fields for >>> the various parts and have the string concatenation be implicit >>> from the point of view of the configuration. > > I don't think we want to let a user set $webworkDirs{logs} or > $courseURLs{html} through the web-based configuration. I looked > through global.conf.dist and I don't see any variables on the right > side of an assignment which a regular user should be able to > change. Are there some others have in mind? What you propose is probably fine for the kind of customization we want to allow right now. Here's my thinking, though: * I want to be able to use web-based (i.e. non-turing-complete) configuration for things that site administrators might want to configure. Look at moodle -- there are many per-course options that can be configured, but system-wide admin-type options are also exposed. * We can't predict what kinds of options administrators (or even users) are going to want to customize. * I want global.conf/course.conf to become more like source and less like configuration over time. On the other hand, your method is simpler and doesn't have bootstrapping problems, so I would say that you should go ahead with it. On Sep 29, 2005, at 19:11, John Jones wrote: > To know what values to write, the module will figure out what the > system defaults are, the values for this course, and the values for > "this course minus anything previously set by this module". The > last one is needed to prevent odd behaviour if course.conf differs > from the system default in its upper part and the user switches > back to the system default. This may be a rare occurance, but if > we can check for it, we might as well. Why not enclose the stuff written by the Config.pm module in a conditional like unless ($skip_config_pm) { ... } and then call WeBWorK::CourseEnvironment->new(..., skip_config_pm => 1)? -sam |
From: Arnold P. <ap...@ma...> - 2005-09-30 12:58:56
|
At 08:42 PM 9/29/2005, John Jones wrote: >The current types are 'simple' (a text string), 'permission', 'list' >(a list of text strings like feedback e-mail addresses), and >'boolean' (for things like useOldAnswerMacros and useBaseTenLog >where Config translates back and forth between a drop-down menu of >true/false and 0/1 for the variables). Adding other types will not >be very hard, but would require changes to the module itself. A very simple comment. Why not rename 'simple' to be 'text' . I had no idea what "simple" meant until I read the above. Arnie Prof. Arnold K. Pizer Dept. of Mathematics University of Rochester Rochester, NY 14627 (585) 275-7767 |
From: John J. <jj...@as...> - 2005-09-30 05:56:36
|
Sam Hathaway wrote: > What do you think of having these values pre-seed the course > environment, rather than being tacked on at the end? This would let > us incorporate them into inline logic in global.conf, which would be > useful in cases where one value is used in several places. I guess I haven't run across any places where this savings would take place. Mostly, we are just assigning to variables, and so the last assignment wins. Pre-seeding seems like it would be more complicated since setting the global values would have to check to see if a course value was pre-seeded set. > This would also save you from having to calculate the values for > "this course minus anything previously set by this module". I'm not sure it saves anything. I think the same problem exists if you pre-seed, and you have the analogous set of solutions (not worry about user edits in course.conf, just save all values regardless of whether they seem to differ from system defaults, and figure out the three values of system, upper-part of course.conf, and lower-part of course.conf). > Also, it would avoid having to rewrite user-editable text files, > which, while I'm sure it could be done relatively sanely, make me > nervous. I think it would be trouble if Config had to parse course.conf itself and try to rewrite portions which contain might have contained tricky things in it. In the current approach, neither of those things happen. The use of CourseEnvironment means that values are computed by the existing mechanisms. You can be as tricky as you want in the top half of course.conf. In will be rewritten only in the sense of transcribed verbatim. Writing the bottom half of course.conf would be straight variable assignments, and it would only write variables it has been taught to write. The only part of that which makes me nervous is for string values where you want to protect the user from unbalanced quotes. > Dennis's take on the subject: > >> You define a limited set of configuration options that most "simple" >> users will want. Then you develop a simpler config file format for >> describing those options and put a GUI on it. Then you write a >> course.conf file that reads that file (or is given the data inside >> via a stream or something for security reasons) and sets the >> appropriate values based on it. > This seems equivalent to the approach I was taking. The only difference is whether simple settings are in a separate file, or part 2 of course.conf. The advantage of using course.conf is that it gets read on every web page webwork renders, so reading one few file is a fraction of a second faster. If you do have a course.simple which gets read after course.conf, it would still be helpful to have a mechanism to say: make a CourseEnvironment object where you do not read course.simple. This seems to be pretty similar to: make a CourseEnvironment with this file as course.conf. >> For the things that involve the setting of a string and then the >> subsequent using it all over, you could just define fields for the >> various parts and have the string concatenation be implicit from the >> point of view of the configuration. > I don't think we want to let a user set $webworkDirs{logs} or $courseURLs{html} through the web-based configuration. I looked through global.conf.dist and I don't see any variables on the right side of an assignment which a regular user should be able to change. Are there some others have in mind? John |
From: Sam H. <sh...@ma...> - 2005-09-30 02:47:49
|
On Sep 29, 2005, at 22:32, John Jones wrote: > Sam Hathaway wrote: > >> On Sep 29, 2005, at 20:42, John Jones wrote: >> >>> One problem with permissions is that the value of things like >>> "ta" is configurable in global.conf, but the value is not >>> visible from the outside. One change I was going to make in >>> global.conf.dist was to add to the permissions structure: >>> >>> %permissionLevels = ( >>> login => $guest, >>> report_bugs => $student, >>> ... >>> guest => $guest, >>> student => $student, >>> proctor => $proctor, >>> ta => $ta, >>> professor => $professor, >>> ); >> >> I'd caution against adding these values as "permissions". They're >> not, and they would invite abuse whereby code would check >> hasPermissions($userID, "ta") instead of creating a logical >> capability. >> >> Instead, why not add a %userRoles hash, like this: >> >> %userRoles = ( >> guest => -5, >> student => 0, >> proctor => 2, >> ta => 5, >> professor => 10, >> ); >> >> and then redefine %permissionLevels like so: >> >> >> %permissionLevels = ( >> login => $userRoles{guest}, >> report_bugs => $userRoles{student}, >> > > I was thinking of this, but thought someone would object since $ta, > $student, etc were specifically kept out of the course > environment. But, I think this would definitely be better. It > would mean a site could add a permission level by adding it in one > place in global.conf. My long term plan is to replace the permission_level field in the permission table with a role field, and then also have include_permissions and omit_permissions to include additional or omit omissions from the role. >> or even, with a slight change to Authz.pm: >> >> %permissionLevels = ( >> login => "guest", >> report_bugs => "student", >> >> Come to think of it, once we have this, we can go wild. It would >> be nice to break out of the this-permission-value-or-higher trap, >> for example: >> >> %permissionLevels = ( >> login => qw/guest student proctor >> ta professor/, >> report_bugs => qw/student proctor ta >> professor/, > > Have people run into cases where there was a problem with > permission types being linearly ordered? Not in particular, although it's caused us to have to have weirdly formulated permissions like avoid_recording_answers and dont_log_past_answers. Allowing for this would bring the permission system closer to being a generalized role-based authentication system. -sam |
From: John J. <jj...@as...> - 2005-09-30 02:30:35
|
Sam Hathaway wrote: > On Sep 29, 2005, at 20:42, John Jones wrote: > >> One problem with permissions is that the value of things like "ta" >> is configurable in global.conf, but the value is not visible from >> the outside. One change I was going to make in global.conf.dist was >> to add to the permissions structure: >> >> %permissionLevels = ( >> login => $guest, >> report_bugs => $student, >> ... >> guest => $guest, >> student => $student, >> proctor => $proctor, >> ta => $ta, >> professor => $professor, >> ); > > > I'd caution against adding these values as "permissions". They're > not, and they would invite abuse whereby code would check > hasPermissions($userID, "ta") instead of creating a logical capability. > > Instead, why not add a %userRoles hash, like this: > > %userRoles = ( > guest => -5, > student => 0, > proctor => 2, > ta => 5, > professor => 10, > ); > > and then redefine %permissionLevels like so: > > > %permissionLevels = ( > login => $userRoles{guest}, > report_bugs => $userRoles{student}, I was thinking of this, but thought someone would object since $ta, $student, etc were specifically kept out of the course environment. But, I think this would definitely be better. It would mean a site could add a permission level by adding it in one place in global.conf. > or even, with a slight change to Authz.pm: > > %permissionLevels = ( > login => "guest", > report_bugs => "student", > > Come to think of it, once we have this, we can go wild. It would be > nice to break out of the this-permission-value-or-higher trap, for > example: > > %permissionLevels = ( > login => qw/guest student proctor ta > professor/, > report_bugs => qw/student proctor ta > professor/, Have people run into cases where there was a problem with permission types being linearly ordered? John |
From: Michael G. <ga...@ma...> - 2005-09-30 01:50:57
|
> > Come to think of it, once we have this, we can go wild. It would be > nice to break out of the this-permission-value-or-higher trap, for > example: > > %permissionLevels = ( > login => qw/guest student proctor > ta professor/, > report_bugs => qw/student proctor ta > professor/, > > Ok, that's enough of that. :) > -sam > No, no -- go wild -- :-) Take care, Mike "Only dead fish swim with the stream." |
From: Sam H. <sh...@ma...> - 2005-09-30 01:39:39
|
On Sep 29, 2005, at 20:42, John Jones wrote: > One problem with permissions is that the value of things like "ta" > is configurable in global.conf, but the value is not visible from > the outside. One change I was going to make in global.conf.dist > was to add to the permissions structure: > > %permissionLevels = ( > login => $guest, > report_bugs => $student, > ... > guest => $guest, > student => $student, > proctor => $proctor, > ta => $ta, > professor => $professor, > ); I'd caution against adding these values as "permissions". They're not, and they would invite abuse whereby code would check hasPermissions($userID, "ta") instead of creating a logical capability. Instead, why not add a %userRoles hash, like this: %userRoles = ( guest => -5, student => 0, proctor => 2, ta => 5, professor => 10, ); and then redefine %permissionLevels like so: %permissionLevels = ( login => $userRoles{guest}, report_bugs => $userRoles{student}, or even, with a slight change to Authz.pm: %permissionLevels = ( login => "guest", report_bugs => "student", Come to think of it, once we have this, we can go wild. It would be nice to break out of the this-permission-value-or-higher trap, for example: %permissionLevels = ( login => qw/guest student proctor ta professor/, report_bugs => qw/student proctor ta professor/, Ok, that's enough of that. :) -sam |
From: Sam H. <sh...@ma...> - 2005-09-30 01:27:59
|
On Sep 29, 2005, at 19:11, John Jones wrote: > Adding variables which can be configured will amount to adding > entries to this constant. The first question is, where should this > go? Should it be a constant in the new module, or should it be in > Constants.pm, in which case configuration would be "configurable". > Both ways are easy to work with, so I don't really care myself. Constants.pm sounds like a good place for this. > The saving of information is done at the end of course.conf after a > comment line it adds as a separator. Writing to course.conf will > mean preserving the stuff above its separator, and then writing > values which are needed below the separator. > > To know what values to write, the module will figure out what the > system defaults are, the values for this course, and the values for > "this course minus anything previously set by this module". The > last one is needed to prevent odd behaviour if course.conf differs > from the system default in its upper part and the user switches > back to the system default. This may be a rare occurance, but if > we can check for it, we might as well. > > I am getting the values of variables by firing up multiple course > environments. You have the current course for free, and one can > easily get the system defaults by WeBWorK::ContentGenerator->new > with no course specified. > > But, to easily know what the values would be if we only had the top > part of course.conf, I would like to be able to specify the > course.conf file while creating a new CourseEnvironment object. > Then I could write the top half of course.conf to a file named > something like course-config-tmp.conf and use it for a new course > environment. I want to use that to create a course environment, > and then delete it. So far, my attempts have failed (to give the > current course as the course name but to have course-config- > tmp.conf be used as the course configuration file). > I could work around it by making a copy of course.conf, replacing > it with the top half, creating a course environment, then moving > the original course.conf back into place, but I would rather not > make so many changes to course.conf. > > So, is there a way to have WeBWorK::CourseEnvironment->new be > tolded the name of the course configuration file for the current > invocation? > > If not, would anyone mind if I added that feature to > CourseEnvironment.pm (specified through the hash reference way of > specifying arguments)? What do you think of having these values pre-seed the course environment, rather than being tacked on at the end? This would let us incorporate them into inline logic in global.conf, which would be useful in cases where one value is used in several places. This would also save you from having to calculate the values for "this course minus anything previously set by this module". Also, it would avoid having to rewrite user-editable text files, which, while I'm sure it could be done relatively sanely, make me nervous. Dennis's take on the subject: > You define a limited set of configuration options that most > "simple" users will want. Then you develop a simpler config file > format for describing those options and put a GUI on it. Then you > write a course.conf file that reads that file (or is given the data > inside via a stream or something for security reasons) and sets the > appropriate values based on it. > > For the things that involve the setting of a string and then the > subsequent using it all over, you could just define fields for the > various parts and have the string concatenation be implicit from > the point of view of the configuration. > > I think there are times in a project's life cycle when you don't > know what your users are going to want, but you do know that they > will be sophisticated early-adopters, and so you make your system > turing-complete. but at some point common usage patterns appear > and you can start to make them more static. > > I have a secret agenda here that course.conf eventually stops being > user-edited. > > a TC config file is useful, but for non-technical users, it starts > to feel like a cop-out for inadequate user testing. And: > you don't have to think of yourself as making that distinction > [between beginner and advanced users]. The distinction isn't > present in the GUI. I mean, all open-source code makes that > distinction. The regular users edit the config files, the advanced > users edit the program. > > I'm saying, course.conf becomes part of the "source code" of the > program, slowly but surely as you learn what kinds of configuration > people actually want to do. Imagine a machine-readable and -writeable representation that would be stored somewhere. (file? database? whatever.) It could be something as simple as a set of key-value pairs, or a Data::Dumper string. CourseEnvironment would read it in, and Safe::share() the values contained in it into the compartment that I think this would be good for flexibility, but there are bootstrapping problems. Namely, the only thing we know before the course environment gets built is the path to the webwork base directory (and we assume "conf/global.conf" relative to that), so it would be impossible to store the config information under the course directory, for example. Brainstorming... One solution would be to pull the database config out of the course environment and make it static (Constants.pm or passed in from the apache config or something). Since we're planning on removing all but sql_single for 2.2 anyway, this would be doable. Then, the "simple config" information could be stored in a settings table, and used to seed the course environment before evaluating global.conf. Another possibility is to let global.conf decide when to load the simple config data. It could get loaded from a file in the course directory after the initial values are defined, because by that time the loader would have access to $webwork_courses_dir. Comments? -sam |
From: Michael G. <ga...@ma...> - 2005-09-30 01:14:16
|
On Sep 29, 2005, at 8:42 PM, John Jones wrote: > Michael Gage wrote: > > >> >> On Sep 29, 2005, at 7:11 PM, John Jones wrote: >> >> >>> Hi, >>> >>> There was previous discussion of a web-based course >>> configuration module. I have a draft of this, but also a couple >>> of questions. >>> >>> First, the module knows what values can be configured (and how) >>> via one variable which looks like this: >>> >>> [['General', >>> { var => 'sessionKeyTimeout', >>> doc => 'Inactivity time before a user is required to >>> login again.', >>> doc2 => 'Length of inactivity, in seconds, before a >>> user is required to login again.', >>> type => 'simple'}, >>> { var => 'courseFiles{course_info}', >>> doc => 'Name of course information file', >>> doc2 => 'Name of course information file (located in >>> the templates directory)', >>> type => 'simple'}], >>> ['Permissions', >>> { var => 'permissionLevels{login}', >>> doc => 'Allowed to login to the course', >>> type => 'permission'}, ...]] >>> >>> Adding variables which can be configured will amount to adding >>> entries to this constant. The first question is, where should >>> this go? Should it be a constant in the new module, or should >>> it be in Constants.pm, in which case configuration would be >>> "configurable". Both ways are easy to work with, so I don't >>> really care myself. >>> >>> >> Hi John, >> >> I guess I vote for Constants.pm, but I don't have a strong >> preference. >> >> It's not completely clear from your description... >> Does your scheme above allow one to specify the values and >> perhaps labels of those values that a variable can assume? >> >> What I have in mind is a form element for permissions that has a >> popup menu with guest, nobody, student, ta, prof as labels >> and -5, undef, 0, 5, 10 as values. Having the allowable values >> configurable will probably be useful. >> >> There will be other examples where it will be best if the >> instructor is allowed to choose among specified alternatives >> rather than >> enter values free form. >> >> > I didn't include the full configurations part, but there is enough > to see that each variable has a type, and permissions is one of the > types, so it gets special handling. > > One problem with permissions is that the value of things like "ta" > is configurable in global.conf, but the value is not visible from > the outside. One change I was going to make in global.conf.dist > was to add to the permissions structure: > > %permissionLevels = ( > login => $guest, > report_bugs => $student, > ... > guest => $guest, > student => $student, > proctor => $proctor, > ta => $ta, > professor => $professor, > ); > > This way, the numeric value of ta is known to the Config module. > The config module then handles permissions with an official webwork > combobox which shows both the name and numeric value in the menu > part. I thought this was better than just name because it lets > users set other crazy permission values if they want (which is the > current situation), they can see qualitatitively what the numbers > mean, but they have the numbers which is what they see on the > classlist page. With this change, however, the classlist page > could switch to names for permissions if the numeric value matches > one of the values for standard names. > > The current types are 'simple' (a text string), 'permission', > 'list' (a list of text strings like feedback e-mail addresses), and > 'boolean' (for things like useOldAnswerMacros and useBaseTenLog > where Config translates back and forth between a drop-down menu of > true/false and 0/1 for the variables). Adding other types will not > be very hard, but would require changes to the module itself. > > John > If you add a key/value pair type then I think you cover everything I can think I would want. The boolean is already a key/value pair. And some versions of email addresses might involve key/value pairs: e.g. user_id/user_email_address. You'd use the key as a label in a popup menu and the value as the vaule. I'd like to suggest that for the first approximation you assume that the "upper" part of the course.conf file is empty. What I would hope is that when we first implement your module there are the site configurations in global.conf and anything that we currently override in any of our installations for course.conf can be written in the lower part of course.conf. Instructors would be discouraged (perhaps prevented) from adding things directly to course.conf via File Manager. Eventually we'll find something complicated that has to go in course.conf but can't easily be handled by the mechanism you've defined and it will have to go in the top part of course.conf. Then the more general paradigm you're talking about will be useful. At the beginning however I'd like to keep the top part either empty or very small. About permissions. Eventually I'd like to use strings for permission values rather than integers. Permissions would also form a partial ordering instead of a linear ordering (or perhaps a more general structure). That's for the far future however. Take care, Mike > PS HTML::ComboBox::combobox allows a second argument of @Records > which doesn't seem to be used. > > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: > Power Architecture Resource Center: Free content, downloads, > discussions, > and more. http://solutions.newsforge.com/ibmarch.tmpl > _______________________________________________ > OpenWeBWorK-Devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/openwebwork-devel > "Only dead fish swim with the stream." |
From: John J. <jj...@as...> - 2005-09-30 00:40:21
|
Michael Gage wrote: > > On Sep 29, 2005, at 7:11 PM, John Jones wrote: > >> Hi, >> >> There was previous discussion of a web-based course configuration >> module. I have a draft of this, but also a couple of questions. >> >> First, the module knows what values can be configured (and how) via >> one variable which looks like this: >> >> [['General', >> { var => 'sessionKeyTimeout', >> doc => 'Inactivity time before a user is required to login >> again.', >> doc2 => 'Length of inactivity, in seconds, before a user is >> required to login again.', >> type => 'simple'}, >> { var => 'courseFiles{course_info}', >> doc => 'Name of course information file', >> doc2 => 'Name of course information file (located in the >> templates directory)', >> type => 'simple'}], >> ['Permissions', >> { var => 'permissionLevels{login}', >> doc => 'Allowed to login to the course', >> type => 'permission'}, ...]] >> >> Adding variables which can be configured will amount to adding >> entries to this constant. The first question is, where should this >> go? Should it be a constant in the new module, or should it be in >> Constants.pm, in which case configuration would be "configurable". >> Both ways are easy to work with, so I don't really care myself. >> > Hi John, > > I guess I vote for Constants.pm, but I don't have a strong preference. > > It's not completely clear from your description... > Does your scheme above allow one to specify the values and perhaps > labels of those values that a variable can assume? > > What I have in mind is a form element for permissions that has a > popup menu with guest, nobody, student, ta, prof as labels > and -5, undef, 0, 5, 10 as values. Having the allowable values > configurable will probably be useful. > > There will be other examples where it will be best if the instructor > is allowed to choose among specified alternatives rather than > enter values free form. > I didn't include the full configurations part, but there is enough to see that each variable has a type, and permissions is one of the types, so it gets special handling. One problem with permissions is that the value of things like "ta" is configurable in global.conf, but the value is not visible from the outside. One change I was going to make in global.conf.dist was to add to the permissions structure: %permissionLevels = ( login => $guest, report_bugs => $student, ... guest => $guest, student => $student, proctor => $proctor, ta => $ta, professor => $professor, ); This way, the numeric value of ta is known to the Config module. The config module then handles permissions with an official webwork combobox which shows both the name and numeric value in the menu part. I thought this was better than just name because it lets users set other crazy permission values if they want (which is the current situation), they can see qualitatitively what the numbers mean, but they have the numbers which is what they see on the classlist page. With this change, however, the classlist page could switch to names for permissions if the numeric value matches one of the values for standard names. The current types are 'simple' (a text string), 'permission', 'list' (a list of text strings like feedback e-mail addresses), and 'boolean' (for things like useOldAnswerMacros and useBaseTenLog where Config translates back and forth between a drop-down menu of true/false and 0/1 for the variables). Adding other types will not be very hard, but would require changes to the module itself. John PS HTML::ComboBox::combobox allows a second argument of @Records which doesn't seem to be used. |
From: Michael G. <ga...@ma...> - 2005-09-29 23:40:37
|
On Sep 29, 2005, at 7:11 PM, John Jones wrote: > Hi, > > There was previous discussion of a web-based course configuration > module. I have a draft of this, but also a couple of questions. > > First, the module knows what values can be configured (and how) via > one variable which looks like this: > > [['General', > { var => 'sessionKeyTimeout', > doc => 'Inactivity time before a user is required to login > again.', > doc2 => 'Length of inactivity, in seconds, before a user > is required to login again.', > type => 'simple'}, > { var => 'courseFiles{course_info}', > doc => 'Name of course information file', > doc2 => 'Name of course information file (located in the > templates directory)', > type => 'simple'}], > ['Permissions', > { var => 'permissionLevels{login}', > doc => 'Allowed to login to the course', > type => 'permission'}, ...]] > > Adding variables which can be configured will amount to adding > entries to this constant. The first question is, where should this > go? Should it be a constant in the new module, or should it be in > Constants.pm, in which case configuration would be "configurable". > Both ways are easy to work with, so I don't really care myself. > Hi John, I guess I vote for Constants.pm, but I don't have a strong preference. It's not completely clear from your description... Does your scheme above allow one to specify the values and perhaps labels of those values that a variable can assume? What I have in mind is a form element for permissions that has a popup menu with guest, nobody, student, ta, prof as labels and -5, undef, 0, 5, 10 as values. Having the allowable values configurable will probably be useful. There will be other examples where it will be best if the instructor is allowed to choose among specified alternatives rather than enter values free form. Thanks for working on this. It looks like a good start. Take care, Mike > The saving of information is done at the end of course.conf after a > comment line it adds as a separator. Writing to course.conf will > mean preserving the stuff above its separator, and then writing > values which are needed below the separator. > > To know what values to write, the module will figure out what the > system defaults are, the values for this course, and the values for > "this course minus anything previously set by this module". The > last one is needed to prevent odd behaviour if course.conf differs > from the system default in its upper part and the user switches > back to the system default. This may be a rare occurance, but if > we can check for it, we might as well. > > I am getting the values of variables by firing up multiple course > environments. You have the current course for free, and one can > easily get the system defaults by WeBWorK::ContentGenerator->new > with no course specified. > > But, to easily know what the values would be if we only had the top > part of course.conf, I would like to be able to specify the > course.conf file while creating a new CourseEnvironment object. > Then I could write the top half of course.conf to a file named > something like course-config-tmp.conf and use it for a new course > environment. I want to use that to create a course environment, > and then delete it. So far, my attempts have failed (to give the > current course as the course name but to have course-config- > tmp.conf be used as the course configuration file). > I could work around it by making a copy of course.conf, replacing > it with the top half, creating a course environment, then moving > the original course.conf back into place, but I would rather not > make so many changes to course.conf. > > So, is there a way to have WeBWorK::CourseEnvironment->new be > tolded the name of the course configuration file for the current > invocation? > > If not, would anyone mind if I added that feature to > CourseEnvironment.pm (specified through the hash reference way of > specifying arguments)? > > Of course, other comments/suggestions are welcome. > > John > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by: > Power Architecture Resource Center: Free content, downloads, > discussions, > and more. http://solutions.newsforge.com/ibmarch.tmpl > _______________________________________________ > OpenWeBWorK-Devel mailing list > Ope...@li... > https://lists.sourceforge.net/lists/listinfo/openwebwork-devel > "Only dead fish swim with the stream." |
From: John J. <jj...@as...> - 2005-09-29 23:10:45
|
Hi, There was previous discussion of a web-based course configuration module. I have a draft of this, but also a couple of questions. First, the module knows what values can be configured (and how) via one variable which looks like this: [['General', { var => 'sessionKeyTimeout', doc => 'Inactivity time before a user is required to login again.', doc2 => 'Length of inactivity, in seconds, before a user is required to login again.', type => 'simple'}, { var => 'courseFiles{course_info}', doc => 'Name of course information file', doc2 => 'Name of course information file (located in the templates directory)', type => 'simple'}], ['Permissions', { var => 'permissionLevels{login}', doc => 'Allowed to login to the course', type => 'permission'}, ...]] Adding variables which can be configured will amount to adding entries to this constant. The first question is, where should this go? Should it be a constant in the new module, or should it be in Constants.pm, in which case configuration would be "configurable". Both ways are easy to work with, so I don't really care myself. The saving of information is done at the end of course.conf after a comment line it adds as a separator. Writing to course.conf will mean preserving the stuff above its separator, and then writing values which are needed below the separator. To know what values to write, the module will figure out what the system defaults are, the values for this course, and the values for "this course minus anything previously set by this module". The last one is needed to prevent odd behaviour if course.conf differs from the system default in its upper part and the user switches back to the system default. This may be a rare occurance, but if we can check for it, we might as well. I am getting the values of variables by firing up multiple course environments. You have the current course for free, and one can easily get the system defaults by WeBWorK::ContentGenerator->new with no course specified. But, to easily know what the values would be if we only had the top part of course.conf, I would like to be able to specify the course.conf file while creating a new CourseEnvironment object. Then I could write the top half of course.conf to a file named something like course-config-tmp.conf and use it for a new course environment. I want to use that to create a course environment, and then delete it. So far, my attempts have failed (to give the current course as the course name but to have course-config-tmp.conf be used as the course configuration file). I could work around it by making a copy of course.conf, replacing it with the top half, creating a course environment, then moving the original course.conf back into place, but I would rather not make so many changes to course.conf. So, is there a way to have WeBWorK::CourseEnvironment->new be tolded the name of the course configuration file for the current invocation? If not, would anyone mind if I added that feature to CourseEnvironment.pm (specified through the hash reference way of specifying arguments)? Of course, other comments/suggestions are welcome. John |
From: Sam H. <sh...@ma...> - 2005-09-27 23:17:30
|
On Sep 27, 2005, at 18:00, John Jones wrote: > Sam Hathaway via activitymail wrote: > > >> Log Message: >> ----------- >> pointless confusion, while humorous, is not good for maintainability. >> >> > Too bad - while I didn't write it, I liked that comment when I ran > across it a while back. > > What does that line do? besides confuse people? nothing. it is never reached. -sam See also: http://cvs.webwork.rochester.edu/viewcvs.cgi/webwork2/lib/WeBWorK/ Authen.pm?rev=1.3&content-type=text/vnd.viewcvs-markup |