Browse Source

Should fix bug when reporting fill in blank, hotspot and matching see #5257

Julio Montoya 12 years ago
parent
commit
332fda3289

+ 180 - 12
main/exercice/exercise.lib.php

@@ -1630,7 +1630,7 @@ function get_number_students_question_with_answer_count($question_id, $exercise_
 	$exercise_id 		= intval($exercise_id);
 	$course_code 		= Database::escape_string($course_code);
 	$session_id 		= intval($session_id);
-   
+  
 
 	$sql = "SELECT DISTINCT exe_user_id
 			FROM $track_exercises e INNER JOIN $track_attempt a ON (a.exe_id = e.exe_id) INNER JOIN $course_user cu
@@ -1639,10 +1639,11 @@ function get_number_students_question_with_answer_count($question_id, $exercise_
 					a.course_code 	= '$course_code' AND
 					e.session_id 	= $session_id AND            
 					question_id 	= $question_id AND
-                    answer          <> 0 AND   
-                    cu.status          = ".STUDENT." AND 
-                    relation_type <> 2 AND
-                    e.status          = ''"; 
+                    answer          <> 0 AND 
+                    cu.status       = ".STUDENT." AND 
+                    relation_type  <> 2 AND
+                    e.status        = ''";
+    
 	$result = Database::query($sql);
 	$return = 0;
 	if ($result) {
@@ -1651,38 +1652,205 @@ function get_number_students_question_with_answer_count($question_id, $exercise_
 	return $return;
 }
 
-
-function get_number_students_answer_count($answer_id, $question_id,  $exercise_id, $course_code, $session_id) {
+function get_number_students_answer_hotspot_count($answer_id, $question_id,  $exercise_id, $course_code, $session_id) {
 	$track_exercises	= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
-	$track_attempt		= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+	$track_hotspot		= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
     $course_user        = Database::get_main_table(TABLE_MAIN_COURSE_USER);
 
 	$question_id 		= intval($question_id);
     $answer_id          = intval($answer_id);
 	$exercise_id 		= intval($exercise_id);
 	$course_code 		= Database::escape_string($course_code);
-	$session_id 		= intval($session_id);
+	$session_id 		= intval($session_id);    
 
 	$sql = "SELECT DISTINCT exe_user_id
+			FROM $track_exercises e INNER JOIN $track_hotspot a ON (a.hotspot_exe_id = e.exe_id) INNER JOIN $course_user cu
+                ON cu.course_code = a.hotspot_course_code AND cu.user_id  = exe_user_id
+			WHERE 	exe_exo_id              = $exercise_id AND
+					a.hotspot_course_code 	= '$course_code' AND
+					e.session_id            = $session_id AND
+                    hotspot_answer_id       = $answer_id AND                    
+					hotspot_question_id     = $question_id AND 
+                    cu.status               = ".STUDENT." AND
+                    hotspot_correct         =  1 AND
+                    relation_type           <> 2 AND
+                    e.status                = ''";
+    
+	$result = Database::query($sql);
+	$return = 0;
+	if ($result) {
+		$return = Database::num_rows($result);
+	}
+	return $return;
+}
+
+
+function get_number_students_answer_count($answer_id, $question_id, $exercise_id, $course_code, $session_id, $question_type = null, $answer = null, $fill_in_blank_answer = null) {
+	$track_exercises	= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
+	$track_attempt		= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+    $course_user        = Database::get_main_table(TABLE_MAIN_COURSE_USER);
+
+	$question_id 		= intval($question_id);
+    $answer_id          = intval($answer_id);
+	$exercise_id 		= intval($exercise_id);
+	$course_code 		= Database::escape_string($course_code);
+	$session_id 		= intval($session_id);    
+    
+    if ($question_type == FILL_IN_BLANKS) {
+        $answer_condition = "";
+        $select_condition = " e.exe_id, answer ";
+    } else {
+        $answer_condition = "answer       	= $answer_id AND ";
+        $select_condition = "DISTINCT exe_user_id";
+    }
+    
+	$sql = "SELECT $select_condition
 			FROM $track_exercises e INNER JOIN $track_attempt a ON (a.exe_id = e.exe_id) INNER JOIN $course_user cu
                 ON cu.course_code = a.course_code AND cu.user_id  = exe_user_id
 			WHERE 	exe_exo_id 		= $exercise_id AND
 					a.course_code 	= '$course_code' AND
 					e.session_id 	= $session_id AND
-                    answer       	= $answer_id AND                    
+                              
 					question_id 	= $question_id AND 
-                    cu.status        = ".STUDENT." AND 
+                    cu.status        = ".STUDENT." AND                     
                     relation_type <> 2 AND
                     e.status = ''";
+    
 	$result = Database::query($sql);
 	$return = 0;
 	if ($result) {
-		$return = Database::num_rows($result);
+        if ($question_type == FILL_IN_BLANKS) {
+            $good_answers = 0;            
+            while ($row = Database::fetch_array($result, 'ASSOC')) {   
+                $fill_blank = check_fill_in_blanks($answer, $row['answer']);                
+                if (isset($fill_blank[$fill_in_blank_answer]) && $fill_blank[$fill_in_blank_answer] == 1 ) {                    
+                    $good_answers++;
+                }
+            }
+            return $good_answers;
+        } else {
+            $return = Database::num_rows($result);
+        }
 	}
 	return $return;
 }
 
 
+function check_fill_in_blanks($answer, $user_answer) {    
+    // the question is encoded like this
+    // [A] B [C] D [E] F::10,10,10@1
+    // number 1 before the "@" means that is a switchable fill in blank question
+    // [A] B [C] D [E] F::10,10,10@ or  [A] B [C] D [E] F::10,10,10
+    // means that is a normal fill blank question
+    // first we explode the "::"
+    $pre_array = explode('::', $answer);
+    // is switchable fill blank or not
+    $last = count($pre_array) - 1;
+    $is_set_switchable = explode('@', $pre_array[$last]);
+    $switchable_answer_set = false;
+    if (isset ($is_set_switchable[1]) && $is_set_switchable[1] == 1) {
+        $switchable_answer_set = true;
+    }
+    $answer = '';
+    for ($k = 0; $k < $last; $k++) {
+        $answer .= $pre_array[$k];
+    }
+    // splits weightings that are joined with a comma
+    $answerWeighting = explode(',', $is_set_switchable[0]);
+
+    // we save the answer because it will be modified
+    //$temp = $answer;
+    $temp = $answer;
+
+    $answer = '';
+    $j = 0;
+    //initialise answer tags
+    $user_tags = $correct_tags = $real_text = array ();
+    // the loop will stop at the end of the text
+    while (1) {
+        // quits the loop if there are no more blanks (detect '[')
+        if (($pos = api_strpos($temp, '[')) === false) {
+            // adds the end of the text
+            $answer = $temp;
+            /* // Deprecated code
+             // TeX parsing - replacement of texcode tags
+            $texstring = api_parse_tex($texstring);
+            $answer = str_replace("{texcode}", $texstring, $answer);
+            */
+            $real_text[] = $answer;
+            break; //no more "blanks", quit the loop
+        }
+        // adds the piece of text that is before the blank
+        //and ends with '[' into a general storage array
+        $real_text[] = api_substr($temp, 0, $pos +1);
+        $answer .= api_substr($temp, 0, $pos +1);
+        //take the string remaining (after the last "[" we found)
+        $temp = api_substr($temp, $pos +1);
+        // quit the loop if there are no more blanks, and update $pos to the position of next ']'
+        if (($pos = api_strpos($temp, ']')) === false) {
+            // adds the end of the text
+            $answer .= $temp;
+            break;
+        }
+        
+        $str = $user_answer;
+
+        preg_match_all('#\[([^[]*)\]#', $str, $arr);
+        $str = str_replace('\r\n', '', $str);
+        $choice = $arr[1];
+
+        $tmp = api_strrpos($choice[$j],' / ');
+        $choice[$j] = api_substr($choice[$j],0,$tmp);
+        $choice[$j] = trim($choice[$j]);
+
+        //Needed to let characters ' and " to work as part of an answer
+        $choice[$j] = stripslashes($choice[$j]);
+
+        $user_tags[] = api_strtolower($choice[$j]);
+        //put the contents of the [] answer tag into correct_tags[]
+        $correct_tags[] = api_strtolower(api_substr($temp, 0, $pos));
+        $j++;
+        $temp = api_substr($temp, $pos +1);        
+    }
+    
+    $answer = '';
+    $real_correct_tags = $correct_tags;
+    $chosen_list = array();
+    
+    $good_answer = array();
+    
+    for ($i = 0; $i < count($real_correct_tags); $i++) {        
+        if (!$switchable_answer_set) {
+            //needed to parse ' and " characters
+            $user_tags[$i] = stripslashes($user_tags[$i]);
+            if ($correct_tags[$i] == $user_tags[$i]) {                    
+                $good_answer[$correct_tags[$i]] = 1;
+            } elseif (!empty ($user_tags[$i])) {                
+                $good_answer[$correct_tags[$i]] = 0;
+            } else {
+                $good_answer[$correct_tags[$i]] = 0;
+            }
+        } else {
+            // switchable fill in the blanks
+            if (in_array($user_tags[$i], $correct_tags)) {                
+                $correct_tags = array_diff($correct_tags, $chosen_list);
+                $good_answer[$correct_tags[$i]] = 1;
+            } elseif (!empty ($user_tags[$i])) {                
+                $good_answer[$correct_tags[$i]] = 0;
+            } else {                
+                $good_answer[$correct_tags[$i]] = 0;
+            }
+        }
+        // adds the correct word, followed by ] to close the blank
+        $answer .= ' / <font color="green"><b>' . $real_correct_tags[$i] . '</b></font>]';
+        if (isset ($real_text[$i +1])) {
+            $answer .= $real_text[$i +1];
+        }
+    }    
+    return $good_answer;    
+}
+
+
 function get_number_students_finish_exercise($exercise_id, $course_code, $session_id) {
 	$track_exercises	= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
 	$track_attempt		= Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);

+ 57 - 7
main/exercice/stats.php

@@ -104,14 +104,16 @@ if (!empty($question_list)) {
 		$answer_count = $answer->selectNbrAnswers();
         
         for ($answer_id = 1; $answer_id <= $answer_count; $answer_id++) {
-            $answer_info = $answer->selectAnswer($answer_id);
-            $is_correct  = $answer->isCorrect($answer_id);
+            $answer_info    = $answer->selectAnswer($answer_id);
+            $is_correct     = $answer->isCorrect($answer_id);
             $correct_answer = $is_correct == 1 ? get_lang('Yes') : get_lang('No');
+            $real_answer_id = $answer->selectAutoId($answer_id);
             
             //$data[$id]['name'] .=$answer_count;
             //Overwriting values depending of the question
             switch($question_obj->type) {
                 case FILL_IN_BLANKS :
+                    $answer_info_db = $answer_info;
                     $answer_info = substr($answer_info, 0, strpos($answer_info, '::'));
                     $correct_answer = $is_correct;                
                     $answers = $objExercise->fill_in_blank_answer_to_array($answer_info);
@@ -121,14 +123,62 @@ if (!empty($question_list)) {
                             $data[$id]['name']      = cut($question_obj->question, 100);
                         } else {
                             $data[$id]['name']      = '-';    
+                        
+                            
                         }
-                        $data[$id]['answer'] 	= $answer_item;
-                        $data[$id]['correct'] 	= get_lang('Yes');
-                        $data[$id]['attempts'] 	= '-';
+                        $data[$id]['answer'] 	= $answer_item; 
+                        
+                        $answer_item = api_substr($answer_item, 1);
+                        $answer_item = api_substr($answer_item, 0, api_strlen($answer_item) -1);
+                                                                      
+                        $data[$id]['correct'] 	= '-';
+                        
+                        $count = get_number_students_answer_count($real_answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id(), $question_obj->type, $answer_info_db, $answer_item);
+                        
+                        $percentange = $count/$count_students*100;
+                        $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);
+                    
                         $id++;
-                        $counter++;
+                        $counter++;                        
                     }
                     break;
+                case MATCHING:
+                    if ($is_correct == 0) {                   
+                        if ($answer_id == 1) {                
+                            $data[$id]['name']      = cut($question_obj->question, 100);
+                        } else {
+                            $data[$id]['name']      = '-';
+                        }
+                        
+                        $correct = '';
+                        for ($i = 1; $i <= $answer_count; $i++) {
+                             $is_correct_i     = $answer->isCorrect($i);
+                             if ($is_correct_i != 0 && $is_correct_i == $answer_id) {
+                                 $correct = $answer->selectAnswer($i);
+                             }
+                             
+                        }
+                        $data[$id]['answer'] 	= $answer_info;
+                        $data[$id]['correct'] 	= $correct;
+
+                        $count = get_number_students_answer_count($answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id(), $real_answer_id);                        
+                        $percentange = $count/$count_students*100;
+                        $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);
+                    }                    
+                    break;
+                case HOT_SPOT:
+                    if ($answer_id == 1) {                
+                        $data[$id]['name']      = cut($question_obj->question, 100);
+                    } else {
+                        $data[$id]['name']      = '-';
+                    }
+                    $data[$id]['answer'] 	= $answer_info;
+                    $data[$id]['correct'] 	= '-';
+                    
+                    $count = get_number_students_answer_hotspot_count($answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id());                    
+                    $percentange = $count/$count_students*100;
+                    $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);                    
+                    break;
                 default:
                     if ($answer_id == 1) {                
                         $data[$id]['name']      = cut($question_obj->question, 100);
@@ -137,7 +187,7 @@ if (!empty($question_list)) {
                     }
                     $data[$id]['answer'] 	= $answer_info;
                     $data[$id]['correct'] 	= $correct_answer;
-                    $real_answer_id         = $answer->selectAutoId($answer_id);            
+                    
                     $count = get_number_students_answer_count($real_answer_id, $question_id, $exercise_id, api_get_course_id(), api_get_session_id());
                     $percentange = $count/$count_students*100;
                     $data[$id]['attempts'] 	= Display::bar_progress($percentange, false, $count .' / '.$count_students);

+ 1 - 1
main/template/default/layout/menu.tpl

@@ -2,7 +2,7 @@
     
 <div class="navbar subnav">
     <div class="navbar-inner">
-        <div class="container">            
+        <div class="container">
             <a data-toggle="collapse" data-target=".nav-collapse" class="btn btn-navbar">                
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>

+ 1 - 6
main/template/default/layout/topbar.tpl

@@ -2,12 +2,7 @@
 {% if show_toolbar == 1 %}
     <div id="topbar" class="navbar navbar-fixed-top">
         <div class="navbar-inner">
-            <div class="container-fluid">
-                <a data-toggle="collapse" data-target=".nav-collapse" class="btn btn-navbar">
-                    <span class="icon-bar"></span>
-                    <span class="icon-bar"></span>
-                    <span class="icon-bar"></span>
-                </a>
+            <div class="container-fluid">              
                 <a class="brand" href="{{ _p.web }}">
                     {{ "siteName" | get_setting }}
                 </a>