CSCI 344
Quiz 4
Monday December 15
You may use any non-living reference. In other words, you can use
books, notes, your solutions to lab assignments, and the web but you cannot communicate with anyone.
Copy your Perl scripts to:
/user/projects/csci344/quizN/USERNAME/quizN
where N is the quiz number and USERNAME is your ecst username.
Put your name in a comment at the top of each file (after the line that contains #!/usr/bin/perl).
1) (10 points) Write a Perl script
(called db) that reads a database of the following form:
<first>:<last>:<street>:<city>:<state>
For example ~tyson/344/quiz4/db.small contains:
Philip:King:715 Birch Ave:Silver Spring:Maryland
Sara:Turner:85 College St:Santa Rosa:California
Samuel:Ward:509 Twelfth Blvd:Joyce:Washington
Paula:Bell:551 View Ct:Ithaca:New York
Mary:Wilson:269 California Way:W St. Louis:Missouri
Brenda:Thompson:804 Cedar St:Miami:Florida
Joyce:Johnson:478 Broadway Ave:San Antonio:Texas
Martin:Scott:93 Sara St:Charlottesville:Virginia
Aaron:Barnes:622 Thirteenth Ave:Albuquerque:New Mexico
Gary:Rodriguez:623 Oak St:Los Angeles:California
and allows the user to query the database by field until a ^D is entered. For example:
$ db db.small
first:Joyce
Joyce:Johnson:478 Broadway Ave:San Antonio:Texas
city:Joyce
Samuel:Ward:509 Twelfth Blvd:Joyce:Washington
state:California
Sara:Turner:85 College St:Santa Rosa:California
Gary:Rodriguez:623 Oak St:Los Angeles:California
$
For the queries the fields should be called: "first" "last" "street" "city" "state".
You should return all matches for that field, but not matches in other
fields (that is "first:Joyce" should not return Samual Ward who lives
in "Joyce, Washington").
Assume that the database file is given on the command line and the
queries are read from standard input. Assume that the database
file contains no errors and the queries contain no errors.
HINT: While this could be implemented by using one or more hashes, it
is really easy (16 total lines) to store all the data in a single array
and create clever patterns for the queries. For example, for a
city to match there must be three ":" before the string that matches a
city.
2) (15 points) Using Perl
implement a shell (call it tsh) that times all the commands performed
by the user and prints a summary of all commands and the their
execution times. Print the summary when the shell is exited using
a ^D. Use "%" for your shell's prompt. The program should
run like this:
[tyson@gila quiz4]$ tsh
% vi hello.cpp
% g++ -o hello hello.cpp
% hello
hello world
% vi goodbye.cpp
% g++ -o goodbye goodbye.cpp
% goodbye
goodbye world
% ls *.cpp
goodbye.cpp hello.cpp
% date
Mon Dec 15 09:43:09 PST 2008
% ^D
date:0.00101399421691895 seconds
hello:0.0016939640045166 seconds
vi:18.5880360603333 seconds
ls:0.00302505493164062 seconds
goodbye:0.00172996520996094 seconds
g++:0.346757173538208 seconds
prompt:46.6848196983337 seconds
[tyson@gila quiz4]$
The times for each command should be cumulative. For example, in
the above example vi was called twice. The total time used by vi
for both instantiations was 18.5 seconds.
The "prompt" is the total time tsh ran minus all the time spent running
other programs: $end_time - $start_time - $sum_of_cmd_times;
Use the HiRes time package to redefine the time function so it returns fractions of seconds (the default time function returns whole seconds):
use Time::HiRes ("time");
$start_time = time;
do something
$end_time = time;
You could use gettimeofday or the Linux time command but using Perl's HiRes time is easier and good enough for this problem.
Termination: read until end of standard input (until the user enters
^D). ^D is usually not automatically printed. In my program
(shown above) I print the string "^D" (not a real ^D) when the program
reaches end of standard input.
3) (20 points) Write a perl
program called keys that reads a list of keywords from the file "./keywords" (always use this filename) and then
reads text from standard input. Report which keywords are used in
the text read from standard input and which words from the text are not keywords. When comparing words ignore
the case of both the keywords and the input (use the lc function to
convert to lower case).
Assume that the keywords file contains one word per line.
Assume that the input text contains words, commas, periods, and
whitespace. Ignore the commas, periods, and whitespace (in other
words, commas, periods, and whitespace should all be considered word
separators). Hint: if you substitute all "," and "\." to spaces and use the default split you will get the correct words.
Your program should work like this (sample files are in ~tyson/344/quiz4):
$ cat keywords
Student
Assignment
class
course
final
exam
csci
$
$ cat keywords.text
The students took the final exam, for their CSCI 344 course, on Monday December 15.
It was a difficult exam.
$
$ keys < keywords.text
keywords used:
course
exam
final
CSCI
non keywords used:
It
the
a
for
15
Monday
took
December
on
was
their
344
students
difficult
The
$