/** * 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; }
function testRandset() { $this->clearAll(); $this->clearTemp(); $filename = 'randset.xml'; $filepath = $this->config->xml->import_path . "/" . $filename; $xml = simplexml_load_file($filepath); $concept = (string) $xml->concepts->concept; //from source $importer = $this->createXmlImporter($this->path); $importer->parseFile($filename); //Create the quiz $qz = $this->createQuiz("Some Quiz", 'comp115-students'); //Add tested concept to quiz $this->addTestedConcept($qz, $concept, 3); My_Logger::clearLog(); $this->clearMysqlLog(); My_Logger::log('**** BEGIN ******'); // Get the Question XML $mQuestion = new Model_Shell_GenericQuestion($filepath); $this->assertEquals('output', $mQuestion->getFriendlyType()); $this->assertTrue(in_array($concept, $mQuestion->getConcepts())); $this->assertEquals('1', $mQuestion->getDifficulty()); //Here comes the compilation. After this single call, all the artifacts are produced $this->assertEquals(trim((string) $xml->instructions), $mQuestion->getInstructions()); //return; //for fun let's ourselves load the xml My_Logger::log(__METHOD__ . ": simpleXml " . print_r($xml, true)); My_Logger::log(__METHOD__ . ": substitution " . print_r($xml->substitutions->substitution[0], true)); My_Logger::log(__METHOD__ . ": substitution " . (string) $xml->substitutions->substitution[0]->attributes()->{'val'}); My_Logger::log(__METHOD__ . ": substitution " . (string) $xml->substitutions->substitution[0]); My_Logger::log(__METHOD__ . "problem:" . (string) $xml->problem); My_Logger::log(__METHOD__ . "actual:" . $mQuestion->getProblem()); $this->assertEquals('foo', $mQuestion->getCorrectOutput()); }