From: Chris S. <san...@us...> - 2005-11-19 15:34:03
|
Update of /cvsroot/stack/stack-1-0/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20480/scripts Modified Files: stackCAS.php stackDatabase.php stackQuestion.php stackWin.php Log Message: Index: stackDatabase.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackDatabase.php,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** stackDatabase.php 27 Oct 2005 14:39:22 -0000 1.54 --- stackDatabase.php 19 Nov 2005 15:33:54 -0000 1.55 *************** *** 973,977 **** FROM questionAttempts WHERE questionID=$questionID AND questionSeedInst=$seed AND userID=$user ! ORDER BY TimeStamp"; $result= stack_db_query($query); --- 973,977 ---- FROM questionAttempts WHERE questionID=$questionID AND questionSeedInst=$seed AND userID=$user ! ORDER BY attemptID"; $result= stack_db_query($query); Index: stackCAS.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackCAS.php,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** stackCAS.php 17 Nov 2005 21:54:19 -0000 1.12 --- stackCAS.php 19 Nov 2005 15:33:54 -0000 1.13 *************** *** 8,71 **** /** - * Maxima-specific function used to produce the code - * to process a list of local variables. - * - * @param array $locvars List of local variables to be instantiated - * @param int $t Timestamp identifier used to match CAS input and output - * @param int $seed The random number generation seed - * @param array $options - * @return string The command to send to the CAS - */ - function CASCodeInstantiate($locvars, $t, $seed, $options) { - global $stackOptionsCAS; - // Generates Maxima specific code - // We will use a maxima block. - // block([v1,...,vk], state1,...statej) - - $loclistA = ''; - $loclistB = ''; - $loclistC = ''; - $cs ='cab:block([ random_seed'; - - // Now we will add options - foreach ($stackOptionsCAS as $optname => $opt) { - $optkey = $opt['CAS_KEY']; - switch ($opt['CAS_TYPE']) { - case 'string': - $loclistA.= ', '.$optkey; - $loclistC.= ', '.$optkey.':"'.$options[$optname].'"'; - break; - case 'ex': - $loclistA.= ', '.$optkey; - $loclistC.= ', '.$optkey.':'.$options[$optname]; - break; - case 'fun': - $loclistC.= ', '.$optkey.'('.$options[$optname].')'; - break; - } - } - - // We know $locvars is non-empty, as we have put $answer into it! - foreach ($locvars as $lk => $locv) { - $key = $locv['key']; - $val = str_replace('?','qmchar',$locv["value"]); - $loclistA.= ','.$key; - $loclistB.= ", print(\"$lk=[ error= [\"), cte(\"$key\",errcatch($key:$val)) "; - } - - $cs .= $loclistA.'], random_seed:'.$seed.$loclistC; - - $cs .= ", print(\"[TimeStamp= [ $t ], Locals= [ \") "; - $cs .= $loclistB; - - $cs .= ', print("] ]") '; - $cs .= ", return(true) ); \n"; - - //echo "<pre>".$cs."</pre>"; - return($cs); - } - - - /** * Maxima-specific function used to parse CAS output into an array. * --- 8,11 ---- *************** *** 150,171 **** return($unp); } ! /** ! * Maxima-specific function used to produce the CAS command ! * to apply a specific answer test. * ! * @param string $exp1 The first expression (nominally the student's answer) ! * @param string $exp2 The second expression (nominally the teacher's answer) ! * @param int $t Timestamp identifier used to match CAS input and output ! * @param string $display The desired output format (a Stack Option) ! * @param string $test The answer test to apply * @return string The command to send to the CAS */ ! function CASAnsTestCmd($exp1, $exp2, $t, $options, $test) { ! // Generates the CAS command to mark a question ! global $stackAnswerTest,$stackOptionsCAS; ! ! $exp1 = str_replace('?','qmchar',$exp1); ! $exp2 = str_replace('?','qmchar',$exp2); $loclistA = ''; --- 90,110 ---- return($unp); } ! ! /** ! * Maxima-specific function used to produce the code ! * to process a list of local variables. * ! * @param array $locvars List of local variables to be instantiated ! * @param int $t Timestamp identifier used to match CAS input and output ! * @param int $seed The random number generation seed ! * @param array $options * @return string The command to send to the CAS */ ! function CASCodeInstantiate($locvars, $t, $seed, $options) { ! global $stackOptionsCAS; ! // Generates Maxima specific code ! // We will use a maxima block. ! // block([v1,...,vk], state1,...statej) $loclistA = ''; *************** *** 191,265 **** } } - - $cas_cmd = "cab:block([ ans,str{$loclistA}] {$loclistC}, "; - $cas_cmd .= " simp:false, "; - $cas_cmd .= " print(\"[ Timestamp = [ $t ], Ans= [ error = [\"), cte(\"ans\",errcatch(ans:$exp1)),"; - $cas_cmd .= " print(\" ValidationError = [ \"), str:stack_validate(ans), print(str),"; - $cas_cmd .= " simp:".$options['Simplify'].", "; - $fname = $stackAnswerTest[$test]['function']; - $cas_cmd .= " print(\" AnswerTestError = [ \"), str:$fname(ans,$exp2), print(\" ], \"), print(str), return(true)); \n"; - - return $cas_cmd; - } - - - /** - * Maxima-specific function used to parse the CAS output from - * an answer test into an array. - * - * @param string $instr the raw CAS output - * @return array containing fields ['AnsValue'] and ['AnsDisplay'] - */ - function CASAnsTestParse($instr) { ! $unp = CASParsePreparse($instr); ! $unp['Ans'] = CASParsePreparse($unp['Ans']); ! ! if (''==$unp['Ans']['error']) { ! unset($unp['Ans']['error']); ! } ! ! if (array_key_exists('Valid',$unp)) { ! $unp['Valid'] = strtolower($unp['Valid']); ! } ! ! if ('false' == strtolower($unp['ValidationValid'])) { ! $unp['Valid'] = 'false'; ! $unp['AnswerNote'] = $unp['ValidationNote']; ! $unp['FeedBack'] = $unp['ValidationFeedBack']; ! } ! unset($unp['ValidationValid']); ! unset($unp['ValidationNote']); ! unset($unp['ValidationFeedBack']); ! ! if ('' != $unp['ValidationError']) { ! $unp['Valid'] = 'false'; ! $unp['AnswerNote'] = 'ValidationError'; ! $unp['Ans']['error'] = $unp['ValidationError']; ! } ! unset($unp['ValidationError']); ! unset($unp['AnswerTestError']); ! ! // Sort out translations of the feedback. ! if (array_key_exists('FeedBack',$unp)) { ! $strin = str_replace("\n","",$unp['FeedBack'] ); ! $strin = str_replace('\\','\\\\',$strin); ! $strin = str_replace('$','\$',$strin); ! $strin = str_replace("<QUOT>",'"',$strin); ! ! //echo "STRIN: <pre>$strin</pre><br>"; ! ob_start(); ! eval($strin); ! $strin = ob_get_contents(); ! ob_end_clean(); ! ! $unp['FeedBack'] = $strin; ! } ! return $unp; } ! /** --- 130,154 ---- } } ! // We know $locvars is non-empty, as we have put $answer into it! ! foreach ($locvars as $lk => $locv) { ! $key = $locv['key']; ! $val = str_replace('?','qmchar',$locv["value"]); ! $loclistA.= ','.$key; ! $loclistB.= ", print(\"$lk=[ error= [\"), cte(\"$key\",errcatch($key:$val)) "; ! } ! $cs .= $loclistA.'], random_seed:'.$seed.$loclistC; ! $cs .= ", print(\"[TimeStamp= [ $t ], Locals= [ \") "; ! $cs .= $loclistB; + $cs .= ', print("] ]") '; + $cs .= ", return(true) ); \n"; + + //echo "<pre>".$cs."</pre>"; + return($cs); } ! /** *************** *** 358,375 **** } /** ! * Directly perform an answer test * * @param string $exp1 A CAS expression, nominally the student's - * @param string $exp2 A CAS expression, nominally the teachers's - * @param string $test Which AnswerTest to apply. * @param array $options * @return array $this_attempt An array structure, which is used to build the student's attempt. */ ! function CPProcessAnsTest($exp1,$exp2,$test,$options,&$err) { // create a StackResponse object - $t = time(); ! $varCommand = CASAnsTestCmd($exp1, $exp2, $t, $options, $test); if ($varCommand != '') { --- 247,372 ---- } + + + /** + * Maxima-specific function used to validate the answer, + * and display the result. + * + * @param string $exp1 The first expression (nominally the student's answer) + * @param string $options + * @return string The command to send to the CAS + */ + function CAS_Validate_Ans_Expr($exp1, $options) { + // Generates the CAS command to mark a question + global $stackAnswerTest,$stackOptionsCAS; + + $exp1 = str_replace('?','qmchar',$exp1); + $exp2 = str_replace('?','qmchar',$exp2); + + $loclistA = ''; + $loclistB = ''; + $loclistC = ''; + $cs ='cab:block([ random_seed'; + + // Now we will add options + foreach ($stackOptionsCAS as $optname => $opt) { + $optkey = $opt['CAS_KEY']; + switch ($opt['CAS_TYPE']) { + case 'string': + $loclistA.= ', '.$optkey; + $loclistC.= ', '.$optkey.':"'.$options[$optname].'"'; + break; + case 'ex': + $loclistA.= ', '.$optkey; + $loclistC.= ', '.$optkey.':'.$options[$optname]; + break; + case 'fun': + $loclistC.= ', '.$optkey.'('.$options[$optname].')'; + break; + } + } + + // Ensure that the student's answer is not automatically simplified + + $cas_cmd .= " cab:block([ ans,str{$loclistA}] {$loclistC}, "; + $cas_cmd .= " simp:false, "; + $cas_cmd .= " print(\"[ Timestamp = [ 0 ], Ans= [ error = [\"), cte(\"ans\",errcatch(ans:$exp1)),"; + $cas_cmd .= " print(\" ValidationError = [ \"), str:stack_validate(ans), print(str),"; + $cas_cmd .= " print(\" ], \"), print(str), return(true)); \n"; + + //echo "<pre>".$cas_cmd."</pre>"; + return $cas_cmd; + } + + + /** + * Maxima-specific function used to parse the CAS output from + * the validation call into an array. + * + * @param string $instr the raw CAS output + * @return array containing fields + */ + function CAS_Validate_Ans_Parse($instr) { + + $unp = CASParsePreparse($instr); + $unp['Ans'] = CASParsePreparse($unp['Ans']); + + if (''==$unp['Ans']['error']) { + unset($unp['Ans']['error']); + } + + if (array_key_exists('Valid',$unp)) { + $unp['Valid'] = strtolower($unp['Valid']); + } + + if ('false' == strtolower($unp['ValidationValid'])) { + $unp['Valid'] = 'false'; + $unp['AnswerNote'] = $unp['ValidationNote']; + $unp['FeedBack'] = $unp['ValidationFeedBack']; + } + unset($unp['ValidationValid']); + unset($unp['ValidationNote']); + unset($unp['ValidationFeedBack']); + + if ('' != $unp['ValidationError']) { + $unp['Valid'] = 'false'; + $unp['AnswerNote'] .= ' ValidationError'; + $unp['Ans']['error'] = $unp['ValidationError']; + } + unset($unp['ValidationError']); + unset($unp['AnswerTestError']); + + // Sort out translations of the feedback. + if (array_key_exists('FeedBack',$unp)) { + $strin = str_replace("\n","",$unp['FeedBack'] ); + $strin = str_replace('\\','\\\\',$strin); + $strin = str_replace('$','\$',$strin); + $strin = str_replace("<QUOT>",'"',$strin); + + //echo "STRIN: <pre>$strin</pre><br>"; + + ob_start(); + eval($strin); + $strin = ob_get_contents(); + ob_end_clean(); + + $unp['FeedBack'] = $strin; + } + + + return $unp; + } + /** ! * Directly validate an expression using the CAS * * @param string $exp1 A CAS expression, nominally the student's * @param array $options * @return array $this_attempt An array structure, which is used to build the student's attempt. */ ! function CAS_Validate_Ans($exp1,$options) { // create a StackResponse object ! $varCommand = CAS_Validate_Ans_Expr($exp1, $options); if ($varCommand != '') { *************** *** 380,391 **** $varResponse = strstr($varResponse,"[ Timestamp"); ! $parsed = CASAnsTestParse($varResponse); ! //show_array($parsed); ! ! // If we have errors, we need to add blank fields. ! if (!array_key_exists('AnswerNote',$parsed)) { ! $parsed['AnswerNote'] = ''; ! } ! if (!array_key_exists('FeedBack',$parsed)) { $parsed['FeedBack'] = ''; --- 377,383 ---- $varResponse = strstr($varResponse,"[ Timestamp"); ! $parsed = CAS_Validate_Ans_Parse($varResponse); ! unset($parsed['Timestamp']); ! if (!array_key_exists('FeedBack',$parsed)) { $parsed['FeedBack'] = ''; *************** *** 408,411 **** --- 400,533 ---- } } + + return $parsed; + + } + + + + /** + * Maxima-specific function used to produce the CAS command + * to apply a specific answer test. + * + * @param string $exp1 The first expression (nominally the student's answer) + * @param string $exp2 The second expression (nominally the teacher's answer) + * @param int $t Timestamp identifier used to match CAS input and output + * @param string $display The desired output format (a Stack Option) + * @param string $test The answer test to apply + * @return string The command to send to the CAS + */ + function CASAnsTestCmd($exp1, $exp2, $t, $options, $test) { + // Generates the CAS command to mark a question + global $stackAnswerTest,$stackOptionsCAS; + + $exp1 = str_replace('?','qmchar',$exp1); + $exp2 = str_replace('?','qmchar',$exp2); + + $loclistA = ''; + $loclistB = ''; + $loclistC = ''; + $cs ='cab:block([ random_seed'; + + // Now we will add options + foreach ($stackOptionsCAS as $optname => $opt) { + $optkey = $opt['CAS_KEY']; + switch ($opt['CAS_TYPE']) { + case 'string': + $loclistA.= ', '.$optkey; + $loclistC.= ', '.$optkey.':"'.$options[$optname].'"'; + break; + case 'ex': + $loclistA.= ', '.$optkey; + $loclistC.= ', '.$optkey.':'.$options[$optname]; + break; + case 'fun': + $loclistC.= ', '.$optkey.'('.$options[$optname].')'; + break; + } + } + + $cas_cmd = "cab:block([ ans,str{$loclistA}] {$loclistC}, "; + $cas_cmd .= " print(\"[ Timestamp = [ $t ], Ans= [ error = [\"), cte(\"ans\",errcatch(ans:$exp1)),"; + $fname = $stackAnswerTest[$test]['function']; + $cas_cmd .= " print(\" AnswerTestError = [ \"), str:$fname(ans,$exp2), print(\" ], \"), print(str), return(true)); \n"; + + //echo "<pre>".$cas_cmd."</pre>"; + return $cas_cmd; + } + + + /** + * Maxima-specific function used to parse the CAS output from + * an answer test into an array. + * + * @param string $instr the raw CAS output + * @return array containing fields ['AnsValue'] and ['AnsDisplay'] + */ + function CASAnsTestParse($instr) { + + $unp = CASParsePreparse($instr); + $unp['Ans'] = CASParsePreparse($unp['Ans']); + + if (''==$unp['Ans']['error']) { + unset($unp['Ans']['error']); + } + + if (''!=$unp['AnswerTestError']) { + $unp['Ans']['error']=$unp['AnswerTestError']; + } + unset($unp['AnswerTestError']); + + if (array_key_exists('Valid',$unp)) { + $unp['Valid'] = strtolower($unp['Valid']); + } + + // Sort out translations of the feedback. + if (array_key_exists('FeedBack',$unp)) { + $strin = str_replace("\n","",$unp['FeedBack'] ); + $strin = str_replace('\\','\\\\',$strin); + $strin = str_replace('$','\$',$strin); + $strin = str_replace("<QUOT>",'"',$strin); + + //echo "STRIN: <pre>$strin</pre><br>"; + + ob_start(); + eval($strin); + $strin = ob_get_contents(); + ob_end_clean(); + + $unp['FeedBack'] = $strin; + } + + return $unp; + + } + + + /** + * Directly perform an answer test + * + * @param string $exp1 A CAS expression, nominally the student's + * @param string $exp2 A CAS expression, nominally the teachers's + * @param string $test Which AnswerTest to apply. + * @param array $options + * @return array $this_attempt An array structure, which is used to build the student's attempt. + */ + function CPProcessAnsTest($exp1,$exp2,$test,$options,&$err) { + // create a StackResponse object + $t = time(); + + $varCommand = CASAnsTestCmd($exp1, $exp2, $t, $options, $test); + + if ($varCommand != '') { + // send to CAS + $varResponse = stack_maxima_rawsend($varCommand); + + // Chop off the part up till the first input group. + $varResponse = strstr($varResponse,"[ Timestamp"); + + $parsed = CASAnsTestParse($varResponse); + //show_array($parsed); + } return $parsed; Index: stackWin.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackWin.php,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** stackWin.php 17 Nov 2005 21:54:19 -0000 1.14 --- stackWin.php 19 Nov 2005 15:33:54 -0000 1.15 *************** *** 122,126 **** if ($debug) { echo "<b>Input</b> <pre>$strin</pre>"; ! echo '<pre>'; }; while (!feof($pipes[1]) and $continue) { $out = fgets($pipes[1], 1024); --- 122,126 ---- if ($debug) { echo "<b>Input</b> <pre>$strin</pre>"; ! echo "<b>Output</b> <pre>"; }; while (!feof($pipes[1]) and $continue) { $out = fgets($pipes[1], 1024); *************** *** 132,143 **** if ($debug) { echo $out; } $now = stack_microtime_float(); - // if (($now-$start_time) > 0.3) { - // // CTRL+C should be ASCII 3. - // //fwrite($pipes[0], chr(3)); - // $continue = FALSE; - // echo "STOP!"; - // fwrite($pipes[0], chr(27)."[13~"); - // fflush($pipes[0]); - // } } fclose($pipes[0]); --- 132,135 ---- Index: stackQuestion.php =================================================================== RCS file: /cvsroot/stack/stack-1-0/scripts/stackQuestion.php,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** stackQuestion.php 17 Nov 2005 21:54:19 -0000 1.51 --- stackQuestion.php 19 Nov 2005 15:33:54 -0000 1.52 *************** *** 47,51 **** $stackOptions['AllowInputTool']['type'] = 'list'; $stackOptions['AllowInputTool']['values'] = array('Form box','Form box + JOME'); ! $stackOptions['AllowInputTool']['default'] = 'Form box + JOME'; // 'Syntax Hint'; --- 47,51 ---- $stackOptions['AllowInputTool']['type'] = 'list'; $stackOptions['AllowInputTool']['values'] = array('Form box','Form box + JOME'); ! $stackOptions['AllowInputTool']['default'] = 'Form box'; // 'Syntax Hint'; *************** *** 64,68 **** $stackOptions['MultiplicationSign']['type'] = 'list'; $stackOptions['MultiplicationSign']['values'] = array('(none)','cross','dot'); ! $stackOptions['MultiplicationSign']['default'] = '(none)'; $stackOptions['MultiplicationSign']['CAS_KEY'] = 'make_multsgn'; $stackOptions['MultiplicationSign']['CAS_TYPE'] = 'fun'; --- 64,68 ---- $stackOptions['MultiplicationSign']['type'] = 'list'; $stackOptions['MultiplicationSign']['values'] = array('(none)','cross','dot'); ! $stackOptions['MultiplicationSign']['default'] = 'dot'; $stackOptions['MultiplicationSign']['CAS_KEY'] = 'make_multsgn'; $stackOptions['MultiplicationSign']['CAS_TYPE'] = 'fun'; *************** *** 1567,1571 **** $this_attempt['RawAns'] = ''; $this_attempt['RawMark'] = 0; ! $this_attempt['Penalty'] = 0; $this_attempt['Valid'] = 'true'; $this_attempt['AnswerNote'] = ''; --- 1567,1571 ---- $this_attempt['RawAns'] = ''; $this_attempt['RawMark'] = 0; ! $this_attempt['Penalty'] = NULL; $this_attempt['Valid'] = 'true'; $this_attempt['AnswerNote'] = ''; *************** *** 1628,1631 **** --- 1628,1643 ---- } + + // Now send the RawAns to the CAS to validate and display it. + if ('true' === $this_attempt['Valid']) { + + $valid_attempt = CAS_Validate_Ans($RawAns,$options); + if (is_array($valid_attempt)) { + $this_attempt=array_merge($this_attempt,$valid_attempt); + } + + } + + show_array($this_attempt); return $this_attempt; } *************** *** 1730,1742 **** } - // (3.4) Start to build $this_attempt - - $this_attempt['Ans'] = $all_locs_Inst[$anstrack0]; - $this_attempt['RawMark'] = 0; - $this_attempt['Penalty'] = NULL; - $this_attempt['FeedBack'] = ''; - $this_attempt['AnswerNote'] = ''; - $this_attempt['RawAns'] = $RawAns; - if (array_key_exists('error',$this_attempt['Ans'])) { if ( '' == trim($this_attempt['Ans']['error']) ) { --- 1742,1745 ---- *************** *** 1808,1812 **** // Add any penalty if (array_key_exists('Penalty',$potresp[$branch])) { ! $this_attempt['Penalty'] += $potresp[$branch]['Penalty']; } // If there is no penalty set, we use the default, *AT THE END* --- 1811,1815 ---- // Add any penalty if (array_key_exists('Penalty',$potresp[$branch])) { ! $this_attempt['Penalty'] = $potresp[$branch]['Penalty']; } // If there is no penalty set, we use the default, *AT THE END* *************** *** 1862,1866 **** } ! $this_attempt = array_merge($this_attempt,stack_apply_answertest($RawAns,$CorrectAns,$at,$ato,$options,$errors)); $this_attempt['RawAns']= $RawAns; --- 1865,1871 ---- } ! $this_prattempt = stack_apply_answertest($RawAns,$CorrectAns,$at,$ato,$options,$errors); ! unset($this_prattempt['Ans']); ! $this_attempt = array_merge($this_attempt,$this_prattempt); $this_attempt['RawAns']= $RawAns; |