Solved

Basic Perl Quiz Help...

Posted on 2004-08-25
10
252 Views
Last Modified: 2012-06-21
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 :-)
0
Comment
Question by:chalexmandrake
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1
10 Comments
 

Expert Comment

by:xnxnxn
ID: 11893521
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
0
 

Expert Comment

by:xnxnxn
ID: 11893589
bahhh...
the while part should be:

while ($line = <INFILE>)

sorry about that
0
 

Expert Comment

by:xnxnxn
ID: 11893628
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
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:chalexmandrake
ID: 11893777
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.
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 11893910
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.
0
 
LVL 8

Accepted Solution

by:
davorg earned 500 total points
ID: 11901216
I'd change the format of the question file to use a known separator between the questions.

What is your favourite metavariable?
a) $foo
b) @bar
c) %bar
--
How long is a piece of string?
a) 1 mm
b) 1 m
c) 1 Km

Then you can use $/ to get the individual questions in an array. This makes the task much easier.

#!/usr/bin/perl
 
use strict;
use warnings;
 
open my $q, 'questions.txt' or die $!;
open my $a, '>answers.txt' or die $!;
 
my @q;
{
  local $/ = "--\n";
  @q = <$q>;
  chomp @q;
}
 
foreach (1 .. @q) {
  my $ans;
  do {
    print "$.: $q[$_ - 1]";
    print ': ';
    $ans = <STDIN>;
    chomp $ans;
  } until $ans =~ /^[abc]/i;
  print $a "$_: $ans\n";
}

For extra credit, you could add code to parse each question and build the "valid answers" regex on the fly. This would then allow for questions with different numbers of answers.

Dave...
0
 

Author Comment

by:chalexmandrake
ID: 11903082
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.


0
 
LVL 8

Expert Comment

by:davorg
ID: 11903143
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...
0
 
LVL 8

Expert Comment

by:davorg
ID: 11903177
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...
0
 
LVL 8

Expert Comment

by:davorg
ID: 11903241
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...
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

622 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question