Browse Source

Merge pull request #1020 from jloguercio/8077

Fix getFillTheBlankTabResult() and getNbResultFillBlankAll() is not defined - Refs #8077
Yannick Warnier 9 years ago
parent
commit
8156dea078
3 changed files with 200 additions and 19 deletions
  1. 122 0
      main/exercice/fill_blanks.class.php
  2. 5 12
      main/exercice/stats.php
  3. 73 7
      main/inc/lib/exercise.lib.php

+ 122 - 0
main/exercice/fill_blanks.class.php

@@ -727,6 +727,128 @@ class FillBlanks extends Question
 
         return $listAnswerResults;
     }
+    
+    /**
+    * Return an array of student state answers for fill the blank questions
+    * for each students that answered the question
+    * -2  : didn't answer
+    * -1  : student answer is wrong
+    *  0  : student answer is correct
+    * >0  : for fill the blank question with choice menu, is the index of the student answer (right answer indice is 0)
+    *
+    * @param $testId
+    * @param $questionId
+    * @param $studentsIdList
+    * @param $startDate
+    * @param $endDate
+    * @param bool $useLastAnswerredAttempt
+    * @return array
+    * (
+    *     [student_id] => Array
+    *         (
+    *             [first fill the blank for question] => -1
+    *             [second fill the blank for question] => 2
+    *             [third fill the blank for question] => -1
+    *         )
+    * )
+    */
+    public static function getFillTheBlankTabResult($testId, $questionId, $studentsIdList, $startDate, $endDate, $useLastAnswerredAttempt = true) {
+
+       $tblTrackEAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
+       $tblTrackEExercise = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
+       $courseId = api_get_course_int_id();
+
+       require_once api_get_path(SYS_PATH).'main/exercice/fill_blanks.class.php';
+
+       // request to have all the answers of student for this question
+       // student may have doing it several time
+       // student may have not answered the bracket id, in this case, is result of the answer is empty
+
+       // we got the less recent attempt first
+       $sql = '
+           SELECT * FROM '.$tblTrackEAttempt.' tea
+
+           LEFT JOIN '.$tblTrackEExercise.' tee
+           ON tee.exe_id = tea.exe_id
+           AND tea.c_id = '.$courseId.'
+           AND exe_exo_id = '.$testId.'
+
+           WHERE tee.c_id = '.$courseId.'
+           AND question_id = '.$questionId.'
+           AND tea.user_id IN ('.implode(',', $studentsIdList).')
+           AND tea.tms >= "'.$startDate.'"
+           AND tea.tms <= "'.$endDate.'"
+           ORDER BY user_id, tea.exe_id;
+       ';
+
+       $res = Database::query($sql);
+       $tabUserResult = array();
+       $bracketNumber = 0;
+       // foreach attempts for all students starting with his older attempt
+       while ($data = Database::fetch_array($res)) {
+           $tabAnswer = FillBlanks::getAnswerInfo($data['answer'], true);
+
+           // for each bracket to find in this question
+           foreach ($tabAnswer['studentanswer'] as $bracketNumber => $studentAnswer) {
+
+               if ($tabAnswer['studentanswer'][$bracketNumber] != '') {
+                   // student has answered this bracket, cool
+                   switch (FillBlanks::getFillTheBlankAnswerType($tabAnswer['tabwords'][$bracketNumber])) {
+                       case self::FILL_THE_BLANK_MENU :
+                           // get the indice of the choosen answer in the menu
+                           // we know that the right answer is the first entry of the menu, ie 0
+                           // (remember, menu entries are shuffled when taking the test)
+                           $tabUserResult[$data['user_id']][$bracketNumber] = FillBlanks::getFillTheBlankMenuAnswerNum($tabAnswer['tabwords'][$bracketNumber], $tabAnswer['studentanswer'][$bracketNumber]);
+                           break;
+                       default :
+                           if (FillBlanks::isGoodStudentAnswer($tabAnswer['studentanswer'][$bracketNumber], $tabAnswer['tabwords'][$bracketNumber])) {
+                               $tabUserResult[$data['user_id']][$bracketNumber] = 0;   //  right answer
+                           } else {
+                               $tabUserResult[$data['user_id']][$bracketNumber] = -1;  // wrong answer
+                           }
+                   }
+               } else {
+                   // student didn't answer this bracket
+                   if ($useLastAnswerredAttempt) {
+                       // if we take into account the last answered attempt
+                       if (!isset($tabUserResult[$data['user_id']][$bracketNumber])) {
+                           $tabUserResult[$data['user_id']][$bracketNumber] = -2;      // not answered
+                       }
+                   } else {
+                       // we take the last attempt, even if the student answer the question before
+                       $tabUserResult[$data['user_id']][$bracketNumber] = -2;      // not answered
+                   }
+               }
+           }
+
+
+       }
+       return $tabUserResult;
+    }
+
+
+
+    /**
+     * Return the number of student that give at leat an answer in the fill the blank test
+     * @param $resultList
+     * @return int
+     */
+    public static function getNbResultFillBlankAll($resultList)
+    {
+        $outRes = 0;
+        // for each student in group
+        foreach($resultList as $userId => $tabValue) {
+            $trouve = false;
+            // for each bracket, if student has at leat one answer ( choice > -2) then he pass the question
+            foreach($tabValue as $i => $choice) {
+                if ($choice > -2 && !$trouve) {
+                    $outRes++;
+                    $trouve = true;
+                }
+            }
+        }
+        return $outRes;
+    }
 
     /**
      * Replace the occurrence of blank word with [correct answer][student answer][answer is correct]

+ 5 - 12
main/exercice/stats.php

@@ -146,26 +146,19 @@ if (!empty($question_list)) {
 
                         $answer_item = api_substr($answer_item, 1);
                         $answer_item = api_substr($answer_item, 0, api_strlen($answer_item) -1);
+                        
+                        $data[$id]['answer'] 	= $answer_item;
 
                         $data[$id]['correct'] 	= '-';
 
-                        $count = ExerciseLib::get_number_students_answer_count(
-                            $real_answer_id,
-                            $question_id,
-                            $exercise_id,
-                            $courseCode,
-                            $sessionId,
-                            FILL_IN_BLANKS,
-                            $answer_info_db,
-                            $answer_item
-                        );
-
+                        $count = ExerciseLib::getNumberStudentsFillBlanksAnwserCount($question_id, $exercise_id);
+                        $count = $count[$counter];
+                        
                         $percentange = 0;
                         if (!empty($count_students)) {
                             $percentange = $count/$count_students*100;
                         }
                         $data[$id]['attempts'] = Display::bar_progress($percentange, false, $count .' / '.$count_students);
-
                         $id++;
                         $counter++;
                     }

+ 73 - 7
main/inc/lib/exercise.lib.php

@@ -2864,6 +2864,53 @@ HOTSPOT;
 
         return $return;
     }
+    
+    /**
+     * Get the correct answer count for a fill blanks question
+     * 
+     * @param int $question_id
+     * @param int $exercise_id
+     * @return int
+     */
+    public static function getNumberStudentsFillBlanksAnwserCount(
+        $question_id,
+        $exercise_id
+    ) {
+        $listStudentsId = [];
+            $listAllStudentInfo = CourseManager::get_student_list_from_course_code(
+                api_get_course_id(),
+                true
+            );
+            foreach ($listAllStudentInfo as $i => $listStudentInfo) {
+                $listStudentsId[] = $listStudentInfo['user_id'];
+            }
+
+            $listFillTheBlankResult = FillBlanks::getFillTheBlankTabResult(
+                $exercise_id,
+                $question_id,
+                $listStudentsId,
+                '1970-01-01',
+                '3000-01-01'
+            );
+
+            $arrayCount = [];
+
+            foreach ($listFillTheBlankResult as $resultCount) {
+                foreach ($resultCount as $index => $count) {
+                    //this is only for declare the array index per answer
+                    $arrayCount[$index] = 0;
+                }
+            }
+
+            foreach ($listFillTheBlankResult as $resultCount) {
+                foreach ($resultCount as $index => $count) {
+                    $count = ($count === 0) ? 1 : 0;
+                    $arrayCount[$index] += $count;
+                }
+            }
+            
+            return $arrayCount;
+    }
 
     /**
      * @param int $question_id
@@ -2907,7 +2954,7 @@ HOTSPOT;
                 $listStudentsId[] = $listStudentInfo['user_id'];
             }
 
-            $listFillTheBlankResult = getFillTheBlankTabResult(
+            $listFillTheBlankResult = FillBlanks::getFillTheBlankTabResult(
                 $exercise_id,
                 $question_id,
                 $listStudentsId,
@@ -2915,7 +2962,7 @@ HOTSPOT;
                 '3000-01-01'
             );
 
-            return getNbResultFillBlankAll($listFillTheBlankResult);
+            return FillBlanks::getNbResultFillBlankAll($listFillTheBlankResult);
         }
 
         if (empty($session_id)) {
@@ -3126,7 +3173,8 @@ HOTSPOT;
                     while ($row = Database::fetch_array($result, 'ASSOC')) {
                         $fill_blank = self::check_fill_in_blanks(
                             $correct_answer,
-                            $row['answer']
+                            $row['answer'],
+                            $current_answer
                         );
                         if (isset($fill_blank[$current_answer]) && $fill_blank[$current_answer] == 1) {
                             $good_answers++;
@@ -3151,7 +3199,7 @@ HOTSPOT;
      * @param string $user_answer
      * @return array
      */
-    public static function check_fill_in_blanks($answer, $user_answer)
+    public static function check_fill_in_blanks($answer, $user_answer, $current_answer)
     {
         // the question is encoded like this
         // [A] B [C] D [E] F::10,10,10@1
@@ -3208,10 +3256,28 @@ HOTSPOT;
 
             preg_match_all('#\[([^[]*)\]#', $str, $arr);
             $str = str_replace('\r\n', '', $str);
-            $choice = $arr[1];
-
+            $choices = $arr[1];
+            $choice = [];
+            $check = false;
+            $i = 0;
+            foreach ($choices as $item) {
+                if ($current_answer === $item) {
+                    $check = true;
+                }
+                if ($check) {
+                    $choice[] = $item;
+                    $i++;
+                }
+                if ($i == 3) {
+                    break;
+                }
+            }
             $tmp = api_strrpos($choice[$j], ' / ');
-            $choice[$j] = api_substr($choice[$j], 0, $tmp);
+            
+            if ($tmp !== false) {
+                $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