Having a text file:

$string = 
'1) The most important feature of spiral model is: requirement analysis. risk management. quality management. configuration management 2)   The worst type of coupling is: Data coupling. control coupling. stamp coupling. content coupling 3) One of the fault base testing techniques is: unit testing. beta testing. Stress testing. mutation testing 4)    A fault simulation testing technique is: Mutation testing. Stress testing. Black box testing. White box testing. 5) RS is also known as specification of: White box testing. Stress testing. Integrated testing. Black box testing 6)   Which of these terms is a level name in the Capability Maturity Model?: Ad hoc. Repeatable. Reusable. Organized 7)  FP-based estimation techniques require problem decomposition based on?: information domain values. project schedule. software functions. process activities 8)  What types of models are created during software requirements analysis?: Functional and behavioral. Algorithmic and data structure. Architectural and structural. Usability and reliability 9)  Which of the following is not an attribute of software engineering: Efficiency. Scalability. Dependability. Usability'  

And a code that reads the question and answers text file and put in an html form format:

<html>
    <head>
    <style>
#text_disabled{
border:0;
font-size:10pt;
color:black;
}
</style>
    <title>Question and Answer Read From Text File</title>
    </head>
    <body>
        <form action="processor.php" method="POST" align="center">
        <b><u> QUESTIONS AND ANSWERS QUIZ</u></b> <br /><br />
<?php
$openFile = fopen("questionandanswers.txt", "r") or exit ("unable to open the text       file");
$string = fread($openFile, filesize("questionandanswers.txt"));

//Regex to get from the first number to the string's end, so we ignore the Number Question... bit;
preg_match('/\d.*/', $string, $match);

//We get all the strings starting with a number until it finds another number (which will be the beginning of another question;
preg_match_all('/\d\D*/', $match[0], $results);

$qas = array(); // We prepare an array that will store the questions/answers
foreach($results[0] as $result)
{
    //Separating the question from the string with all the answers.
    list($question, $all_answers) = explode(':', $result);

    //Separating the different answers
    $answers_array = explode('.', $all_answers);

    //Storing the question and the array with all the answers into the previously prepared array;
    $qas[] = array('question' => $question, 'answers' => $answers_array);
}

//Looping through the array and outputting all the info into a form;
foreach($qas as $k=>$v)
{
echo "<input id='text_disabled' style='width:40%' type='text' value='".$v['question']."' name='questions[]' disabled>";
echo "<select name='selected_answers[]'>";
foreach($v['answers'] as $answer){
echo "<option value='".$answer."'>".$answer."</option>";
}
echo "</select>";
echo "<br/><br/>";
}
?>
<input type="submit" value="Submit Answers">&nbsp <input type="reset" value ="Clear Answers">
</form>
    </body>
</html>

Upon submission I am trying to compute the total marks scored after undertaking the test, plus diplaying the answered questions and if possible the other answers too... This is the furthest I have gone but it seems to be not working, Kindly assist me to get this right. Thank you.
These are the codes:

<pre>
<?php
print_r($_POST[question])
$answers = $_POST['selected_answers'];
$total=0;
//Question one
if ($answers[0]=="risk management")
{
$total++;
}
else
{
print_r($answers[0]);
}
echo '<br />';
//second question
if ($answers[1]=="Data coupling")
{
$total++;
}
else
{
print_r($answers[1]);
}

echo '<br />';
//third question
if ($answers[2]=="Unit testing")
{
$total++;
}
else
{
print_r($answers[2]);
}

echo '<br />';
//fourth question

if ($answers[3]=="Mutation testing")
{
$total++;
}
else
{
print_r($answers[3]);
}

echo '<br />';
//fifth question

if ($answers[4]=="white box testing")
{
$total++;
}
else
{
print_r($answers[4]);
}
echo '<br />';
//sixth question

if ($answers[5]=="Ad hoc")
{
$total++;
}
else
{
print_r($answers[5]);
}
echo '<br />';
//seventh question
if ($answers[6]=="information domain values")
{
$total++;
}
else
{
print_r($answers[6]);
}

echo '<br />';
//eigth question

if ($answers[7]=="Functional and behavioral")
{
$total++;
}
else
{
print_r($answers[7]);
}

echo '<br />';
//nineth question

if ($answers[8]=="Efficiency")
{
$total++;
}
else
{
print_r($answers[8]);
}

echo '<br />';
echo '<br />';
//code to generate the total score 
    echo "<b>Total Outcome = $total </b>";
?>
</pre>

Recommended Answers

All 25 Replies

Member Avatar for diafol

I've only given the code a cursory look, but from a 'maintainability' point of view, this is pretty difficult as you need to update the code every time you change the questions / answers.
Is the text file format set and cannot be changed for some reason? Can't you use a database?

Even if the textfile format can't be changed, you could write some code in order to import it to a db table. What it really needs is a correct_answer field. Then is should be a breeze.

Thank you for the insight, then how I'm i suppose to go about it? Thank you.

Member Avatar for diafol

First of all, it depends on your textfile(s). If you've only got the one or two, you may be better off just creating a MySQL table and entering your quiz data directly into that. If however, you have many textfiles, you may be better off creating an 'insert query' to load the majority of the data.

A suggested MySQL table for your quiz:

QUIZZES

quiz_id (PK, int, autoincrement)
quiz_name (varchar, 255)
quiz_description (text)

QUIZ_QUESTIONS

question_id (PK, int, autoincrement - this is not the question number!)
quiz_id (int) - this identifies the particular quiz with a unique id (it should match the quiz_id in the QUIZ table)
question_number (tinyint - the question number to be displayed)
question_text (varchar or text)
answer_1 (varchar)
answer_2 (varchar)
answer_3 (varchar)
answer_4 (varchar)
correct_answer (tinyint - holds 1,2,3 or 4)

If you only have the one quiz, you can do without the QUIZZES table and the quiz_id field in the QUIZ_QUESTIONS table

for example:

$txt = 
'1) The most important feature of spiral model is: requirement analysis. risk management. quality management. configuration management 2)   The worst type of coupling is: Data coupling. control coupling. stamp coupling. content coupling 3) One of the fault base testing techniques is: unit testing. beta testing. Stress testing. mutation testing 4)    A fault simulation testing technique is: Mutation testing. Stress testing. Black box testing. White box testing. 5) RS is also known as specification of: White box testing. Stress testing. Integrated testing. Black box testing 6)   Which of these terms is a level name in the Capability Maturity Model?: Ad hoc. Repeatable. Reusable. Organized 7)  FP-based estimation techniques require problem decomposition based on?: information domain values. project schedule. software functions. process activities 8)  What types of models are created during software requirements analysis?: Functional and behavioral. Algorithmic and data structure. Architectural and structural. Usability and reliability 9)  Which of the following is not an attribute of software engineering: Efficiency. Scalability. Dependability. Usability';

$items = array_filter(preg_split("/\d+\)\s+/",$txt));
$formatted = array();

foreach($items as $q)
{
    list($question,$ans) = explode(": ", $q);
    list($answer1,$answer2,$answer3,$answer4) = array_map("trim", explode(".",$ans));   
    $formatted[] = "('" . implode("','", array_map("mysql_real_escape_string",array($question, $answer1, $answer2, $answer3, $answer4))) . "')";
}

$SQL = "INSERT INTO `table` `question`, `answer1`, `answer2`, `answer3`, `answer4` VALUES " . implode(",", $formatted);
echo $SQL;

As mentioned that's just an example. You'd need to check it.

I have tried your method but the databases is not being loaded with any data from the text file. this are the codes I have used using the textfile u edited above:

<html>
<head>
</style>
    <title>Question and Answer Read From Text File</title>
    </head>
    <body>
        <form action="processor.php" method="POST" align="center">
        <b><u> QUESTIONS AND ANSWERS QUIZ</u></b> <br /><br />
<?php
openFile = fopen("testdb.txt", "r") or exit ("unable to open the text       file");
$txt = fread($openFile, filesize("testdb.txt"));

$items = array_filter(preg_split("/\d+\)\s+/",$txt));
$formatted = array();
foreach($items as $q)
{
    list($question,$ans) = explode(": ", $q);
    list($answer1,$answer2,$answer3,$answer4) = array_map("trim", explode(".",$ans));   
    $formatted[] = "('" . implode("','", array_map("mysql_real_escape_string",array($question, $answer1, $answer2, $answer3, $answer4))) . "')";
}

include 'dbc.php';

$SQL = "INSERT INTO quiz_questions(question_text, answer_1, answer_2, answer_3, answer_4) VALUES " . implode(",", $formatted);
echo $SQL;
?>
</body>
</html>

What could be the problem?

Member Avatar for diafol

You're not running a query.

You need:

$SQL = "INSERT INTO quiz_questions(question_text, answer_1, answer_2, answer_3, answer_4) VALUES " . implode(",", $formatted);
mysql_query( $SQL );

BTW, mysql is dying. Consider moving to mysqli or PDO once you get to grips with the basics.

Its still not working out for me, I dont know where I am going wrong. Any working example to guide me through to work this one out? I would appreciate the guidance.

Member Avatar for diafol

I dont know where I am going wrong

Do this after the $SQL = ...

echo $SQL;
mysql_query( $SQL ) or die(mysql_error());

I'm assuming that you've set up a database and have made a conenction to it before trying to run the query?

Member Avatar for diafol

DOh! I forgot the brackets around the field names too.

This is the table I created:

CREATE TABLE `quiz_questions` (
  `question_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `quiz_id` TINYINT(4) DEFAULT NULL,
  `question_number` TINYINT(4) DEFAULT NULL,
  `question_text` TEXT COLLATE utf8_unicode_ci,
  `answer1` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `answer2` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `answer3` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `answer4` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `correct_answer` TINYINT(1) DEFAULT NULL,
  PRIMARY KEY (`question_id`)
) ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Here's the code I used to successfully load in the file data:

header('Content-Type: text/html; charset=utf-8');

$link = mysql_connect('localhost', 'root', ''); //supply your own data here
if (!$link) {
    die('Not connected : ' . mysql_error());
}

$db_selected = mysql_select_db('daniweb', $link); //change this to your DB name
if (!$db_selected) {
    die ('Can\'t use daniweb : ' . mysql_error());
}

function makeSQL($filename)
{
    if(!file_exists($filename)) return false;
    $quizString = file_get_contents($filename); 
    $items = array_filter(preg_split("/\d+\)\s+/",$quizString));
    $formatted = array();
    $i = 1;
    foreach($items as $q)
    {
        list($question,$ans) = explode(": ", $q);
        list($answer1,$answer2,$answer3,$answer4) = array_map("trim", explode(".",$ans));   
        $formatted[] = "($i,'" . implode("','", array_map("mysql_real_escape_string",array($question, $answer1, $answer2, $answer3, $answer4))) . "')";
        $i++;
    }
    return "INSERT INTO `quiz_questions` (`question_number`, `question_text`, `answer1`, `answer2`, `answer3`, `answer4`) VALUES " . implode(",", $formatted);
}

if($sql = makeSQL('quiz.txt')){  //change this to your filename
    echo $sql;
    mysql_query($sql) or die('Problem with query: ' . mysql_error());   
}else{
    echo "Houston, we have a problem";  
}
commented: This is how it can be implemented in an easier way. Thank you +1

Its actually working so well, Thank you for that. But the page that loads the data into the database also displays every other code on the page, I thought php code should be hidden?
And how will we be able to use the correct answer column? Should we also have another page that contains the correct answers? and at every instant of page refreshement should we replace new data with the old one in the database because it seems it is storing both the old questions and answers, and the new one if at all edited.
I thought its better if we replace everything in the database with the new records incase we eidit the text file with new data entry.
Thank you once again.

Member Avatar for diafol

. But the page that loads the data into the database also displays every other code on the page,

That should just be a one-off script to load your data into a db. Once you've got your data into the db, either delete it - if you daon't think you'll need it again, or comment it out with /* ... */

This should not be run every time you open the page! Once the data is in the DB, that's it, you just retrieve the data for the user in order for him to answer.

e.g. in a form...

$result = mysql_query("SELECT * FROM quiz_questions ORDER BY question_number");
while($data = mysql_fetch_assoc($result)){
    echo $data['question_number'] . ". " . $data['question_text'] . "<br />";
    //then echo out the input radiobuttons ($data['answer1'] etc)
}

As for displaying all your code - I have no idea why that would happen, unledd you've put a ?> tag in the middle somewhere.

For the correct answer column (field), you'll have to enter that manually. The only other way to do it would be to include it in your text file, which you could do, but I thought that we're getting away from such things.

WHen the user sends the form, grab the sent data (radiobutton values) and check against the values in the DB.
You can calculate the total, display the correct and the user's answers.

Member Avatar for diafol

Here's a screnshot of what your table should hold. I filled the correct_answer with random numbers (1-4) - I'm not going to try to find the right answers and look like an idiot!

42c09690ef5b102c846a8d5bc2246be0

You'll see I gave the quiz_id a value of '1' for each question - this is in case you have more than one set of quiz questions (more than one text file?)

If you want to permanently store the user's results, either store the result of each question or just store the total in a results table - but you'll need a users table too. If so, you'll need to build a login system.

quiz_results

quiz_result_id (PK, int, autoincrement)
quiz_id (int)
user_id (int)
total (tinyint)
date_taken (date)

users

user_id (PK, int, autoincrement)
username (varchar 20)
passhash (varchar, 32)
(other details you may need to know, e.g. email...)

You can check the user's results thus:

$quiz_id = $_POST['quiz_id'];  //this could be a hidden input field in the form (perhaps = 1)
$q = array();
$q[] = $_POST['question']; //this would be = to the radiobutton value chosen for the question array fields (e.g. $q[0] = 1,$q[1] = 1,$q[2] = 4,$q[3] = 2...)  

You retrieve the answers from the DB and compare

$total = 0;
$cnt = 0;
$result = mysql_query("SELECT * FROM quiz_questions WHERE quiz_id = $quiz_id ORDER BY question_number");
while($data = mysql_fetch_assoc($result)){
    if($q[$cnt] == $data['correct_answer'])$total++;
    $cnt++;
}

That's a very simplistic example. In a real solution, you'd use the while loop to build up html output too, like show the question, all the answers, highlight the correct answer and underline the chosen answer - or something like that.

I would like to include it in my text file, so that it can also be transfered together with the other data into the database. But would that mean i would need to interfear with my regex.
Thank you.

Member Avatar for diafol

OK, so you use a separaator (e.g. !) at the end of your answers in the textfile and enter a number (1-4) or (0-3) if you want to use base 0.

e.g.

1) The most important feature of spiral model is: requirement analysis. risk management. quality management. configuration management!3 2)   The worst t

You then add an extra rule to the regex/explode routine to extract this from the last answer (answer4).

I have inserted the following code to check on the answer:

preg_match_all('/\d!{0,3}', $match[0], $correct);

If I am able to do that, How will I be able to pass both the correct answer and the selected answer through a form submitted together with the tackled questions, such that I am able to compare the chosen answer with the correct one and compute the total score of the answered questions and display. That is without going through the database procedure. That will have solved my problem. Thank you.

Member Avatar for diafol

I'm lost. I don't understand why you're using regex at all for the site once you've got all the questions and answers in the DB. The 'select query' is essential for creating the form in the first place and then later, for comparing the answers supplied by the user against the correct answers from the DB.

Let's consider the form page, these are the bits required:

1) DB connection
2) Get data from DB for a particular quiz (e.g. quiz_id = 1)
3) Build up form content from the data in the while loop and place into a variable, ready for echoing later on (let's assum it's called $form.
4) Start the html and include an empty form with an echo $form; in it.

The display results page, if you want to display each answer, question by question could be something like this:

1) Get $_POST data from the sent form (as shown in a previous post)
2) Use a SELECT query to get the questions, answers, correct answers etc and check your post data against the DB data in a while loop. Build the output as you go along into a variable called $output, for example.
3) Start the html and include the echo $output; in a suitable place.

I'm sorry if this sounds a bit cryptic, but reviewing the article, I realise that I've been doing a lot of this work for you, instead of leading you to discovery. That's bad. I don't think that you'll learn effectively that way. So from now on, you do the coding, bit by bit if you like and we'll chip in and suggest improvements / alternatives.

Let me try this option. I will get back if I get stack somewhere. Thank you.

I changed and had the following answers in another text file called answers.txt . Now what is submitted from the form and the answers read from the text file are suppose to be compared. if the answers is similar to the correct answer it adds one otherwise adds zero. This is the code:

<html>
<head>
<title>Chosen answers</title>
</head>
<body>
<pre>
<?php
//Posting of the chosen answers

$answers = $_POST['selected_answers'];
echo '<b><u>THE ANSWERS YOU HAVE CHOSEN ARE:</u></b><br /><br />';
print_r($answers);

//Opening of the answers file, reading and printing it

$openFile = fopen("answers.txt", "r") or exit ("unable to open the answers file");
$fileContents = fread($openFile, filesize("answers.txt"));
fclose($openFile);
$delimiter = "  ";
$myArray = explode($delimiter, $fileContents);

$score = $score1 = $score2 = $score3 = $score4 = $score5 = $score6 = $score7 = $score8 = 0;

//Computation of marks scored for the answered questions

if ($answers[0] == $myArray[0])
{
    $score = 1;
}
elseif ($answers[0] !=$myArray[0])
{
    $score = 0;
}echo '<br />';

if ($answers[1] == $myArray[1])
{
    $score1 = 1;
}
elseif ($answers[1] !=$myArray[1])
{
    $score1 = 0;
}echo '<br />';

if ($answers[2] == $myArray[2])
{
    $score2 = 1;
}
elseif ($answers[2] !=$myArray[2])
{
    $score2 = 0;
}echo '<br />';

if ($answers[3] == $myArray[3])
{
    $score3 = 1;
}
elseif ($answers[3] !=$myArray[3])
{
    $score3 = 0;
}echo '<br />';
if ($answers[4] == $myArray[4])
{
    $score4 = 1;
}
elseif ($answers[4] !=$myArray[4])
{
    $score4 = 0;
}echo '<br />';

if ($answers[5] == $myArray[5])
{
    $score5 = 1;
}
elseif ($answers[5] !=$myArray[5])
{
    $score5 = 0;
}echo '<br />';

if ($answers[6] == $myArray[6])
{
    $score6 = 1;
}
elseif ($answers[6] !=$myArray[6])
{
    $score6 = 0;
}echo '<br />';

if ($answers[7] == $myArray[7])
{
    $score7 = 1;
}
elseif ($answers[7] !=$myArray[7])
{
    $score7 = 0;
}echo '<br />';

if ($answers[8] == $myArray[8])
{
    $score8 = 1;
}
elseif ($answers[8] !=$myArray[8])
{
    $score8 = 0;
}

$Total = $score + $score1 + $score2 + $score3 + $score4 + $score5 + $score6 + $score7 + $score8 ;

echo "<b><u>$Total</u></b>";
?>
</pre>
</body>
</html>

The problem is the arrays does not seem to compare and the computation does not seem to work, what might be the problem? thank you.

Member Avatar for diafol

You've gone back to text files then. You're duplicating without need. Just use a loop

$no_questions = 9; // or get this from the textfile
for($x = 0; $x < $no_questions; $x++) $score[$x] = ($answers[$x] == $myArray[$x]) ? 1 : 0;
$total = array_sum($score);

When I use the for formula u have stipulated above i get the following php error:

SCREAM: Error suppression ignored for
Notice: Undefined variable: score in D:\wamp\www\frmfile\processor.php on line 35 & line 36

and also the following error:

Warning: array_sum() expects parameter 1 to be array, null given in D:\wamp\www\frmfile\processor.php on line 38
Member Avatar for diafol
$score = array();
$no_questions = 9; // or get this from the textfile
for($x = 0; $x < $no_questions; $x++) $score[$x] = ($answers[$x] == $myArray[$x]) ? 1 : 0;
$total = array_sum($score);

Thank you Diafol, I have finally figured it out. This is how I have implemented it and it works so well

//Computation of marks scored for the answered questions
$score = 0;
$no_questions = 9;

for ($x = 0; $x < $no_questions; $x++) 
{
if ($answers_trimmed [$x]== $myArray_trimmed[$x])
                {
                $score++;
                }
}
echo '<br />';
echo "<b><u>$score</u></b>";

Thanks, what I dont know how to implement is how not to pass the question in my previous thread, together with the posted answer when I submit the form input. Would you be in a position to know how I may go about it? Thanks once again.

I tought that was dealing with the database system. How to pass it togetehr with the answers from the text file. Thank you.

Member Avatar for diafol

Show us what you have so far, or it'll be me doing this for you.

I have managed to pass the form submission with the questions. What I'm trying to accomplish is to for each question, its subsequent answer chosen follows. This is what I have so far:

These are the questions:

1)  The most important feature of spiral model is2) The worst type of coupling is3) One of the fault base testing techniques is4)   A fault simulation testing technique is5)   RS is also known as specification of6)  Which of these terms is a level name in the Capability Maturity Model?7)    FP-based estimation techniques require problem decomposition based on?8)    What types of models are created during software requirements analysis?9)   Which of the following is not an attribute of software engineeringTHE ANSWERS YOU HAVE CHOSEN ARE:

These are the answers:

Data coupling
Unit testing
Mutation testing
White box testing
Ad hoc
Information domain values
Functional and behavioral
Efficiency

You Total Score is : 8

Now What I am trying to achieve:

foreach ($question as quiz)
{
echo "echo $answers[0]";
}

Without interfearing with my codes. These are the codes that I have on the same so far:

<html>
<head>
<title>Chosen Answers</title>
<style >
<!--
body {
    background-color: #00FFFF;
}

-->
</style>
</head>
<body>
<pre>
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

//Posting of the chosen answers
if(isset($_POST['submit']))
{
$question = $_POST['questions'];
$answers = $_POST['selected_answers'];
echo '<b><u>THE ANSWERS YOU HAVE CHOSEN ARE:</u></b><br /><br />';
$answers_trimmed = array_map('trim', $answers);
}
foreach($question as $quiz)
{
echo ($answers_trimmed);
}
//Opening of the answers file, reading and printing it

$openFile = fopen("answers.txt", "r") or exit ("unable to open the answers file");
$fileContents = fread($openFile, filesize("answers.txt"));
trim($fileContents);
fclose($openFile);
$delimiter = "  ";
$myArray = explode($delimiter, $fileContents);
//Deletes unnecessary spaces in the read text files.
$myArray_trimmed = array_map('trim', $myArray);

//Computation of marks scored for the answered questions
$score = 0;
$no_questions = 9;

for ($x = 0; $x < $no_questions; $x++) 
{
if ($answers_trimmed [$x]== $myArray_trimmed[$x])
        {
        echo "$answers_trimmed[$x]";
        echo '<br />';
        $score++;
        }
}
echo '<br />';
echo "<b>You Total Score is : <u>$score</u></b>";
?>
</pre>
</body>
</html>
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.