Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

totally stuck

Status
Not open for further replies.

kzn

MIS
Jan 28, 2005
209
GB
Hi

I am trying to make a multi choice quiz. I aim to randomly select 5 questions from a database of 100 questions. Two are true false, one will have more than one answer, the other two will have one answer.


// select two questions from database that are true / false
$query = "select row_id from questions where multi_answer = 'b' order by rand() limit 2";
$result = mysql_query($query);

while($boolean = mysql_fetch_array($result,MYSQL_ASSOC)){

$quiz[] = $boolean['row_id'];
};

// select two question from database that will have more than one answer
$query = "select row_id from questions where multi_answer = 'y' order by rand() limit 1";
$result = mysql_query($query);

while($multi = mysql_fetch_array($result,MYSQL_ASSOC)){

$quiz[] = $multi['row_id'];
};

// select two questions from database that can have only one answer
$query = "select row_id from questions where multi_answer = 'n' order by rand() limit 2";
$result = mysql_query($query);

while($normal = mysql_fetch_array($result,MYSQL_ASSOC)){

$quiz[] = $normal['row_id'];
};

and I need to work this somehow into the below code. so that it uses the random set of numbers that i know will be made up of the right type of questions. Maybe I have attacked this from totally the wrong angle. Please let me know.

$display = 1;

if(isset($_GET['np'])) {
$num_pages = $_GET['np'];
} else {
$num_pages = 5;
}

// determine where in the database to start returning results
if(isset($_GET['s'])) {
$start = $_GET['s'];
} else {
$start = 0;
}


$query = "select row_id, question from questions limit $start, $display";
$result = mysql_query($query);



while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
echo "No.".$row['row_id']." ".$row['question']."<br />";

$query2 = 'select answer from x_answers where question_id ='.$row['row_id'];
$result2 = mysql_query($query2);

while($row2 = mysql_fetch_array($result2, MYSQL_ASSOC)) {
echo "Answer ".$row2['answer']."<br />";
}

}


################################################################################################################################

// make the links to the other pages
if($num_pages > 1) {
echo '<br /><p>';

// determine what page the script is on
$current_page = ($start/$display) + 1;

// if its not the first page, make a previous button
if($current_page != 1) {
echo '<a href="quiz.php?s='.($start - $display).'&np='.$num_pages.'">Previous</a>&nbsp;&nbsp;';
}

// make all the numbered pages
for($i=1; $i <= $num_pages; $i++) {
if($i != $current_page) {
echo '<a href="quiz.php?s='.(($display * ($i -1))).'&np='.$num_pages.'">'.$i.'</a>&nbsp;&nbsp;';
} else {
echo $i.' ';
}
}

// if its not the last page make a next button
if($current_page != $num_pages) {
echo '<a href="quiz.php?s='.($start + $display).'&np='.$num_pages.'">Next</a>';
}
}


I hope this makes sense. All I need is create a multi choice quiz. It must pull 5 random questions from the database. (made up of two true/false, one multi answer,and two single answer)

each of the possible answers is also put in a random order.

Any help would be much appreciated.

Thank you


 
kzn,

This may get you started.

I apologize if there are errors, omissions or bugs.

You'll need to add error detection/mitigation yourself.

Darrell

Code:
<?php
// NOTE: (i/o) in front of a function argument means
//             that argument is passed by reference
// totally stuck: [URL unfurl="true"]http://www.tek-tips.com/viewthread.cfm?qid=1441326&page=1[/URL]

$nQuesCnt = 5; // number of questions
$aQuesArray = array(); // array of questions
$aAnsArray = array(); // array of answers

getQandA_ABS($aQuesArray, $aAnsArray, $nQuesCnt);
/* Note:
   Arrays: $aQuesArray and $aAnsArray will have these structures upon return from getQandA_ABS():
	 $aQuesArray[x][0] = 'ans_type' - possible values: 1=Y/N, 2=Multi-answer, 3=Single-answer
	 $aQuesArray[x][1] = 'question' - The question
	 
	 $aAnsArray[x][0] = 'answer' - [x][0] = first answer of multi-answer question
	      ...
	 $aAnsArray[x][y] = 'answer' - [x][y] = last answer of multi-answer question
*/



/************************************************************ 
*
*  This is where your output goes. I'll leave the rest to you... 
*
*************************************************************/




/** Function: getQandA_ABS :: Database abstraction tier
 *	Purpose:  Get the Question and answers - 
 *	Pass:     (i/o) $aQuesArray - The questions array
 *            (i/o) $aAnsArray - The answers array
 *            (i) $nQuesCnt - The number of question/answer pairs
 *	Caller:   ** Main Program **
 *	Calls:    getQandA_DBA()
 *	Return:   ** You should return something - I'll let you work that out. **
 */
function getQandA_ABS(&$aQuesArray, &$aAnsArray, $nQuesCnt) {
	// define and initialize random question placement array
	$aRndPlaceArray = array();
	for ( $i = 0; $i < $nQuesCnt; $i++ ) { 
		$aRndPlaceArray[$i] = false;
	}
	
	seedPlacementArray($aRndPlaceArray, $nQuesCnt);
	getQandA_DBA($aQuesArray, $aAnsArray, $aRndPlaceArray, $nQuesCnt);
}


/** Function: getQandA_DBA :: Database access tier
 *	Purpose:  Query the database and load both the questions and answers array
 *	Pass:     (i/o) $aQuesArray - The questions array
 *            (i/o) $aAnsArray - The answers array
 *            (i) $aRndPlaceArray - The random question/answer placement array
 *            (i) $nQuesCnt - The number of question/answer pairs
 *	Caller:   getQandA_ABS()
 *	Calls:    getConnection()
 *	Return:   ** You should return something - I'll let you work that out. **
 *	Note:     By sending $nQuesCnt, you can work out an algorithm that
 *            will determine a random number of questions to return
 *            of the different question types
 */
function getQandA_DBA(&$aQuesArray, &$aAnsArray, $aRndPlaceArray, $nQuesCnt) {
	
	$rDbc = getConnection(); // Whatever your connection is...
	
	// Queries
	
	// select 2 T/F questions
	$cSQL1 =
		'select 1 as ans_type, a.row_id, a.question, b.answer '
		.'from questions a  '
		.'where a.multi_answer = "b" '
		.'join x_answers b on b.question_id = a.row_id '
		.'order by a.rand() limit 2';

	// select 1 multi-answer question
	$cSQL2 =
		'select 2 as ans_type, a.row_id, a.question, b.answer '
		.'from questions a  '
		.'where a.multi_answer = "y" '
		.'join x_answers b on b.question_id = a.row_id '
		.'order by a.rand() limit 1';

	// select 2 single-answer questions 
	// I assume you'll get mulitple rows based on the
	// row_id in the x_answers table mapping to the 
	// questions table. We'll compensate for this below.
	$cSQL3 = 
		'select 3 as ans_type, a.row_id, a.question, b.answer '
		.'from questions a  '
		.'where a.multi_answer = "n" '
		.'join x_answers b on b.question_id = a.row_id '
		.'order by a.rand() limit 2';
	
	// Do the queries
	$rRS1 = @mysql_query($cSQL1,$rDbc);
	$rRS2 = @mysql_query($cSQL2,$rDbc);
	$rRS3 = @mysql_query($cSQL3,$rDbc);
	
	// Load the Q & A arrays using the random placement array
	$nIndex = 0;
	
	// T/F questions
	while( $rROW = @mysql_fetch_array($rRS1, MYSQL_ASSOC) ) {
		$aQuesArray[$aRndPlaceArray[$nIndex]][0] = $rROW['ans_type'];
		$aQuesArray[$aRndPlaceArray[$nIndex]][1] = $rROW['question'];
		$aAnsArray[$aRndPlaceArray[$nIndex]][0] = $rROW['answer'];
		$nIndex++;
	}

	// multi-answer question
	// This will only allow for 1 multi-answer question
	// to allow for more, you'll need to modify
	$b1stAnswer = true;
	$nAnsCnt = 0;
	while( $rROW = @mysql_fetch_array($rRS2, MYSQL_ASSOC ) ) {
		if($b1stAnswer) {
			$aQuesArray[$aRndPlaceArray[$nIndex]][0] = $rROW['ans_type'];
			$aQuesArray[$aRndPlaceArray[$nIndex]][1] = $rROW['question'];
			$b1stAnswer = false;
			$nIndex++;
		}
		$aAnsArray[$aRndPlaceArray[$nIndex]][$nAnsCnt] = $rROW['answer'];
		$nAnsCnt++;
	}

	// single-answer questions
	while( $rROW = @mysql_fetch_array($rRS3, MYSQL_ASSOC) ) {
		$aQuesArray[$aRndPlaceArray[$nIndex]][0] = $rROW['ans_type'];
		$aQuesArray[$aRndPlaceArray[$nIndex]][1] = $rROW['question'];
		$aAnsArray[$aRndPlaceArray[$nIndex]][0] = $rROW['answer'];
		$nIndex++;
	}
	
	closeConnection($rDbc);
}



/*** These two function allow for better flexibility later on... ***/
function getConnection() {
	// Your database connection goes here...
	// separating connection management allows you to start a connection pooling function...
	return $rDbc;
}
function closeConnection($rDbc) {
  // just close it or return to connection pool
	$didItClose =	@mysql_close($rDbc);
	return $didItClose;
}



/** Function: seedPlacementArray
 *	Purpose:  Seed the random question/answer placement array pointers
 *	Pass:     (i/o) $aRndPlaceArray - The randdom q/a placement array
 *						(i) $nQuesCnt - The number of question/answer pairs
 *	Caller:   ** Main program **
 *	Calls:    getConnection()
 *	Return:   ** You should return something - I'll let you work that out. **
 *	Note:    	By sending $nQuesCnt, you can work out an algorithm that
 *						will determine a random number of questions to return
 *						of the different question types
 */
function seedPlacementArray(&$aRndPlaceArray, $nQuesCnt) {
	while ( true ) { 
		for ( $i=0; $i < $nQuesCnt; $i++ ) {
			$nIndex = rand(0, $nQuesCnt-1);
			if ( !$aRndPlaceArray[$i] && isIndexFree($aRndPlaceArray, $nIndex) ) {
				$aRndPlaceArray[$i] = $nIndex;
			}
		}
		if ( getPlaceArrayCount($aRndPlaceArray) == $nQuesCnt ) { // have we loaded all question placements?
			break;
		}
	}
}


/** Function: isIndexFree
 *	Purpose:  Determine if a particular value is currently in the random placement array
 *	Pass:     (i/o) $aRndPlaceArray - The randdom q/a placement array
 *						(i) $nIndex - The value to test for
 *	Caller:   seedPlacementArray()
 *	Calls:    none
 *	Return:   (o) $bIndexFree - boolean - True := value isn't in the array
 */
function isIndexFree($aRndPlaceArray, $nIndex) {
	$bIndexFree = true;
	for ( $i=0; $i < count($aRndPlaceArray); $i++ ) {
		if ( $aRndPlaceArray[$i] === $nIndex ) {
			$bIndexFree = false;
			break;
		}
	}
	return $bIndexFree;
}


/** Function: getPlaceArrayCount
 *	Purpose:  Return count of array positions that have been filled
 *	Pass:     (i/o) $aRndPlaceArray - The randdom q/a placement array
 *	Caller:   seedPlacementArray()
 *	Calls:    none
 *	Return:   (o) $nCnt - numeric 
 */
function getPlaceArrayCount($aRndPlaceArray) {
	$nCnt = 0;
	for ( $i = 0; $i < count($aRndPlaceArray); $i++ ) {
		if ( $aRndPlaceArray[$i] !== false ) {
			$nCnt++;
		}
	}
	return $nCnt;
}
?>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top