예제 #1
0
 function parseFile($basename)
 {
     $notify = $this->delegate;
     $notify("Parsing file: {$basename} <br/>\nConcepts: ");
     // Begin Processing
     $vQuestion = new Model_Shell_GenericQuestion($this->path . '/' . $basename);
     // Add to questionBase (if not already there)
     $vQuestionBase = Model_Quiz_QuestionBase::fromXml($basename);
     if ($vQuestionBase == null) {
         $vQuestionBase = Model_Quiz_QuestionBase::fromScratch($basename, $vQuestion->getDifficulty(), $vQuestion->getEstimatedTime(), $vQuestion->getFriendlyType(), strtotime("today"));
     }
     // Now look at the concepts
     $vConcepts = $vQuestion->getConcepts();
     foreach ($vConcepts as $vConcept) {
         // Make sure this concept exists in the database
         $vConceptObj = Model_Quiz_Concept::fromID($vConcept);
         if ($vConceptObj == null) {
             // Doesn't exist... we should make a record
             $vConceptObj = Model_Quiz_Concept::fromScratch($vConcept);
         }
         $notify($vConcept . "; ");
         // Now we need to make sure that this question has this concept associated with it
         $vQuestionBase->addConcept($vConceptObj);
     }
     // Update the questionBase's Difficulty & EstimatedTime (these are the things most likely to change)
     $vQuestionBase->setDifficulty($vQuestion->getDifficulty());
     $vQuestionBase->setEstimated_time($vQuestion->getEstimatedTime());
     $notify("<br/>Difficulty: " . $vQuestion->getDifficulty());
     $notify("<br/>Estimated time to complete: " . $vQuestion->getEstimatedTime());
     $notify("<br/><br/>\n");
 }
예제 #2
0
 /**
  * Generates a bank of questions for a question identifier provided
  * Expects parameters [question_id], [questions_to_generate_num], [max_errors_num]
  */
 public function generatequestionbankAction()
 {
     // Check to see that all the parameters get passed
     $parameters = $this->_getAllParams();
     $check_errors = array();
     foreach (array("question_id" => "Question Identifier", "questions_to_generate_num" => "Number of Questions to Generate", "max_errors_num" => "Maximum number of Errors") as $check_key => $check_text) {
         if (!array_key_exists($check_key, $parameters) || !is_numeric($parameters[$check_key]) || $parameters[$check_key] < 0) {
             $check_errors[] = $check_text . " [" . $check_key . "] was not passed, or not a positive number.";
         }
     }
     if (sizeof($check_errors) > 0) {
         cronlog("The following validation errors occured:");
         foreach ($check_errors as $ce) {
             cronlog($ce);
         }
         exit;
     }
     //cronlog('ok so far');
     $question_base_id = intval($parameters['question_id']);
     $number_of_questions = intval($parameters['questions_to_generate_num']);
     $maximum_errors = intval($parameters['max_errors_num']);
     cronlog("Generating {$number_of_questions} questions from Question Base Identifier {$question_base_id} ; Maximum Error threshold is {$maximum_errors}");
     $vQuestionBase = Model_Quiz_QuestionBase::fromID($question_base_id);
     if (is_null($vQuestionBase)) {
         throw new Exception("The question base identifier passed was invalid");
     }
     $question_counter = 0;
     $error_counter = 0;
     My_Logger::log(__METHOD__ . " number_of_questions: {$number_of_questions}");
     My_Logger::log(__METHOD__ . " maximum_errors: {$maximum_errors}");
     while ($question_counter <= $number_of_questions && $error_counter <= $maximum_errors) {
         My_Logger::log(__METHOD__ . " question_counter: {$question_counter}");
         My_Logger::log(__METHOD__ . " error_counter: {$error_counter}");
         try {
             $vGeneratedQuestion = Model_Quiz_GeneratedQuestion::generateNewFromQuestionBase($vQuestionBase);
         } catch (Exception $e) {
             cronlog("Could not generate question. " . $e->getMessage());
             echo Model_Shell_Debug::getInstance()->getLog();
             $error_counter++;
         }
     }
     cronlog("Finished. Generated " . $question_counter . " questions; " . $error_counter . " errornous questions generated (but discarded)");
 }
예제 #3
0
 public static function getAll()
 {
     $db = Zend_Registry::get("db");
     $vReturn = array();
     $result = $db->query("SELECT * FROM question_base");
     $rows = $result->fetchAll();
     foreach ($rows as $row) {
         $vReturn[] = Model_Quiz_QuestionBase::fromID($row['question_id']);
     }
     return $vReturn;
 }
예제 #4
0
 public static function select_next_question_2($vQuizAttempt, $vConcept, $vDifficulty)
 {
     //Firstly get ALL the questionBase's with this difficulty & concept
     $vPossibleQuestions = Model_Quiz_QuestionBase::getAllFromConceptAndDifficulty($vConcept, $vDifficulty);
     //Shuffle it to make it a little random
     shuffle($vPossibleQuestions);
     //print_r($vPossibleQuestions);
     //Now get all the questions the STUDENT has done...
     $vAttemptedQuestions = $vQuizAttempt->getAttemptedQuestionBases($vConcept, $vDifficulty);
     //print_r($vAttemptedQuestions);
     //There's the chance that we haven't had a questionbase asked.
     foreach ($vPossibleQuestions as $vPQ) {
         $vUsed = false;
         foreach ($vAttemptedQuestions as $vAQ) {
             if ($vPQ->getID() == $vAQ->getID()) {
                 $vUsed = true;
                 break;
             }
         }
         if (!$vUsed) {
             return $vPQ;
         }
     }
     //OK. So it turns out that we've used all questions. Pick a random one
     $vTemp = rand(0, sizeof($vPossibleQuestions) - 1);
     return $vPossibleQuestions[$vTemp];
 }
예제 #5
0
 /**
  * Shows the Question Analysis
  */
 public function questionanalysisAction()
 {
     $file_id = $this->_getParam("file");
     $this->view->file = $file_id;
     // Pointless line to load all the other functions in the GeneratedQuestion File
     // TODO: Fix this PLEASE
     $tmp = new Model_Quiz_GeneratedQuestion();
     // Get All Question Bases
     $this->view->all_question_bases = Model_Quiz_QuestionBase::getAll();
     if (is_null($file_id) || !isset($file_id)) {
         $default_question_base = current($this->view->all_question_bases);
         $file_id = $default_question_base->getID();
     }
     if (!is_null($file_id) && isset($file_id)) {
         $question_base = Model_Quiz_QuestionBase::fromID($file_id);
         $attempts = Model_Quiz_QuestionAttempt::getAllFromQuestionBase($question_base);
         // Generate a sample question
         $config = new Zend_Config_Ini(APPLICATION_PATH . "/configs/application.ini", APPLICATION_ENV);
         $path = $config->xml->import_path;
         //$sample_question = new Model_Shell_GenericQuestion(APPLICATION_PATH . "/../xml/questions/" . $question_base->getXml());
         $sample_question = new Model_Shell_GenericQuestion($path . '/' . $question_base->getXml());
         $this->view->question_base = $question_base;
         $this->view->attempts = $attempts;
         $this->view->sample_question = $sample_question;
     }
 }
 /**
  * Gets all Question attempts for a given question
  *
  * @param string $vQB 
  * @return void
  * @author Ben Evans
  */
 public static function getAllFromQuestionBase(Model_Quiz_QuestionBase $vQB)
 {
     $db = Zend_Registry::get("db");
     $vReturn = array();
     $sql = "SELECT attempt_id FROM question_attempt WHERE question_basequestion_id=" . $db->quote($vQB->getID());
     //echo $sql;
     $result = $db->query($sql);
     $rows = $result->fetchAll();
     foreach ($rows as $row) {
         $vReturn[] = Model_Quiz_QuestionAttempt::fromID($row['attempt_id']);
     }
     return $vReturn;
 }
예제 #7
0
 /**
  * This will generate a brand new question from a question base.
  * Unlike fromQuestionBase(), this method will NOT consult the database for question first
  * @param Model_Quiz_QuestionBase $vQuestionBase
  * @return Model_Quiz_GeneratedQuestion
  */
 public static function generateNewFromQuestionBase(Model_Quiz_QuestionBase $vQuestionBase, $path = false)
 {
     /*
     	    $path = "/../xml/questions/";
     	    $path = "/../tests/fixtures/";*/
     if (!$path) {
         $config = new Zend_Config_Ini(APPLICATION_PATH . "/configs/application.ini", APPLICATION_ENV);
         $path = $config->xml->import_path;
     }
     My_Logger::log(__METHOD__ . " Using path: {$path}");
     $vGenerated = null;
     $error_threshold = 4;
     $error_counter = 0;
     while ($error_counter <= $error_threshold && is_null($vGenerated)) {
         // Start by ensuring the Question is has instructions outputs etc etc
         $vQuestion = new Model_Shell_GenericQuestion($path . '/' . $vQuestionBase->getXml());
         $problem_string = $vQuestion->getProblem();
         $question_output = $vQuestion->getCorrectOutput();
         // We need to make sure that the question has valid output
         if (strlen(trim($question_output)) > 0) {
             // If the question is multiple choice, we need to ensure that all answers are different
             $alternate_answers = $vQuestion->getAnswers();
             if (!is_null($alternate_answers) && sizeof($alternate_answers) > 0) {
                 shuffle($alternate_answers);
                 // Now, we need to ensure that we have 3 different answers that are ALL different to the actual answer
                 $answer_set = array(trim($question_output));
                 // Value is the answer
                 foreach ($alternate_answers as $aa_key => $alternate_answer) {
                     if (is_array($alternate_answer)) {
                         $alternate_answer = $alternate_answer[0];
                     }
                     $alternate_answer = trim($alternate_answer);
                     if (in_array($alternate_answer, $answer_set) || strlen(trim($alternate_answer)) == 0) {
                         unset($alternate_answers[$aa_key]);
                         // Answer already exists, or is blank (unusable)
                     } else {
                         $answer_set[] = $alternate_answer;
                     }
                 }
                 if (sizeof($alternate_answers) >= 3) {
                     // All is good. We can add this question, as well as all its alternate answers
                     $vGenerated = Model_Quiz_GeneratedQuestion::fromScratch($vQuestion->getInstructions(), $vQuestion->getProblem(), $vQuestion->getCorrectOutput(), $vQuestionBase);
                     $vNum = 1;
                     foreach ($alternate_answers as $vAltAnswer) {
                         if ($vNum > 3) {
                             break;
                             //Can't have more than 3 alternates
                         }
                         if (is_array($vAltAnswer)) {
                             $vGenerated->addAlternateAnswer($vNum, $vAltAnswer[0], $vAltAnswer[1]);
                         } else {
                             $vGenerated->addAlternateAnswer($vNum, $vAltAnswer, "");
                         }
                         $vNum++;
                     }
                 } else {
                     $error_counter++;
                 }
             } else {
                 // Not a multiple choice question
                 $vGenerated = Model_Quiz_GeneratedQuestion::fromScratch($vQuestion->getInstructions(), $vQuestion->getProblem(), $vQuestion->getCorrectOutput(), $vQuestionBase);
             }
         } else {
             $error_counter++;
             // The question didn't return a result
         }
     }
     if (is_null($vGenerated)) {
         throw new Exception("Attempted to generate a question " . $error_threshold . "  times, but failed. Cannot continue");
     }
     //If the question is a fill-in question, put the whole solution in the 1st alternate answer column
     if ($vQuestion->getFriendlyType() == "fill-in") {
         $vGenerated->setAlt_desc_1($vQuestion->getDebugProblem());
     }
     return $vGenerated;
 }
예제 #8
0
 public function getAttemptedQuestionBases($vConcept, $vDifficulty)
 {
     $db = Zend_Registry::get("db");
     $vReturn = array();
     $sql = "SELECT DISTINCT qb.question_id FROM question_attempt qa, question_base qb, question_concepts qc WHERE qc.conceptsconcept_name=" . $db->quote($vConcept->getID()) . " AND qb.difficulty=" . $db->quote($vDifficulty) . " AND qa.question_basequestion_id=qb.question_id AND qc.question_basequestion_id=qb.question_id AND qa.quiz_attemptquiz_attempt_id=" . $db->quote($this->quiz_attempt_id);
     //echo $sql;
     $result = $db->query($sql);
     $rows = $result->fetchAll();
     foreach ($rows as $row) {
         $vReturn[] = Model_Quiz_QuestionBase::fromID($row['question_id']);
     }
     return $vReturn;
 }
 /**
  * This function rebuilds XML files
  * In doing so, all pre-generated questions will be removed.
  */
 public function rebuildxmlAction()
 {
     $process = $this->_getParam("process");
     if (is_null($process) || $process !== "1") {
         // Get the amount of files in the Questions Dir
         $counter = 0;
         if ($handle = opendir(APPLICATION_PATH . '/../xml/questions')) {
             while (false !== ($file = readdir($handle))) {
                 if (strtolower(substr($file, -3)) == "xml") {
                     $counter = $counter + 1;
                 }
             }
             closedir($handle);
         }
         $this->view->count = $counter;
     } else {
         // Process the XML Files
         if ($handle = opendir(APPLICATION_PATH . '/../xml/questions')) {
             while (false !== ($file = readdir($handle))) {
                 if (strtolower(substr($file, -3)) == "xml") {
                     echo "Parsing file: {$file} <br/>\nConcepts: ";
                     //Begin Processing
                     $vQuestion = new Model_Shell_GenericQuestion(APPLICATION_PATH . '/../xml/questions/' . $file);
                     //Add to questionBase (if not already there)
                     $vQuestionBase = Model_Quiz_QuestionBase::fromXml($file);
                     if ($vQuestionBase == null) {
                         $vQuestionBase = Model_Quiz_QuestionBase::fromScratch($file, $vQuestion->getDifficulty(), $vQuestion->getEstimatedTime(), $vQuestion->getFriendlyType(), strtotime("today"));
                     }
                     //Now look at the concepts
                     $vConcepts = $vQuestion->getConcepts();
                     foreach ($vConcepts as $vConcept) {
                         //Make sure this concept exists in the database
                         $vConceptObj = Model_Quiz_Concept::fromID($vConcept);
                         if ($vConceptObj == null) {
                             //Doesn't exist... we should make a record
                             $vConceptObj = Model_Quiz_Concept::fromScratch($vConcept);
                         }
                         echo $vConcept . "; ";
                         //Now we need to make sure that this question has this concept associated with it
                         $vQuestionBase->addConcept($vConceptObj);
                     }
                     //Update the questionBase's Difficulty & EstimatedTime (these are the things most likely to change)
                     $vQuestionBase->setDifficulty($vQuestion->getDifficulty());
                     $vQuestionBase->setEstimated_time($vQuestion->getEstimatedTime());
                     echo "<br/>Difficulty: " . $vQuestion->getDifficulty();
                     echo "<br/>Estimated time to complete: " . $vQuestion->getEstimatedTime();
                     echo "<br/><br/>\n";
                 }
             }
             closedir($handle);
             Model_Quiz_GeneratedQuestion::removePregeneratedQuestions();
             // Remove all Pre-Generated questions, so as to not cause any conficts
         }
     }
 }