/** * Like {@link swapshuffle()}, but works on associative arrays * * @param array $array The associative array to be rearranged * @return array */ function swapshuffle_assoc($array) { $newarray = array(); $newkeys = swapshuffle(array_keys($array)); foreach ($newkeys as $newkey) { $newarray[$newkey] = $array[$newkey]; } return $newarray; }
<?php include "util.inc.php"; global $config; include INC_DIR . "config.inc.php"; include INC_DIR . "db.inc.php"; ini_set("memory_limit", "32M"); $config = new Config(); $db = new Db(); $names = swapshuffle(createNames()); $query = "SELECT COUNT(*) AS num_caves FROM Cave GROUP BY NULL"; $db_result = $db->query($query); if (!$db_result || $db_result->isEmpty()) { echo "Fehler bei der Abfrage der Anzahl der Höhlen. (1.a.)\n"; return -1; } $row = $db_result->nextrow(MYSQL_ASSOC); $num_caves = $row['num_caves']; if ($num_caves > sizeof($names)) { echo "Zu wenig Namen für alle Höhlen. (2.a.)\n"; return -2; } // hier wird davon ausgegangen, dass die Höhlen mit 1 beginnend fortlaufend durchnummeriert sind. for ($i = 0; $i < $num_caves; ++$i) { $query = "UPDATE Cave SET name = '" . $names[$i] . "' WHERE caveID = " . ($i + 1); $db_result = $db->query($query); if (!$db_result || $db->affected_rows() != 1) { echo "Fehler beim Ändern des Höhlennamen: (" . ($i + 1) . ") " . $names[$i] . ". (3.a.)\n"; echo mysql_errno() . ": " . mysql_error() . "\n"; return -3; }
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) { // create an array of answerids ??? why so complicated ??? $answerids = array_values(array_map(create_function('$val', 'return $val->id;'), $question->options->answers)); // Shuffle the answers if required if (!empty($cmoptions->shuffleanswers) and !empty($question->options->shuffleanswers)) { $answerids = swapshuffle($answerids); } $state->options->order = $answerids; // Create empty responses if ($question->options->single) { $state->responses = array('' => ''); } else { $state->responses = array(); } return true; }
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) { // Choose a random shortanswer question from the category: // We need to make sure that no question is used more than once in the // quiz. Therfore the following need to be excluded: // 1. All questions that are explicitly assigned to the quiz // 2. All random questions // 3. All questions that are already chosen by an other random question global $QTYPES; if (!isset($cmoptions->questionsinuse)) { $cmoptions->questionsinuse = $cmoptions->questions; } if ($question->options->subcats) { // recurse into subcategories $categorylist = question_categorylist($question->category); } else { $categorylist = $question->category; } $saquestions = $this->get_sa_candidates($categorylist, $cmoptions->questionsinuse); $count = count($saquestions); $wanted = $question->options->choose; $errorstr = ''; if ($count < $wanted && isteacherinanycourse()) { if ($count >= 2) { $errorstr = "Error: could not get enough Short-Answer questions!\n Got {$count} Short-Answer questions, but wanted {$wanted}.\n Reducing number to choose from to {$count}!"; $wanted = $question->options->choose = $count; } else { $errorstr = "Error: could not get enough Short-Answer questions!\n This can happen if all available Short-Answer questions are already\n taken up by other Random questions or Random Short-Answer question.\n Another possible cause for this error is that Short-Answer\n questions were deleted after this Random Short-Answer question was\n created."; } notify($errorstr); $errorstr = '<span class="notifyproblem">' . $errorstr . '</span>'; } if ($count < $wanted) { $question->questiontext = "{$errorstr}<br /><br />Insufficient selection options are\n available for this question, therefore it is not available in this\n quiz. Please inform your teacher."; // Treat this as a description from this point on $question->qtype = DESCRIPTION; return true; } $saquestions = draw_rand_array($saquestions, $question->options->choose); // from bug 1889 foreach ($saquestions as $key => $wrappedquestion) { if (!$QTYPES[$wrappedquestion->qtype]->get_question_options($wrappedquestion)) { return false; } // Now we overwrite the $question->options->answers field to only // *one* (the first) correct answer. This loop can be deleted to // take all answers into account (i.e. put them all into the // drop-down menu. $foundcorrect = false; foreach ($wrappedquestion->options->answers as $answer) { if ($foundcorrect || $answer->fraction != 1.0) { unset($wrappedquestion->options->answers[$answer->id]); } else { if (!$foundcorrect) { $foundcorrect = true; } } } if (!$QTYPES[$wrappedquestion->qtype]->create_session_and_responses($wrappedquestion, $state, $cmoptions, $attempt)) { return false; } $wrappedquestion->name_prefix = $question->name_prefix; $wrappedquestion->maxgrade = $question->maxgrade; $cmoptions->questionsinuse .= ",{$wrappedquestion->id}"; $state->options->subquestions[$key] = clone $wrappedquestion; } // Shuffle the answers (Do this always because this is a random question type) $subquestionids = array_values(array_map(create_function('$val', 'return $val->id;'), $state->options->subquestions)); $subquestionids = swapshuffle($subquestionids); // Create empty responses foreach ($subquestionids as $val) { $state->responses[$val] = ''; } return true; }
public function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) { // Choose a random shortanswer question from the category: // We need to make sure that no question is used more than once in the // quiz. Therfore the following need to be excluded: // 1. All questions that are explicitly assigned to the quiz // 2. All random questions // 3. All questions that are already chosen by an other random question. global $QTYPES, $OUTPUT, $USER; if (!isset($cmoptions->questionsinuse)) { $cmoptions->questionsinuse = $cmoptions->questions; } if ($question->options->subcats) { // Recurse into subcategories. $categorylist = question_categorylist($question->category); } else { $categorylist = array($question->category); } $saquestions = $this->get_sa_candidates($categorylist, $cmoptions->questionsinuse); $count = count($saquestions); $wanted = $question->options->choose; if ($count < $wanted) { $question->questiontext = "Insufficient selection options are\n available for this question, therefore it is not available in this\n quiz. Please inform your teacher."; // Treat this as a description from this point on. $question->qtype = 'description'; return true; } $saquestions = draw_rand_array($saquestions, $question->options->choose); // From bug 1889. foreach ($saquestions as $key => $wrappedquestion) { if (!$QTYPES[$wrappedquestion->qtype]->get_question_options($wrappedquestion)) { return false; } // Now we overwrite the $question->options->answers field to only // *one* (the first) correct answer. This loop can be deleted to // take all answers into account (i.e. put them all into the // drop-down menu. $foundcorrect = false; foreach ($wrappedquestion->options->answers as $answer) { if ($foundcorrect || $answer->fraction != 1.0) { unset($wrappedquestion->options->answers[$answer->id]); } else { if (!$foundcorrect) { $foundcorrect = true; } } } if (!$QTYPES[$wrappedquestion->qtype]->create_session_and_responses($wrappedquestion, $state, $cmoptions, $attempt)) { return false; } $wrappedquestion->name_prefix = $question->name_prefix; $wrappedquestion->maxgrade = $question->maxgrade; $cmoptions->questionsinuse .= ",{$wrappedquestion->id}"; $state->options->subquestions[$key] = clone $wrappedquestion; } // Shuffle the answers (Do this always because this is a random question type). $subquestionids = array_values(array_map(create_function('$val', 'return $val->id;'), $state->options->subquestions)); $subquestionids = swapshuffle($subquestionids); // Create empty responses. foreach ($subquestionids as $val) { $state->responses[$val] = ''; } return true; }
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) { // Find out how many datasets are available global $CFG, $DB, $QTYPES, $OUTPUT; $maxnumber = (int) $DB->get_field_sql("SELECT MIN(a.itemcount)\n FROM {question_dataset_definitions} a, {question_datasets} b\n WHERE b.question = ? AND a.id = b.datasetdefinition", array($question->id)); if (!$maxnumber) { print_error('cannotgetdsforquestion', 'question', '', $question->id); } $sql = "SELECT i.*\n FROM {question_datasets} d, {question_dataset_definitions} i\n WHERE d.question = ? AND d.datasetdefinition = i.id AND i.category != 0"; if (!$question->options->synchronize || !($records = $DB->get_records_sql($sql, array($question->id)))) { $synchronize_calculated = false; } else { // i.e records is true so test coherence $coherence = true; $a = new stdClass(); $a->qid = $question->id; $a->qcat = $question->category; foreach ($records as $def) { if ($def->category != $question->category) { $a->name = $def->name; $a->sharedcat = $def->category; $coherence = false; break; } } if (!$coherence) { echo $OUTPUT->notification(get_string('nocoherencequestionsdatyasetcategory', 'qtype_calculated', $a)); } $synchronize_calculated = true; } // Choose a random dataset // maxnumber sould not be breater than 100 if ($maxnumber > CALCULATEDQUESTIONMAXITEMNUMBER) { $maxnumber = CALCULATEDQUESTIONMAXITEMNUMBER; } if ($synchronize_calculated === false) { $state->options->datasetitem = rand(1, $maxnumber); } else { $state->options->datasetitem = intval($maxnumber * substr($attempt->timestart, -2) / 100); if ($state->options->datasetitem < 1) { $state->options->datasetitem = 1; } else { if ($state->options->datasetitem > $maxnumber) { $state->options->datasetitem = $maxnumber; } } } $state->options->dataset = $this->pick_question_dataset($question, $state->options->datasetitem); // create an array of answerids ??? why so complicated ??? $answerids = array_values(array_map(create_function('$val', 'return $val->id;'), $question->options->answers)); // Shuffle the answers if required if (!empty($cmoptions->shuffleanswers) and !empty($question->options->shuffleanswers)) { $answerids = swapshuffle($answerids); } $state->options->order = $answerids; // Create empty responses if ($question->options->single) { $state->responses = array('' => ''); } else { $state->responses = array(); } return true; }