--- loncom/publisher/testbankimport.pm 2006/04/06 19:31:03 1.8 +++ loncom/publisher/testbankimport.pm 2008/06/05 01:24:59 1.14 @@ -1,5 +1,5 @@ # Handler for parsing text upload problem descriptions into .problems -# $Id: testbankimport.pm,v 1.8 2006/04/06 19:31:03 albertel Exp $ +# $Id: testbankimport.pm,v 1.14 2008/06/05 01:24:59 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -35,6 +35,7 @@ use HTML::Entities(); use Apache::lonlocal; use Apache::lonupload; use File::Basename(); +use LONCAPA(); # ---------------------------------------------------------------- Display Control sub display_control { @@ -348,10 +349,16 @@ sub jscript_three { $source = $env{'form.go'}; } + my %body_layout = ('rightmargin' => "0", + 'leftmargin' => "0", + 'marginwidth' => "0", + 'topmargin' => "0", + 'marginheight' => "0"); + my $start_page = - &Apache::loncommon::start_page('Create IMS import directory',undef, + &Apache::loncommon::start_page('Create Testbank directory',undef, {'only_body' => 1, - 'add_entries' => "topmargin='0' leftmargin='0' marginheight='0'marginwidth='0' rightmargin='0'", + 'add_entries' => \%body_layout, 'js_ready' => 1,}); my $end_page = &Apache::loncommon::end_page({'js_ready' => 1,}); @@ -386,7 +393,7 @@ function createWin() { newWindow.document.write("

Location: $fullpath

New Directory

\\n") newWindow.document.write("  \\n") newWindow.document.write("
\\n") - newWindow.document.write("Enter the name of the new directory where you will store the converted testbank questions

") + newWindow.document.write("Enter the name of the new directory where you will save the converted testbank questions

") newWindow.document.write("") newWindow.document.write("") newWindow.document.write("") @@ -449,8 +456,8 @@ The Testbank Upload utility can b
  • All questions (including question text and all foils) must occur before any of the answers. Each question should begin on a new line, and should start with the question number. Questions should be numbered sequentially using a number followed immediately by a space, a period, or enclosed in parentheses, i.e., 1 , 1., (1), 1), or (1 .
  • Multiple choice and multiple answer correct questions should consist of: (i) the question number followed by (ii) the question text beginning on the same line and (iii) two or more foils, with each foil beginning on a new line and prefixed by a unique letter, or Roman numeral, listed in alphabetic or numeric order, beginning at a (alphabetic) or i (Roman numeral), followed by a period, or enclosed in parentheses, i.e., a., (a), i., or (i).
  • One or more correct answers should be provided for all questions (although blank answers may be provided for essay questions). Answers should be numbered sequentially, using the same scheme as used for the questions, and must occur after all the questions. -
  • If fill-in-the-blank or multiple answer questions have more than one correct answer, each answer should appear in a comma-, tab-, space-, or new line-delimited list. For a ranking/ordering question, the "answer" should contain the foil identifiers correctly ordered in a similarly delimited list.
  • - +
  • If fill-in-the-blank or multiple answer questions have more than one correct answer, each answer should appear in a comma-, tab-, space-, or new line-delimited list. For a ranking/ordering question, the "answer" should contain the foil identifiers correctly ordered in a similarly delimited list. If two or more foils have the same ranking, they should occur together, with an equals sign separating equally ranked foils [e.g., (b),(e)=(a),(d),(c)].
  • + Five steps are involved in the import process.
    1. Upload your text file to the server.|); @@ -463,7 +470,7 @@ Five steps are involved in the import pr $r->print(qq|
    2. Provide information about the question format - i.e., question numbering style, and the number of blocks of questions of each question type.
    3. Provide information about the questions in each block, including question type, start and end question numbers for each block, and foil labelling style and answer format where required.
    4. -
    5. Create a new directory where you will store the converted testbank questions.
    6. +
    7. Create a new directory where you will save the converted testbank questions.
    8. Complete the import of questions to the selected pool.
    @@ -1023,7 +1030,7 @@ END_OF_ONE    - Create a directory to store your testbank questions. + Create a directory to save your testbank questions. @@ -1033,7 +1040,7 @@ END_OF_ONE   -Please choose a destination LON-CAPA directory in which to store your uploaded questions.   +Please choose a destination LON-CAPA directory in which to save your uploaded questions.   @@ -1181,19 +1188,58 @@ sub final_display { $items[$k] =~ tr/A-Z/a-z/; my @corrects = split/$patterns{$ansrtypes[$i]}/,$items[$k]; foreach my $correct (@corrects) { - $correct =~s/\W//g; + my @tied; + if ($qtype[$i] eq "Ord") { + if ($correct =~ /=/) { + @tied = split(/=/,$correct); + for (my $j=0; $j<@tied; $j++) { + $tied[$j] =~ s/\W//g; + } + } else { + $correct =~s/\W//g; + } + } else { + $correct =~s/\W//g; + } if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod") { - for (my $j=0; $j<@alphabet; $j++) { - if ($alphabet[$j] eq $correct) { - push @{$answers{$k}}, $j; - last; + if (($qtype[$i] eq "Ord") && (@tied > 0)) { + my @ties; + foreach my $tie (@tied) { + for (my $j=0; $j<@alphabet; $j++) { + if ($alphabet[$j] eq $tie) { + push(@ties,$j); + last; + } + } + } + my $ans = join('=',@ties); + push(@{$answers{$k}},$ans); + } else { + for (my $j=0; $j<@alphabet; $j++) { + if ($alphabet[$j] eq $correct) { + push @{$answers{$k}}, $j; + last; + } } } } elsif (($foilformats[$i] eq "romparen") || ($foilformats[$i] eq "romperiod") || ($foilformats[$i] eq "romoneparen") || ($foilformats[$i] eq "romdotparen")) { - for (my $j=0; $j<@romans; $j++) { - if ($romans[$j] eq $correct) { - push @{$answers{$k}}, $j; - last; + if (($qtype[$i] eq "Ord") && (@tied > 0)) { + my @ties; + foreach my $tie (@tied) { + for (my $j=0; $j<@romans; $j++) { + if ($romans[$j] eq $tie) { + push(@ties,$j); + last; + } + } + } + push(@{$answers{$k}},join('=',@ties)); + } else { + for (my $j=0; $j<@romans; $j++) { + if ($romans[$j] eq $correct) { + push @{$answers{$k}}, $j; + last; + } } } } @@ -1444,7 +1490,7 @@ sub file_split { my %multparts = (); for (my $i=0; $i<$blocks; $i++) { if (${$numsref}[$i] > 0) { - if ((${$qtyperef}[$i] eq "MC") || (${$qtyperef}[$i] eq "MA")) { + if ((${$qtyperef}[$i] eq "MC") || (${$qtyperef}[$i] eq "MA") || (${$qtyperef}[$i] eq "Ord")) { my $splitstr = ''; if (${$foilsref}[$i] eq "lcperiod") { $splitstr = '[a-z]\.'; @@ -1561,7 +1607,26 @@ sub create_mcq { |; for (my $k=0; $k<@{$qstnref}-1; $k++) { - $output .= " ".${$qstnref}[$k+1]."\n"; + my $ansval; + my $num = 0; + for (my $i=0; $i<@{$answerref}; $i++) { + if ($$answerref[$i] =~ /=/) { + my @tied = split(/=/,$$answerref[$i]); + foreach my $tie (@tied) { + if ($k == $tie) { + $ansval = $num + 1; + last; + } + } + $num += scalar(@tied); + } elsif ($k == $$answerref[$i]) { + $ansval = $num + 1; + last; + } else { + $num ++; + } + } + $output .= " ".${$qstnref}[$k+1]."\n"; } chomp($output); $output .= qq| @@ -1659,7 +1724,9 @@ sub create_ess { + $answertxt + |; } elsif ($qtype eq "TF") { @@ -1705,7 +1772,6 @@ sub handler { my $javascript = ''; my $page_name = ''; my $current_page = ''; - my $loadentries = ''; my $qcount = ''; # # phase two: re-attach user @@ -1731,7 +1797,7 @@ sub handler { $fn=$env{'form.filename'}; $fn=~s/^http\:\/\/[^\/]+\///; $fn=~s/^\///; - $fn=~s/(\~|priv\/)(\w+)//; + $fn=~s{(~|priv/)($LONCAPA::username_re)}{}; $fn=~s/\/+/\//g; } else { $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}. @@ -1747,7 +1813,6 @@ sub handler { my $dirpath = '/home/'.$uname.'/public_html'; my @text = (); - my $loadentries = ''; if ($env{'form.phase'} eq 'three') { if (-e "$dirpath$fn") { open(TESTBANK,"<$dirpath$fn"); @@ -1762,20 +1827,21 @@ sub handler { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; + my %loadentries; if ($env{'form.phase'} eq 'three') { $current_page = &display_control(); my @PAGES = ('Welcome','Blocks','Format','Target','Confirmation'); $page_name = $PAGES[$current_page]; if ($page_name eq 'Blocks') { - $loadentries = 'onLoad= "setElements()"'; + $loadentries{'onload'} = "setElements()"; &jscript_one(\$javascript); } elsif ($page_name eq 'Format') { $qcount = question_count($env{'form.qnumformat'},\@text); &jscript_two(\$javascript,$qcount); } elsif ($page_name eq 'Target') { if ($env{'form.go'} eq "PreviousPage") { - $loadentries = 'onLoad = "setElements()"'; + $loadentries{'onload'} = "setElements()"; } &jscript_three($fullpath,\$javascript); } elsif ($page_name eq 'Confirmation') { @@ -1788,7 +1854,7 @@ sub handler { $r->print(&Apache::loncommon::start_page('Upload testbank questions to Construction Space', $javascript, - {'add_entries' => $loadentries})); + {'add_entries' => \%loadentries})); if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) { $r->print('

    '.&mt('Co-Author').': '.$uname.