## Forum archive 2000-2006

### Nandor Sieben - evaluator swallowing more than one answer boxes

by Arnold Pizer -
Number of replies: 0
 evaluator swallowing more than one answer boxes topic started 6/29/2005; 10:27:48 PMlast post 7/4/2005; 6:54:02 PM
 Nandor Sieben - evaluator swallowing more than one answer boxes  6/29/2005; 10:27:48 PM (reads: 1548, responses: 11) How can I write an evaluator that eats up several answer boxes? I know that I could ask for a comma separated list rather than several answer boxes but this is a little inconvenient in the application we have in mind. I am not absolutely sure but I belive basis_cmp can do this. Unfortunately basis_cmp is a little complicated so I couldn't figure out how exactly this is done. If I understand it correctly ANS simply fills a list with evaluators. Then I think there must be another list containing as many elemnts as answer boxes. Then a function checks if these two lists have the same size and calls the evaluators one by one with the corresponding student answers. Is this correct? I'd like to somehow change this and have only 2 evaluators and 3 answers and call the second evaluator with the last 2 answers. Nandor <| Post or View Comments |>

 Davide P. Cervone - Re: evaluator swallowing more than one answer boxes  6/29/2005; 11:08:02 PM (reads: 1787, responses: 0) You might try the MultiPart object that is part of the new Parser. It allows you to have one answer checker that operates on more than one answer blank. See the discussion at for details. If you are really intent on writing your own, it is a bit complicated, but can be done. Davide <| Post or View Comments |>

 Edgar Fisher - Re: evaluator swallowing more than one answer boxes  7/3/2005; 7:46:59 PM (reads: 1771, responses: 0) What do you mean by "name the answer the blanks with the same name"? I have done this: ################################################sub Iso_build{ my($width) = @_; ans_rule($width);}################################################sub Iso_Eval{ my (%vals) = @_; sub { my @stud_in = @_; $score = 1;$message = ''; my $ans_hash = { score =>$score, correct_ans => '', student_ans => '', preview_latex_string => '', ans_message => ($score) ? '' :$message }; $ans_hash; }}################################################ I then call the function Iso_build twice and use ANS(Iso_Eval()) but it only evaluates one answer.... I tried looking at the other files listed, but don't see implementation of randomly named objects and subroutines. Only the previously defined ones. <| Post or View Comments |>  Michael Gage - Re: evaluator swallowing more than one answer boxes 7/3/2005; 9:49:51 PM (reads: 1777, responses: 0) What you are trying to do is a bit complicated and I don't have a simple model to point you to. If you haven't read Managing answers yet start there -- it gives an overview of most of the mechanism used to connect an answer blank with an answer evaluator. ans_rule, by itself, automatically increments the label for the answer blank (e.g. AnSwEr01, AnSwEr02) etc. so all of your answers above had individual answers. The next thing to look at is the description at PGbasicmacros.pl about answer blanks. I think the closest thing to what you want is the ANS_RADIO and ANS_RADIO_OPTION. There is also an ANS_CHECKBOX and ANS_CHECKBOX_OPTION, but you will need to read the actual code in PGbasicmacros.pl to see how that works. A model of how to evaluate these input vectors together is checkbox_cmp in PGanswermacros.pl (again you will have to read the code, the pod documentation is incomplete). This is not the best model, since it does not use an AnswerEvaluator which will do much of the work for you. It is however a place to start. (AnswerEvaluators are described in AnswerHash.pm) The linear algebra macros in PGmatrixmacros.pl and PGmorematrixmacros.pl handle more complicated situations. The examples in Davide Cervone's MultiPart.pm object are the most recent and the cleanest. Hope this helps. -- Mike <| Post or View Comments |>  Edgar Fisher - Re: evaluator swallowing more than one answer boxes 7/4/2005; 2:31:13 PM (reads: 1739, responses: 0) Ok, I now have a handle on how to call the evaluator with an array of answers. However, I was wondering about a couple of things. First, I tried the @{$in} stuff and it doesn't work. Instead I have to use @list = split "\0", @in[0], which the docs say is old hat. Also, is there any way to have each answer blank display only that value in the answer preview box? Along with that is whether there is a way to not change the value in the answer boxes. They all become the value of the first box because of this function call. I have looked in the files and not found where I can change that. I will continue to look, but need some help finding the right lines to look at. <| Post or View Comments |>
 Edgar Fisher - Re: evaluator swallowing more than one answer boxes  7/4/2005; 3:32:53 PM (reads: 1720, responses: 0) The context of the problem is given some graphs, find which are isomorphic and from those, what is a vertex correspondence between them. So I can't simply use a string compare because there is likely more than one correspondence, especially with random graphs. This is about as simple as I could make it and still retain the basic shape of the question and my problems. loadMacros("PGstandard.pl");TEXT(&beginproblem);$showPartialCorrectAnswers = 1;$size = random(6,7);$table = begintable($size);@letters = ('A'..'G');push @row1, "Original Vertices";push @row2, "Isomorphic Vertices";for ($i = 0;$i < $size;$i++){ push @row1, $letters[$i]; push @row2, NAMED_ANS_RULE('iso_ans', 1);}$table .= row(@row1);$table .= row(@row2);$table .= endtable();################################################sub Iso_Eval{ my ($graph) = @_; sub { my @stud_in = @_; @list = split "\0", @stud_in[0]; $score = 1;$message = 'Good'; $text = join ',', @list; my$ans_hash = { score => $score, correct_ans => '', student_ans =>$text, preview_latex_string => @list, ans_message => ($score) ? '' :$message }; $ans_hash; }}################################################BEGIN_TEXT$BRFrom the given graphs (omitted), list the vertex correspondence between themin the following table.$BR$table$BREND_TEXTNAMED_ANS("iso_ans", Iso_Eval(5));ENDDOCUMENT(); <| Post or View Comments |>  Michael Gage - Re: evaluator swallowing more than one answer boxes 7/4/2005; 6:06:34 PM (reads: 1726, responses: 1) # Here is an initial suggestion. This will allow you to check your graphs.# the handling of errors won't be ideal# I think you'll want to use ideas from PGmorematrixmacros.pl for that# remember to CHANGE ~~ to \ when moving subroutines to a .pl file!!!DOCUMENT();loadMacros( "PGstandard.pl",PGmorematrixmacros.pl,PGanswermacros.pl,);TEXT(beginproblem());$showPartialCorrectAnswers = 1;$size = random(6,7);$table = begintable($size);@letters = ('A'..'G');push @row1, "Original Vertices";push @row2, "Isomorphic Vertices";for ($i = 0; $i <$size; $i++){; push @row1,$letters[$i]; push @row2, NAMED_ANS_RULE('iso_ans', 1);};$table .= row(@row1);$table .= row(@row2);$table .= endtable();################################################sub Iso_Eval { my $graph = shift; # correct answer object # routines to handle options in standard ways my %options = @_; # standard methods for handling options # CHANGE ~~ to \ when moving to a macro .pl file!!!!! assign_option_aliases(~~%options, ); set_default_options(~~%options, 'debug' => 0, 'type' => 'Iso_Eval', ); my$answer_evaluator = new AnswerEvaluator( correct_ans => $graph, ); # initialize debug feature. debug=>1 prints out trace$answer_evaluator->{debug} = $options{debug}; # You can install pre_filters massage/normalize the student answers and correct answers #Here is the actual evaluation$answer_evaluator->install_pre_filter( sub { my $rh_ans = shift; # insert code to compare$rh_ans->{student_ans} and $rh_ans->{correct_ans}$rh_ans; # return answer hash }); # You can install post_filters to clean up error messages and so forth $answer_evaluator;}################################################BEGIN_TEXT$BRFrom the given graphs (omitted), list the vertex correspondence between themin the following table.$BR$table$BREND_TEXTNAMED_ANS("iso_ans"=> Iso_Eval(5) );ENDDOCUMENT(); <| Post or View Comments |>  Davide P. Cervone - Re: evaluator swallowing more than one answer boxes 7/4/2005; 6:44:12 PM (reads: 1994, responses: 0) OK, here is another approach, based on using WeBWorK's tools for this. It's not a completely happy solution, but my MultiPart object was supposed to be that. Anyhow, here it is.  DOCUMENT(); # This should be the first executable line in the problem. loadMacros( "PG.pl", "PGbasicmacros.pl", "PGanswermacros.pl", ); TEXT(&beginproblem); # # This will only work once in a problem (you would need to # keep track of the rule separately if you wanted multiple # sets of answers in a single problem). #$ruleCount = 0; sub extra_ans_rule {NAMED_ANS_RULE_EXTENSION(RECORD_FORM_LABEL("Part".(++$ruleCount)),@_)} sub myChecker { my @correct = @_; my$ans = new AnswerEvaluator; $ans->ans_hash( correct_ans => join(", ",@correct), # show all answers in one line type => "multiple answer", # or whatever you want );$ans->install_evaluator(sub { my $ans = shift; my @correct = @_; # # Collect student answers from$inputs_ref # my @student = ($ans->{student_ans}); foreach my$i (1..$ruleCount) { my$x = $inputs_ref->{"Part$i"}; $x = "" unless defined($x); push(@student,$x); } # # Check student's answers against professor's #$ans->score(1); my @latex = (); foreach my $i (0..$ruleCount) { $student[$i] =~ s/(^ +| +)//g; # trim leading and trailing spaces ### need to do error checking on student answers here ### $ans->score(0) if ($correct[$i] ne$student[$i]); if ($student[$i] eq "") {push(@latex,"\_\_");$student[$i] = "__ "} else {push(@latex,"{\rm$student[$i]}")} }$ans->{preview_latex_string} = join(", ",@latex); $ans->{student_ans} = join(", ",@student); return$ans; },@_); # don't do blank check (so if the first blank is empty, we still get called) $ans->install_pre_filter('erase'); return$ans; } BEGIN_TEXT Enter A and B: \{ans_rule(2)\}, \{extra_ans_rule(2)\} END_TEXT ANS(myChecker('A','B')); ENDDOCUMENT(); # This should be the last executable line in the problem.  The key parts to note are that NAMED_ANS_RULE_EXTENSION creates an answer rule that is not tied to an answer checker, and RECORD_FORM_LABEL makes its contents be retained by the WW database (so the student's answers for this blank will be recorded). The first rule is a normal one that gets associated with an answer checker, but the second (and potentially more) blanks are not. The first answer checker has to look up the values that have been entered by the student. This is done by accessing the $input_refs array reference. This sample doesn't do any error checking, but you would probably want to do that in the loop at the location indicated. Also, the check given here is just a straight string compare between the student and professor answers. Obviously, you would need to do whatever you need to do to check your graph. Note that the checker handles creation of the answer preview LaTeX string and combines the student (and correct) answers into a single string. Since the student answers are shown in a single row of the answer response area at the top of the page, the answers are separated by commas, and underscores are used to mark any blank entries to make them more visible. Finally, I have used an AnswerEvaluator object rather than pure code, to give you an example of how to do that. Hope that is clear. On the other hand, I still think the Parser's MultiPart object is a better choice for this. Here is another example, this time based on the MultiPart object. All the complexity of dealing with the answer rules, combining answers, looking up student answers, error checking and reporting, and so on, have been handled by the MultiPart. You just have to be concerned with the check you want to perform.  DOCUMENT(); # This should be the first executable line in the problem. loadMacros( "PG.pl", "PGbasicmacros.pl", "PGanswermacros.pl", "Parser.pl", "contextString.pl", "parserMultiPart.pl", ); TEXT(&beginproblem); Context("String")->strings->are( A => {caseSensitive=>1}, B => {caseSensitive=>1}, );$mp = MultiPart("A","B")->with( singleResult => 1, checker => sub { my ($correct,$student,$self) = @_; # get the parameters for my$i (0..scalar(@correct)-1) { return 0 if $correct->[$i] != $student->[$i]; } return 1; }, ); BEGIN_TEXT Enter A and B: \{$mp->ans_rule(2)\}, \{$mp->ans_rule(2)\} END_TEXT ANS(\$mp->cmp); ENDDOCUMENT(); # This should be the last executable line in the problem.  Here, we set up a string context for the labels that we want the student to enter. (You could use numbers as strings if you want.) The rest is pretty simple: just do whatever check you want to do in the checker routine. Hope one of these suits your needs. Davide <| Post or View Comments |>