Reading:
Deitel Chapter 3 (3.1 - 3.6)
In the last lecture
we saw how to write a program to execute a series of commands. The
perl interpreter starts at the beginning of the program, and executes
the statements in order, until it reaches the end of the program.
Now we learn how
to get our programs to make decisions based on the data available
to them.
Comparisons
Let's review some
expressions and see what they evaluate to
program 1
| 33 == 33; # true
8 == 3 +3; # false
5 != 4; # true
"Hello World" eq "Hello World"; # true
"yes" eq "no"; # false
"brazil" ne "Brazil"; # true
|
download
we can also compare
variables:
program 2
|
$a == $a; # always true
$x = 5;
$y = 10;
$x == $y - 5; # true
|
download
other numeric
comparisons:
program 3
| $x < $y; # less than
$x > $y; # more than
$x <= $y; # less than or equal
$x >= $y; # more than or equal
|
download
other string comparisons:
program 4
| $x lt $y; # alphabetically before
$x gt $y; # alphabetically after
$x le $y; # alphabetically before or equal
$x ge $y; # alphabetically after or equal
|
download
| a common mistake is using the wrong comparison for the variable type; make sure
ou use numberic comparisons for numbers and string comparisons for strings.
|
| don't confuse the assignment operator = with the equality comparison ==
|
| a very common mistake is to compare two strings using ==
|
In Perl, Truth
is defined as follows:
|
- The string "0" is False.
- The empty string ("" or '') is False
- The empty list is False
- The undefined value is False (e.g. an uninitialized variable)
- A number is false if it converts to string "0".
- Everything else is True.
|
program 5
| #!/usr/local/bin/perl -w
# logical_expressions.pl
$a; # FALSE (not yet defined)
$a = 1; # TRUE
$b = 0; # FALSE
$c = ""; # FALSE
$d = 'true'; # TRUE
$e = 'false'; # TRUE (watch out! "false" is a nonempty string)
$f = ' '; # TRUE (a single space is non-empty)
$g = "\n"; # TRUE (a single newline is non-empty)
@h = (); # FALSE array
$i = 0.0; # FALSE (converts to string "0")
$j = '0.0'; # TRUE (watch out! The string "0.0" is not the same as "0")
|
download
Truth and
the Comparison Operations
|
- If a comparison operation is true, it returns 1.
- If a comparison operation is false, it returns undefined.
|
program 6
| $a = 4 == 1+3;
print "The answer is $a","\n";
|
download
Conditional
Execution
Imagine we want
to write a simple blast output evaluation program, for determining
if individual blast hits are better than some predetermined threshold:
We have a very
simple algorithm, expressed in pseudocode as:
| Step 1: IF blast e value is LESS THAN OR EQUAL TO 1e-50
THEN this is a significant hit - notify user and carry on
to step 2
Step 2: Program is finished - notify user
|
This is how we
express this in perl:
Using the
if keyword
program 7
| # the variable $expect should be
# set previously in this program
if ($expect < 1e-50) {
print "Good match!\n";
}
# end of program
print "Done!\n";
|
download
(This is just
a fragment of a program - it will not do much on it's own as the assumption
is this piece of code is embedded in a larger program)
The more general
form of this is
if ( expression
) { statement1 , statement2 , statement3 , ...
statementN }
the program above
can also be written
program 8
| print "Good match!\n" if $expect < 1e-50;
|
download
The more general
form of this is
statement
if test expression
The preceeding
construct requires parentheses and a statement block {}
the second construct
does not.
A statement block
allows you to include multiple statements to be conditionally executed
Unless
This is the converse
of if
program 9
| unless ($expect < 1e-50) {
print "Not good enough!\n";
}
|
download
which can also
be written as:
program 10
| print "Not good enough!\n" unless $expect < 1e-50;
|
download
The else keyword
Now imagine we
want to program a slightly different algorithm.
Again, expressed
in pseudocode :
| Step 1:
IF blast e value is LESS THAN OR EQUAL TO 1e-50
THEN this is a significant hit - notify user, and increment the
count of good matches and carry on to step 2
OTHERWISE
this is not a significant hit according to our criteria.
notify the user, and carry on to step 2
Step 2:
This is the end of the program. notify the user.
|
program 11
| if ($expect < 1e-50) {
print "Good match!\n";
$good_matches++;
}
else {
print "Expectation value does not meet threshold\n";
}
# end of program - notify user
print "Done!\n";
|
download
If-elsif-else
constructs
Let's put all
the above into a complete program, and introduce a new construct,
elsif
program 12
| #!/usr/local/bin/perl
# evaluate_expect.pl - evalautes user provided expect scores
# get the expect value from the unix command line
$expect = shift @ARGV;
# check the user has entered something
if (!defined($expect)) {
die("Usage: evaluate_expect.pl EXPECT-VALUE");
}
if ($expect < 1e-50) {
print "Good match!\n";
$good_matches++;
}
elsif ($expect < 1e-20) {
print "Reasonable match\n";
}
elsif ($expect < 1e-4) {
print "borderline match\n";
}
else {
print "poor match\n";
}
|
download
Flowcharts
As a visual aid,
you can draw flow charts depicting decision points and flow
of control through your program. Deitel has an extensive discussion
of this in chapter 3. The parts about flow charts are not compulsory
reading, some people find them useful ways to think about program
flow.
| /\
/ \
/ \
/ is \ +-------+
/ $e \ YES | |
START ----> < < > ------> | Good | ----------> END
\ 1e-50 / | Match | ^
\ ? / +-------+ |
\ / |
\ / |
\/ |
| +-----------+ |
| | Doesn't | |
+------------> | meet |----------+
NO | threshold |
+-----------+
|
Logical
Operators
Boolean
logic
We have already
seen the and operator and the or operator.
Often the symbols
&& and || are used in place of and/or. these
operators have higher precedence.
Once the truth
can be determined, the remainder of the expression is not evaluated.
We can also use
the not operator, or the higher precedence !
Conditional
evaluation
program 13
| if ( 1 == 1 && 2 == 1 ) { ..... }
|
download
the 2==1
part of the expression is never evaluated; it doesn't need to be.
This means we
can write things like this
program 14
| $expect >= 0 or die("logic error; expect = $expect is invalid");
|
download
So long as the
$expect >= 0 expression evaluates to TRUE, the second part
of the expression is not evaluated. If the first part evaluates to
FALSE then the second expression is evaluated and the program dies
with an error message.
Pattern
Matching I
Pattern matching
is covered in more detail in a future lecture.
program 15
| $a = 'gatttccaa';
if ($a =~ /ttt/) {
print "contains three t's" ;
}
if ($a =~ /gaattc/) {
print "contains an EcoRI site" ;
}
|
download
here is another
example:
program 16
| #!/usr/local/bin/perl
# characterize_sequence.pl
print "Type in a sequence (all on one line):\n";
$sequence = <STDIN>;
chomp $sequence;
$sequence = lc($sequence); # make sequence lowercase
if ($sequence =~ /n/) {
print "sequence contain at least one gap\n";
}
if ($sequence =~ /atg/) {
print "sequence contains possible translation start\n";
}
if ($sequence =~ /gaattc/) {
print "sequence contains EcoRI site\n";
}
print "Done!\n";
|
download
Nested
ifs and indentation
program 17
| # $test1 and $test2 are assumed to be set
# previously in the program
if ( $test1 ) {
if ($test2) {
print "test1 and test2 are both TRUE";
}
else {
print "test1 is TRUE and test2 is FALSE";
}
}
else {
if ($test2) {
print "test1 is FALSE and test2 is TRUE";
}
else {
print "test1 and test2 are both FALSE";
}
}
|
download
Exercises:
Write a script
that divides two numbers entered by the user. it should check that
the divisor is not zero to prevent a division by 0 error.
optional:
draw the following
code as a flow chart
program 18
| #!/usr/local/bin/perl
# pentagon.pl
print "Welcome to the Pentagon\n\n";
print "Please Enter your name:\n";
$name = <STDIN>;
chomp $name;
print "Please Enter your password:\n";
$password = <STDIN>;
chomp $password;
$authrorization_level = 0;
if ($name eq "") {
print "You did not enter a name!\n";
print "Goodbye\n";
exit;
}
# allow guest logins
if ($name eq "guest") {
$authorization_level = 1;
}
# ordinary user logins
if ($name eq "Tony Blair" &&
$password eq "Cherie") {
$authorization_level = 2;
}
# privileged user logins
if ($name eq "George W Bush" &&
$password eq "DUBYA") {
$authorization_level = 1000;
}
if (!$authorization_level) {
print "You are not authorized to use this system\n";
print "Goodbye!\n";
exit;
}
print "You are an authorized user.\n";
print "Your security clearance level is $authorization_level.\n";
print "What do you want to do today, $name?\n";
$command = <STDIN>;
chomp $command;
if ($command eq "start world war III") {
if ($authorization_level >= 1000) {
print "Certainly sir!\n";
# run the nuclear missle subroutine
launch_nuclear_missiles();
print "Have a nice day!\n";
exit;
}
else {
print "You are not authorized to $command\n";
exit;
}
}
|
download
Chris Mungall cjm@fruitfly.org
Berkeley
Drosophila Genome Project