Lab 4 - Making decisions |
Overview |
Last week we took a quick look at two more Perl data types - the list, an ordered collection of items, and the hash, which organizes items by a scalar called the key. Today we're going to get more practice with scalars, lists, and hashes, while learning about some of Perl's control flow constructs. These are ways you can cause your program to make decisions based on variables, or repeat a section of code several times. We'll also get our start with reading information from files on disk, which is something you'll find very handy for the project. You should know about the following topics by
the end of lab today:
You'll also write a genuinely useful program -- a simplified version of the grep utility for finding strings in files. |
Quick review of decision constructs |
Perl's #!/usr/bin/perl -w use strict; my ($a, $b) = (12, 24); # $a = 12 and $b = 24 if( $a > $b ) { print "$a > $b\n"; } else { print "$a <= $b\n"; } $a *= 2; print "$a == $b\n" if $a == $b; jpr@sulu (i211/lab4) $ ./ifdemo.pl 12 <= 24 24 == 24 jpr@sulu (i211/lab4) $ Notice the shortened form of the |
Quick review of looping constructs |
We already saw one looping construct in the last lab - the Note that neither the #!/usr/bin/perl -w use strict; # code that processes user input might look like this.. my $input = ""; # read a line of input.. while( $input ne "done" ) { # do something with the line of input # read another line of input } # print the numbers from 1 to 10 for( my $i = 1; $i <= 10; $i++ ) { print $i, "\n"; } |
More practice with hashes |
Let's write a simple program that maintains bank accounts. The core of this program is a "database", implemented as a hash, that associates every user with the balance in their account. The program should repeatedly prompt the user for commands. This command can be "add", "wd" (short for withdraw), "print", or "exit". An example run of this program is shown below - try to figure out exactly what the program is supposed to do before you start writing code! jpr@sulu (i211/lab4) $ ./bank.pl Welcome to Techno-Bank 3000. Enter command => add jacob 1000 done. Enter command => add jacob 10000 done. Enter command => this is fun invalid command. Enter command => add fil 1000 done. Enter command => wd fil 20 done. Enter command => print Here are the accounts in Techno-Bank 3000. jacob has 11000. fil has 980. Enter command => exit Goodbye. jpr@sulu (i211/lab4) $ The first step in solving this assignment is to think about it one step at a time. The following skeleton program can give you an idea of what needs to be done, and serve as a starting point. #!/usr/bin/perl -w use strict; my %accounts; # create the hash that stores everything my $next_line = < STDIN>; chomp $next_line; # this trick can help you separate the command from the username and amount my ($command, $user, $amount) = split / /, $next_line; while( the next command is not "exit" ) { # figure out what the next command is # do the appropriate thing # if the command is invalid, print an error message. # Print another prompt # read another command } Do not worry about overdrafts (withdrawing more money than a person has) or invalid amounts (e.g. entering a word instead of a number for the amount). Implement the "exit" command first, then "print", then "add", then "wd" - doing things in this order will make testing easy. Try to run your program often to make sure errors don't pile up. Do this:
Write bank.pl. If you choose, you can use the code above to help you get started. Make sure to place the finished program in your i211/lab4 directory. Test your program thoroughly to make sure it works right. Hint:The body of your |
Quick review of globs and file I/O |
The "angle brackets" ( Globs let you grab the names of all files in the current directory that match a certain pattern, and return these names as a list. #!/usr/bin/perl -w use strict; my @perl_scripts = <*.pl> # * means "anything" here foreach my $perl_script (@perl_scripts) { # do something... } The angle brackets can also be used to read from files. This program copies the file "a" to the file "b". #!/usr/bin/perl -w use strict; open my $infile, "a" or die; open my $outfile, ">b" or die; while( my $nextline = <$infile> ) { print $outfile $nextline; } close $infile; close $outfile; The angle brackets can also be used to read an entire file at once, as an array of lines. To do this, simply evaluate the angle brackets in list context. The following program copies a to b using arrays. #!/usr/bin/perl -w use strict; open my $infile, "a" or die; open my $outfile, ">b" or die; my @lines = <$infile>; print $outfile @lines; close $infile; close $outfile; |
Practice with globs and file I/O |
Here, let's write a useful program - a simplied version of the grep program, which searches for things in files. Your program should be able to be run with two command line arguments - a file extension (like .pl) and a string to find. It should then print out all the lines in files with that extension that contain the string, in the following format: jpr@sulu (i211/lab4) $ ./mygrep.pl .txt hello
one.txt 5 : hello, this is a line in one.txt
two.txt 12 : At least you could have said hello, she said.
jpr@sulu (i211/lab4) $
That is, your program should print the file name and line number where each match occurs. What follows is a skeleton that may help you get started. #!/usr/bin/perl -w use strict; # get command line arguments. my ($extension, $str) = @ARGV; die unless $extension and $str; # make sure both are defined. my @files = # appropriate glob goes here foreach my $filename (@files) { # open the file, read all of its lines into an array, then close it. # use a for-loop to loop over the array (so you can keep track of line number) # match each line against $str to see if it matches. # if( $line =~ /$str/ ) { ... is one way to do that. # if it matches, print out the filename, line number, and the line that matches. } Do this:
Write mygrep.pl. Pay close attention to the requirements, and just ask if
you are unsure about anything. Make sure you put your file in the i211/lab4
directory.
|
Turn in your assignment |
As usual, let's make a tarball of your assignment files (make sure they are ALL in the lab4 directory!) For this lab, you should have the following files:
jpr@sulu (i211/lab4) $ cd .. jpr@sulu (i211) $ tar cvz lab4 > lab4.tar.gz bank.pl mygrep.pl jpr@sulu (i211) $ You should then download this Okay, that's it! Have a good weekend. |