print "\ntype something: "; $input1 = <STDIN>; chomp $input1; print "\ntype something else: "; chomp ($input2 = <STDIN>); print "This is the first thing you typed: $input1\n"; print "This is the second thing you typed: $input2\n";
print "Type a number or some text; you'll then see the number 1\n"; print "printed to the screen if you typed a non-zero integer, or nothing\n"; print "printed to the screen if you typed 0 or a string: "; chomp ($input = <STDIN>); print ($input > 0 || $input < 0);
print "Covert the following number of miles to kilometers: "; chomp ($mi = <STDIN>); $km = $mi * 1.609; print "$mi miles equals $km kilometers";
$password = "potatohead";
print "Please enter the password: ";
chomp ($input = <STDIN>);
if ($input eq $password) {
print "That's the correct password!\n";
}
else {
print "Sorry, that's not the right password.\n";
}
$count = 0;
while ($count < 5) {
$count++;
print "the value of \$count is $count\n";
}
print "What is 17 plus 26? ";
chomp ($input = <STDIN>);
until ($input == (17 + 26)) {
print "Sorry, that's incorrect. Please try again: ";
chomp ($input = <STDIN>);
}
print "That's correct! 17 plus 26 equals ", (17 + 26), "\n";
print "Type in an integer: ";
chomp ($input1 = <STDIN>);
print "Type in another integer: ";
chomp ($input2 = <STDIN>);
if ($input1 == $input2) {
print "$input1 and $input2 are the same number.\n";
}
elsif ($input1 == ($input2 + 1)) {
print "$input1 is one more than $input2\n";
}
elsif ($input2 == ($input1 + 1)) {
print "$input2 is one more than $input1\n";
}
else {
print "The two numbers are not equal.\n";
}
< when you mean lt. The former is a numeric comparison operator, and the latter is a string comparison operator. In the expression: "a" < "b", the operands are evaluated as numbers, since this is a numeric comparison operator. "a" and "b" have no value as numbers (they each evaluate to null). Since null is not less than null, the expression returns false. If you used lt instead of < the expression would return true, since "a" is less than "b" in a string context.
The foregoing type of problem comes up most frequently when performing assignments and when testing for equality. So it's very important 1. to not mix up the assignment operator = with either of the equality comparison operators == and eq, and 2. to not mix up the equality comparison operators with each other. These are probably the most common mistakes in Perl programming, so I'd like to illustrate with a couple of examples:
print "please type your name: ";
$name = <STDIN>;
chomp ($name);
print ("hello") if ($name eq "mike");
The above does a string comparison of $name with "mike". It will return true if they are the same string, and false if they are not. The code below does a numeric comparison of $name with "mike". Assuming the user types in a string, it will always return true, since both strings have a null value in a numeric context, and null equals null.
print "please type your name: ";
$name = <STDIN>;
chomp ($name);
print ("hello") if ($name == "mike");
Here's an example of incorrect use of the assignment operator:
print "please type your name: ";
$name = <STDIN>;
chomp ($name);
print ("hello") if ($name = "mike");
The last line of code assigns the string "mike" to $name. The assignment operation is successful, so it returns true. The if statement then prints the string "hello", regardless of what the user typed in.
A good way to guard against these kinds of mistakes is to run Perl with warnings turned on, by using the -w switch. This will result in a warning message whenever Perl detects something like strings being used as operands with numeric operators.
(1, 5.3, "hello", 2)
(1, $number, "hello", 2)
(1, $numberA + $numberB, "hello", 2)
($value, "The answer is $value")
@ (as opposed to the leading $ used to denote scalar variables). The same naming rules used for scalar variables apply to array variables: only letters, numbers, and underscores are allowed, and the first character following the @ cannot be a number.
@numbers = (1, 2, 3);
@letters = ("a", "b", "c");
print $letters[1];
Note that you use a $ instead of an @ when referring to a list element. If this seems confusing, just remember the following rule: whenever you want to refer to a single value, use a $ when referring to it, even if it's in an array.
@letters = ("a", "b", "c");
print "the second element of \@letters is $letters[1]\n";
$letters[1] = "chicken";
print "the second element of \@letters is now $letters[1]\n";
@numbers = (1,2,3,4,5,6,7,8,9,10);
Is the same as this:
@numbers = (1..10);
You can do the same thing with letters (a..z)
Rules of the list range operator:
@copy = @original;
@numbers = (1,2,3);
$name = "mike";
@stuff = ("hello", @numbers, $name);
This yields the following list assigned to @stuff: ("hello", 1, 2, 3, "mike")
@numbers = (1,2,3); $howMany = @numbers; print $howMany;
$howMany equals 3.
@numbers = (1,2,3); $howMany = $#numbers; print $howMany;
@numbers = (5, 7); ($var1, $var2) = @numbers; print "\$var1 is $var1\n; # prints 5 print "\$var2 is $var2\n; # prints 7
@greeting = ("my", "name", "is", "Mike");
print "@greeting"; # using quotes puts a space between each element
print @greeting; # without quotes, there are no spaces between the elements
When creating an array of strings, you can save yourself some typing by using the qw (quote word) operator:
@greeting = qw(my name is Mike); print "@greeting";
@words = ("this", "is", "a", "test");
print "@words\n";
@sortedWords = sort(@words);
print "@sortedWords\n";
Note that this does not alter the original list: @words is the same as it was before - only @sortedWords contains the alphabetically sorted list.
Also note that it always does an alphabetic sort. This means that numbers will be sorted alphabetically:
@numbers = (70,100,8); @sortedNumbers = sort(@numbers); print "\@sortedNumbers is: @sortedNumbers\n";
If you're trying to get your numbers sorted numerically, there are two ways to do it. One way is to use a fixed number of digits in each value so that they come out the way you want:
@numbers = ("070","100","008");
@sortedNumbers = sort(@numbers);
print "\@sortedNumbers is: @sortedNumbers\n";
If you use leading zeros on your numbers for this purpose, be sure to include quotes around them - otherwise Perl will treat them as octal numbers instead of strings.
The other, and usually more preferable, method allows for an actual numeric sort. If you want to use a sorting method other than the default alphabetic sort, the sort function allows you to use a statement block to specify the desired sorting parameters:
@numbers = (70,100,8);
@sortedNumbers = sort { $a <=> $b } @numbers;
print "\@sortedNumbers is: @sortedNumbers\n";
The code above uses the numeric comparison operator (also known as the spaceship operator), to numerically compare the list elements to each other. The sort function uses the return value of each comparison (1, 0, or -1) to figure out what order the numbers go in.
@backwards = ("backwards", "is", "array", "this");
@forwards = reverse(@backwards);
print "@forwards\n";
reverse is commonly used in combination with sort to provide a reverse alphabetic sorting.
@months = ("12","02","05","03","11");
@sortedMonths = reverse(sort(@months));
print "@sortedMonths\n";
$line = "This:is:a:string"; @words = split (/:/, $line, 3); print "@words\n";
The first argument to split is a pattern to search for (in this case, the colon character), enclosed by two slashes. The second argument is the name of the variable to search in. The third argument is optional, and it indicates the number of times to search for the pattern (the search is conducted left to right). If the third argument is omitted, split will find every occurrence of the pattern. The result of the split function is a list, which you can assign to an array variable.
You'll use split a lot. When you store data in a file, you'll use a character, such as a \t (a tab), or set of characters, to delimit fields of data on a line. For example:
Toppa\tMichael\t6\t0\n Smith\tJoe\t5\t10\n
When you want to read these fields into an array, you'll use split to separate them from each other.
@words = ("This", "is", "an", "array");
$line = join ("::", @words);
print "$line\n";
print scalar(localtime);
If you call localtime without scalar, it is automatically evaluated as an array. Here's an example:
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; $thisYear = $year + 1900; # In Perl, 1900 is year 0, so add 1900 to get the current year $thisMonth = $mon + 1; # $mon values are 0 to 11, so add 1 for the real month print "Today is $thisMonth/$mday/$thisYear\n";
The localtime function returns an array of numbers. In the above code we're assigning each of those numbers to a scalar variable. See p. 66 of your book for a breakdown of what each number represents.
Using arrays, you can print the current day and month:
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime;
@days = ('Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday');
@months = ('January','February','March','April','May','June',
'July','August','September','October','November','December');
$realYear = $year + 1900;
print "Today is $days[$wday], $months[$mon] $mday, $realYear\n";
@stuff = (1, "chicken", 1.23, "\"Having fun?\"", 9.33e+23);
$count = 0;
while ($count <= $#stuff) {
print "element $count is $stuff[$count]\n";
$count++;
}
Perl provides for and foreach, which allow you to more efficiently access to array elements.
In the foregoing example of while there are three things you need to control the loop:
With a for loop, you can put all of the loop control elements in a single line:
@stuff = (1, "chicken", 1.23, "\"Having fun?\"", 9.33e+23);
for ($count = 0; $count <= $#stuff; $count++) {
print "element $count is $stuff[$count]\n";
}
If you've used other programming languages, this is similar to a for...next loop. In Perl, the next syntax is not used to close the statement block.
When doing a loop that depends on iteration, it's generally advisable to use a for loop instead of a while loop. When using while, it's easy to forget to iterate the loop.
The most straightforward way to loop through an array is with the foreach statement:
@words = ("Here", "is", "a", "list");
foreach $word (@words) {
print "$word\n";
}
Note the variable $word. It's a "placeholder" that holds the value of the current array element as foreach loops through the array. I did not have to use the variable name $word - I could have used anything I wanted: $item, $x, etc.
In the above code, $word is a local variable, which means its value is held only for the duration of the loop. If $word had a value before the loop began, that value is restored when the loop ends. For example:
$word = "Howdy";
print "\$word is initially: $word\n";
@words = qw(Here is a list);
foreach $word (@words) {
print "\$word is now: $word\n";
}
print "\$word is again: $word\n";
To avoid confusion, it's generally not a good idea to have a global variable ($word as it exists outside the foreach loop) use the same name as a local variable. It's too easy to get them confused, and if you did use the same variable name for both, you wouldn't be able to refer to your global variable within your foreach loop, as it's value is temporarily replaced by the local variable.
We'll talk more about local variables when we get to the topic of subroutines in a later class.
print "what is your name? ";
chomp ($input = <STDIN>);
$count = 0;
@names = qw(Mike Joe Bob Fred);
while ($count <= $#names) {
if ($names[$count] eq $input) {
print "I found your name on my list: $names[$count]\n";
last;
}
else {
print "Your name is not $names[$count]\n";
}
$count++;
}
for ($count = 0; $count <= 5; $count++;) {
next if ($count == 3);
print "count is $count\n";
}
$count1 = 0;
DONE: while ($count1 < 10) {
$count2 = 0;
while ($count2 < 10) {
$count2++;
last DONE if ($count1 == 5 && $count2 == 7);
}
$count1++;
}
print "$count1" . "$count2";
The quiz will be open note and open book, but you will not have time to do a lot reading. This means that it's most important to understand the concepts we have covered so far in class, and that it's less important to memorize all the details of syntax. This does not mean your syntax can be wrong! It simply means that it's easier to check up on a detail in your notes during a quiz than it is, for example, to try figuring out a basic Perl concept. For example, before coming in to the quiz you should already have a solid understanding of how a for loop works and what it's used for - you won't have time to read up it during the quiz. But you can bookmark the page that provides the syntax and refer to it if you need to.
While the quiz is open book, it is not open neighbor. Conversation is not allowed during the quiz - this includes online chats!
The quiz will consist of four questions. Each one will ask you to write a short script, or make corrections to a script that has errors in it.
I have to rescind a statement I made in the first lecture. I said that one of the questions would come straight from your lab assignments. I've decided not to do that. Since the test is open book and open note, and the answers to the lab assignments are in my online lecture notes, that would be too easy!
If you have a laptop computer you're willing to bring to class, please to do so. That way we'll hopefully have enough computers for everyone to take the quiz in B-2. If we don't have enough computers, then some of you can take the quiz in the open lab next door.
@me which contains four elements: your first name, your last name, your age, and the name of the town you are from.
$sumAll
$sumEven
$count to iterate a for loop 10 times.
$count to $sumAll
$count to $sumEven if $count is an even number.
$sumAll and $sumEven
@me (from question 1) in reverse alphabetical order. Then use a foreach loop to print each element.
@pages = qw(index.html chapter1.html chapter4.html chapter8.html chapter1.html index.html chapter4.html chapter3.html); $previous = "";
@pagesSorted that is an alphabetically sorted copy of @pages
$previous as the last statement inside the loop. Then, as the first statement inside the loop, you can compare the current array element to the value of $previous.