Grading.
If you have a question about the grading of your test, please write it on the front of the exam and hand the exam back to me, within the next several days. Do not write anything on the question pages.
The median score was 38 of 50. Only scores are recorded, not letter grades, but here are some approximate grade ranges: A- to A 42-50, B- to B+ 34-41, C- to C+ 24-33. People whose grades improve as the course goes on will be given extra consideration at the end (as long as coursework has been done), so you can always do better.
Problems.
1. (a) The first argument is $ARGV[0]
.
(b) prg
standard input from keyboard
prg < myfile
standard input from a file
other_prg | prg
a pipe: standard input from standard output
of another program
(c) prg
standard output to screen
prg > myfile
standard output to a file
prg >> myfile
standard output is appended to (added onto) a file
prg | other-prg
a pipe: standard output to standard intput of
another program.
Note. As explained in Handout J distributed with the returned quizzes,
a filename argument does not result in reading the file by standard
input; instead the program has to open the file on purpose (which
<>
does).
2. (a)
<HTML>
<HEAD>
<TITLE> ... </TITLE>
</HEAD>
<BODY>
...
</BODY>
</HTML>
(b) if (/\s/)
and unless (/\S/)
are different. The first
says to do something if the line does contain some whitespace
character. The second says to do something unless the line
contains some non-whitespace character. These are the same if
the line has just one character, but what if the line has two
characters, say " a"
? Then the ``if'' and ``unless'' have
opposite effects.
A good way to think of it is that /\s/
and /\S/
are
opposites for a one-character string, but they give the same result
on " a"
, where they are both true, and also on the empty
string, where they are both false (as one of you pointed out).
3. (a) The shortest answer is
$count = 0;
while(<>)
{
$count += split;
}
print "The text has $count words\n";
This works because split
splits $_
into an array of words
and +=
uses the array in a scalar context, so it becomes the
number of values.
Other valid answers set an array equal to the value of split
and
then either use +=
on the number of values in the array or else
loop over the strings in the array, counting.
(b) Some possible answers are
if ($#ARGV!=2)
{
die $msg;
}
die $msg unless $#ARGV==2;
$#ARGV==2 || die $msg;
4. (a)
sub strip
{
s/^\s*//;
s/\s*$//;
}
(b-1) /[A-Z][z-a]*\:/
(The backslash is optional.)
(b-2) /(^ok$)|(^yes$)|(^y$)/
It is ok to omit the parentheses, but in situations where you
aren't sure about the ``scope'' of an operator such as |
it's
safer to put them in. It can't hurt.
Full credit was given for /^ok|yes|y$/
, which was the answer
we originally had in mind, but Ami discovered that our Perl
compiler doesn't do this one exactly according to the book; it
accepts yeok
and similar combinations as matches.
(b-3) /^\-?\d+$/
5. There are two approaches:
(i) As in lecture and homework examples, wait for a blank line or end of file before printing out for a nonblank group. Use an ``if'' to avoid printing out more than once for the group. Even though the problem doesn't ask for a count, a count is an easy way to keep track of things.
(ii) Print out the first time a nonblank line is encountered.
Again, it's handy to count the nonblank lines. Instead of a count
you could use a Boolean-valued variable $nonblank_seen
.
For (i):
while(<>)
{
if (/\S/)
{ # line is nonblank
$n_nonblank++;
}
else
{ # line is blank
print "group of nonblank lines\n" if $n_nonblank;
$n_nonblank=0;
}
}
print "group of nonblank lines\n" if $n_nonblank;
For (ii):
while(<>)
{
if (/\S/)
{
$n_nonblank++;
print "group of nonblank lines\n" if $n_nonblank==1;
}
else
{
$n_nonblank=0;
}
}