Link to home
Start Free TrialLog in
Avatar of chalexmandrake
chalexmandrake

asked on

Basic Perl Quiz Help...

Hi, I'm very much a Perl newie and am struggling to get a basic program working. If anyone could assist I would be more than grateful.

The program has to ask the user a series of multiple choice questions read from an already created text file, one at a time (I have done this line by line). The answers then have to be recorded in a new text file, to be read and calculated at the end of the quiz.

Here is what I have come up with so far - it seems to half work; opens and reads the 'questions' text file, accepts the user input, writes to a newly created text file, and continues. However, it seems to stop at question 2...(you will obviously need to write a text file called 'questions' with a few lines of questions)...



open FILE, ">answers.txt";
open FILE, "<questions.txt";
$count=1;
while ($line=<FILE>)  {

$new_line=$count.":".$line;
print $new_line;
$count=$count+1;
$answer=<STDIN>;
open FILE,">answers.txt";
print FILE "$answer\n";
open FILE, "<questions.txt";
$line=<FILE>;
}

close FILE;
exit;


I would also like to know how to get the program re-ask a question when an invalid response is input, and also how to read from the 'questions' text file 4 lines at a time, rather than one ie. rather than having to put the full question on just the one line in the text file, I can format it a little more neatly:

Instead of:

1. What is...? a),b) or c)

like this:

1. What is...?
a)
b)
C)


Many thanks for your help :-)
Avatar of xnxnxn
xnxnxn

hey,
one of your problems is that you use the same handler for the files
try this instead:
open OUTFILE, ">answers.txt";
open INFILE, "<questions.txt";

as for invalid response.. what's a valid response ?
For reading serveral lines you can try:
my $question = "";
whlie ($line = <FILE>) {
  if ($line !~ /^\s*$/) {
    # the line isn't only white space chars.
    $question .= $_;
  } else {
    # next line marks a new question
    # so print the question now
    print "$question\n";
    $question = ""; # reset
  }
}

you should use strict module:
"use strict;"

hope i helped
bahhh...
the while part should be:

while ($line = <INFILE>)

sorry about that
sorry again...
i forgot to mention that the last question wouldn't be shown if you don't have an empty line at the end of your file.
to solve this simply add:
 print "$question\n";
at the end
Avatar of chalexmandrake

ASKER

Cheers... Am just trying that out.

"as for invalid response.. what's a valid response ?"

...sorry - what I meant was not a,b, or c... Will be a multiple choice quiz in that format ie. a keystroke 'p' will be an invalid response.
Avatar of FishMonger
This looks like a homework assignment, so instead of rewriting your code, I'll make a few suggestions.

Use error handling when opening the file handles:
open FILE, "<questions.txt" or die "could not open questions.txt $!";

Separate each of the questions with a single blank line and set the "Input Record Seperator" like this: $/ = "\n\n".  That will allow you read-in each multi-line question into a variable.  If you input the questions into an array, you can easily jump back and forth to any question, depending on the answers that they give.

@questions = <FILE>;

>> I would also like to know how to get the program re-ask a question when an invalid response is input
Output the question in a while or until loop so you can test the answer and repeat the Q if needed.
ASKER CERTIFIED SOLUTION
Avatar of Dave Cross
Dave Cross
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for the help so far... I don't for one minute mind admitting that my knowledge of Perl is so limited (I have only just started, please go easy) that I could barely understand any of your assistance :-) I have just about managed to crack it myself (monkey at a typewriter/trial and error style) nonetheless - like so:

print "this program will...\n\n";
$count=1;
open OUTFILE, ">answers.txt";
open INFILE, "<questions.txt";
while (!eof INFILE)
{
$line=<INFILE>;
print "$line";
if ($count%4<1)
{
print "Please enter answer (a, b or c):\n\n";
$answer=<STDIN>;
print "\n";
print OUTFILE "$answer";
$count++;
}
else
{
$count++;

}
}
print "Thanks for taking part...\n";
close FILE;
exit;


...Any imorovements would be welcomed.

My problem now is marking the text file, which I have begun to attempt - it should compare user answers to correct answers contained in seperate text files - although I am starting to feel like I may be barking up the wrong tree:

$count=1;
$score=1;
open CORRECTFILE, "<correct.txt";
open ANSWERFILE, "<answers.txt";
while (!eof ANSWERFILE) {
$linea=<ANSWERFILE>;
$lineb=<CORRECTFILE>;
if ($linea eq $lineb) {
$score=$score+1;
$count=$count+1;
}
else {
$count=$count+1;
}
print "your score is $score";
close FILE;
exit;}


Any help (in the most basic Laymans) would, once again, be massively appreciated.

Cheers.


If one of our answers has given you a solution then you should accept that answer. If you've worked out the answer yourself then you should request that the question is closed and your points refunded.

If, as it seems, you have a new question then you should post that in a new post and not tag it on the end of an existing one.

Dave...
For an explaination of some of the special Perl variables that will make your life (and your code) easier, please take a look at my article at

   http://www.perl.com/pub/a/2004/06/18/variables.html

For this problem you'll find the $. and $/ variables particularly useful (as used in my solution above).

Dave...
Some suggested improvements to your code

print "this program will...\n\n";
# ALWAYS check return code from open
open OUTFILE, ">answers.txt" or die $!;
open INFILE, "<questions.txt" or die $!;

while (<INFILE>) {
  print $_;

  unless ($. % 4) {
    print "Please enter answer (a, b or c):\n\n";
    $answer=<STDIN>;
    print "\n";
    print OUTFILE "$answer";
  }
}
print "Thanks for taking part...\n";
close FILE;
exit;


Dave...