<<

Lecture #7 List, Array, and Hash

What is a list? A Perl list is simply a collection of scalar values, separated by a comma (,) in a pair of parentheses. Items in a list do not have to be the same kind. They could be a mix of numbers and strings. The following is an example of list whose elements are all integers.

(3, 8, 6, 7, 0, 5, 4, 9, 1, 2)

The following is sample list of strings.

("Pomona", "Long Beach", "West Hills", "Irvine");

The following is a list of mixed numbers and strings.

(245, "Perl Programming", 246, "PHP Programming", 247, "Python Programming");

When all elements in a list are consecutive numbers or letters, you can use the range operator (..) to represent them.

(1 .. 100) (A .. Z)

The following is a complete code that demonstrates how to use the range operator to define Perl lists. It also uses foreach loops to iterate through lists. By the way, the lc() function change every letter to lower case.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

foreach $ (A .. Z) { print lc($c), "
"; }

foreach (0..9) { print $_, "
"; }

print end_html;

What is An array is group of items that have something in common, such as Spring, Summer, Fall, and an Array? Winters. They are four individual items; however, they are also one of the seasons. You can, therefore, group these four items into an array called season. Items in an array may have sequence as well. Spring, for instance, come before Summer, followed by Fall, and then Winter. Most programming books refer items in an array as “elements” or “components”. All items in a Perl arrays are placed in sequence. Sequence of items in array is in an order known as “index” or “key”.

The official syntax to declare a Perl array is to declare a variable which is prefixed by an “@” sign. The variable, thus, becomes the identifier (name) of the array. The following depicts the syntax:

192

@arrayName

Elements (items) of the array is populated, one by one, using the following syntax, where index is an integer starting at 0.

$arrayName[index] = "value"

The following is a complete script that illustrates how to declare a string array and then add four elements to it.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@season;

$season[0] = "Fall"; $season[1] = "Winter"; $season[2] = "Spring"; $season[3] = "Summer";

print end_html;

Similarly, the following declare a numeric array named “x”, and then populate it with 4 elements: 8, 6, 4, and 2. Their indexes are 0, 1, 2, and 3 respectively.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@x;

$x[0] = 8; $x[1] = 6; $x[2] = 4; $x[3] = 2;

print end_html;

In Perl, there is a shorthand way to create arrays. You can declare an array by first creating a list and then assigning the entire list to a variable which is prefixed by an “@” sign. The variable, thus, becomes the identifier (name) of the array. The following depicts the syntax:

@arrayName = (elements);

The following example creates a string array named “season” and a numeric array named “x”. The “season” array has four elements: “Spring”, “Summer”, “Fall”, and “Winter”. The “x” array has 10 elements. Both arrays are assigned a Perl list of items.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@season = ("Spring", "Summer", "Fall", "Winter");

@x = (4, 7, 5, 8, 2, 0, 1, 9, 3, 6);

193 print end_html;

An array must contain at least two items; therefore, arrays are not scalar. In order to distinguish an array from a scalar variable, which is prefixed with a dollar sign ($), Perl uses an “at” sign (@) to denote the beginning of array name.

Many programming languages, such as C++, C#, and , do not permit an array to have elements of different types. Perl, does not have such limit. Elements in a Perl array can be a mix of numbers and strings. The following demonstrates how to create a Perl array of different types. After all, a Perl array is simply a grouped list of scalar variables. Each element in the array is an individual value.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@a; # declare

$a[0] = "Apple"; # populate $a[1] = 6.1; $a[2] = 'k'; $a[3] = 2;

print end_html;

Identifying The following is the syntax for identifying the nth value of a given array: elements in an Array $arrayName[n-1]

According to the following statement, the first value of the season array is represented by $season[0], the second is $season[1], the third is $season[2], and the forth is $season[3]. The number inside square brackets is sometimes referred to as the key or index.

@season=("Spring", "Summer", "Fall", "Winter");

In the following example, the print $season[2]; line tells the computer to display the third item, which is Fall. For example:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@season=("Spring", "Summer", "Fall", "Winter");

print $season[2];

print end_html;

The output in a Web browser is:

The ouput of the following is: k.

194

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@a;

$a[0] = "Apple"; $a[1] = 6.1; $a[2] = 'k'; $a[3] = 2;

print $a[2];

print end_html;

You can assign a new value to an existing item of an array. Each element in an array is a scalar variable; therefore, they behave in the same manner as any scalar variable. You just have to stick to the itemization to specify which item is the one to be assigned a new value. In the following example, the $weekdat[0]=”Monday”; line tells the computer to assign a new value “Monday” to the first element as an replacement of “Mon”, thus the print $weekday[0]; line will display Monday on the screen.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@weekday=("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); print $weekday[0], "
";

$weekday[0]="Monday"; print $weekday[0], "
";

print end_html;

The output in a browser is :

Repetition structures, such as the , are useful structures to iterate through a Perl array to retrieve elements. The following example illustrates how to use a for loop for this purpose.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@list = ("Apple", 169.75, "student", 31);

$size = @list; # get total number of elements

for ($i=0; $i < $size; ++$i) { print "$i $list[$i]", br;

195 }

print end_html;

The output looks:

0 Apple 1 169.75 2 student 3 31

In Perl, you can simply create a variable and assign the array to it. Perl will then store the “size” of array in the variable. The “size” of the array is the total number of elements the array has. Some books refer the term “size” to “length”.

$size = @weekday;

Another way to find the size of an array is to call the scalar() function with the following syntax.

scalar(@arrayName)

The following is another example that uses a for loop to iterate through the entire “weekday” array and print each element one by one.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@weekday=("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");

$size = @weekday; #find the size of array

for ($i=0; $i<$size; $i++) { print $weekday[$i], br; }

print end_html;

You can also use the to replace the research the same goal. For example, you can rewrite the above script to:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@list=("Apple", 169.75, "student", 31);

$size = @list;

$i=0;

while ($i < $size) { print "$i $list[$i]", br; $i++; }

print end_html;

196 The foreach loop is a repetition frequently used to process Perl lists and hashes. Similar to the for loop, foreach steps through each element of an array using an . Rather than using a scalar as that iterator (like the for loop), foreach uses the array itself. In the following example, $c is a variable that will represent the value in an iteration.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@car=("Toyota", "Nissan", "Mazda");

foreach $c (@car) { print $c, br; }

print end_html;

The output looks:

Toyota Nissan Mazda

The following example declares a scalar variable $n as the iterator, which will take turn to represent each value of the array.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard); print header, start_html;

@number=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

foreach $n (@number) { $n = $n*2;

print $n, " "; }

print end_html;

The $n = $n*2; line tells the computer to multiple the current value with 2 and then use the product as new value. Consequently the output will look like this:

2 4 6 8 10 12 14 16 18 20

Here is another example. The foreach serves as an iterator to step through each element of the “weekday” array. The Perl $_ variable is known as the “default input and space”. $_ is a special variable which contains the value of the last matched expression; therefore, it can be used to represent the element that was just retrieved.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@weekday = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");

foreach (@weekday)

197 { print $_, br; }

print end_html;

Here is another example which retrieves the current “day of week” value from the localtime() function, $dt[6]. The value is then used to retrieve an element of the “wd” array.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@dt = localtime(); # assign date time values to dt array

@wd = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");

print $dt[6] . ":" . $wd[$dt[6]];

print end_html;

The qw The “quote word” function, qw(), is desgined to generate a list of words. You can also use function CGI.pm function, qw, to assign a list to an array. The following depicts the syntax. There is no comma and quotes required between any two words.

@arrayName = qw(item1 item2 item3 ..... itemn);

The following two statements present two different ways to generate exactly the same array in Perl.

@state = ("California", "Pennsylvania", "Washington");

@state = gw(California Pennsylvania Washington);

The following example illustrate how it work. This sample code also demonstrates how to use a while loop to retrieve every element of an array.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@fruit = qw(apple orange banana grape tangerine);

$size = @fruit;

$i = 0;

while ($i<$size) { print $fruit[$i] . "
"; $i++; }

print end_html;

The output in a Web browser is :

198

The following is another example.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@arr2 = qw(CIS MIS IST CET);

foreach (@arr2) { print $_, "
"; }

print end_html;

Multi- When elements of an array are arrays, namely nested arrays, the array has multiple dimensions. Dimensional The following example creates three individual arrays, campus1, campus2, and campus3, and Arrays then another array named course to store them. In the other words, the “course” array contains three arrays as elements. The “\” sign in “\@campus1”, “\@campus2”, and “\@campus3” is used to escape the sequence.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@campus1; $campus1[0] = 'Pomona'; $campus1[1] = 'Perl'; $campus1[2] = 'Janet Chen';

@campus2; $campus2[0] = 'Long Beach'; $campus2[1] = 'PHP'; $campus2[2] = 'Lauren Lee';

@campus3; $campus3[0] = 'West Hills'; $campus3[1] = 'Python'; $campus3[2] = 'Helen Huang';

@course; $course[0] = \@campus1; $course[1] = \@campus2; $course[2] = \@campus3;

print end_html;

The following is the shorthand way.

#!"X:\xampp\perl\bin\perl.exe"

199 use CGI qw(:standard);

print header, start_html;

@campus1 = ('Pomona', 'Perl', 'Janet Chen'); @campus2 = ('Long Beach', 'PHP', 'Lauren Lee'); @campus3 = ('West Hills', 'Python', 'Helen Huang');

# array that contains arrays as elements @course = (\@campus1, \@campus2, \@campus3);

print end_html;

A more sophisticated method to do this is to put the elements of these three arrays in the list of the course array. In Perl, square brackets ([]) creates an array reference. [$scalar, $scalar] creates an array reference with two items in it. The following demonstrates how it works.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@course = (['Pomona', 'Perl', 'Janet Chen'], ['Long Beach', 'PHP', 'Lauren Lee'], ['West Hills', 'Python', 'Helen Huang']);

print end_html;

The following is the syntax to retrieve values of a two-dimensional array individually, where n is the index (or key) of the parent (layer 1) elements, m is the index of child (layer 2) elements:

$parentArrayName[n]->[m] or simply

$parentArrayName[n][m]

The following is a complete script that illustrates how to retrieve values of elements from a two- dimension array.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@campus1; $campus1[0] = 'Pomona'; $campus1[1] = 'Perl'; $campus1[2] = 'Janet Chen';

@campus2; $campus2[0] = 'Long Beach'; $campus2[1] = 'PHP'; $campus2[2] = 'Lauren Lee';

@campus3; $campus3[0] = 'West Hills'; $campus3[1] = 'Python'; $campus3[2] = 'Helen Huang';

@course; $course[0] = \@campus1;

200 $course[1] = \@campus2; $course[2] = \@campus3;

print $course[0]->[0] . "
"; print $course[0]->[1] . "
"; print $course[0]->[2] . "
";

print $course[1]->[0] . "
"; print $course[1]->[1] . "
"; print $course[1]->[2] . "
";

print $course[2]->[0] . "
"; print $course[2]->[1] . "
"; print $course[2]->[2] . "
";

print end_html;

The following uses nested for loops to iterate through every elements of the two-dimensional array. The instructor creates another variable $s, and use it to store the size of each child array.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@campus1; $campus1[0] = 'Pomona'; $campus1[1] = 'Perl'; $campus1[2] = 'Janet Chen';

@campus2; $campus2[0] = 'Long Beach'; $campus2[1] = 'PHP'; $campus2[2] = 'Lauren Lee';

@campus3; $campus3[0] = 'West Hills'; $campus3[1] = 'Python'; $campus3[2] = 'Helen Huang';

@course; $course[0] = \@campus1; $course[1] = \@campus2; $course[2] = \@campus3;

$size = @course;

for ($i = 0; $i<$size; $i++) {

$s = @{$course[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $course[$i][$j] . "
"; }

}

print end_html;

The following is another example.

201 #!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@campus1 = ('Pomona', 'Perl', 'Janet Chen'); @campus2 = ('Long Beach', 'PHP', 'Lauren Lee'); @campus3 = ('West Hills', 'Python', 'Helen Huang');

# array that contains arrays as elements @course = (\@campus1, \@campus2, \@campus3);

$size = @course;

for ($i = 0; $i<$size; $i++) {

$s = @{$course[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $course[$i]->[$j] . "
"; }

}

print end_html;

Here is one more example.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@course = (['Pomona', 'Perl', 'Janet Chen'], ['Long Beach', 'PHP', 'Lauren Lee'], ['West Hills', 'Python', 'Helen Huang']);

$size = @course;

for ($i = 0; $i<$size; $i++) {

$s = @{$course[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $course[$i]->[$j] . "
"; }

}

print end_html;

By the way, every child array may have inequal number of elements. In the following example, there are three child arrays. Their sizes are 4, 5, and 3 respectively.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

202 @brand = (['Car', 'Toyota', 'Nissan', 'Honda'], ['Smart Phone', 'HTC', 'Samsung', 'Motorola', 'Nokia'], ['TV', 'Sony', 'Toshiba']);

$size = @brand;

for ($i = 0; $i<$size; $i++) {

$s = @{$brand[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $brand[$i]->[$j] . "
"; }

}

print end_html;

Apply the same programming logic and you can create a three dimensional array. For example:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

# 3rd layer @cis245 = ("CIS245", "Perl Programming", "3"); @cis246 = ("CIS246", "PHP Programming", "3"); @cis247 = ("CIS247", "Python Programming", "3");

@tcm102 = ("TCM102", "Intro to Linux", "3"); @tcm103 = ("TCM103", "Linux Administration", "3"); @tcm104 = ("TCM104", "Linux Scripting", "3");

# 2nd layer @cis = (\@cis245, \@cis246, \@cis247); @tcm = (\@tcm102, \@tcm103, \@tcm104);

# 1st layer - parent @course = (\@cis, \@tcm);

print end_html; or simply:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@course = ( #layer 1 [ # layer 2 ["CIS245", "Perl Programming", "3"], # layer 3 ["CIS246", "PHP Programming", "3"], # layer 3 ["CIS247", "Python Programming", "3"] # layer 3 ], [ # layer 2 ["TCM102", "Intro to Linux", "3"], # layer 3 ["TCM103", "Linux Administration", "3"], # layer 3 ["TCM104", "Linux Scripting", "3"] # layer 3 ]

203 );

print end_html;

To retrieve the value, use the syntax:

$parentArrayName[i]->[j]->[k] or simply

$parentArrayName[i][j][k]

The following is an example.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

my @course = ( [ ["CIS245", "Perl Programming", "3"], ["CIS246", "PHP Programming", "3"], ["CIS247", "Python Programming", "3"] ], [ ["TCM102", "Intro to Linux", "3"], ["TCM103", "Linux Administration", "3"], ["TCM104", "Linux Scripting", "3"] ] );

$size = @course;

for (my $i=0; $i < $size; $i++) {

$s1 = @{$course[$i]};

for (my $j=0; $j < $s1; $j++) {

$s2 = @{$course[$i]->[$j]};

for (my $k=0; $k < $s2; $k++) { print $course[$i]->[$j]->[$k], " "; } print "\n
"; } }

print end_html;

The output looks:

204

The child array does not have to be equal in size. In the following example, the size of child arrays are 3, 5, and 2 respectively.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@food = ( [ ["apple", "orange", "banana"] ], [ ["brocolli", "spinach", "cabbage", "carrot", "onion"] ], [ ["shrimp", "crab"] ] );

$size = @food;

for (my $i=0; $i < $size; $i++) {

$s1 = @{$food[$i]};

for (my $j=0; $j < $s1; $j++) {

$s2 = @{$food[$i]->[$j]};

for (my $k=0; $k < $s2; $k++) { print $food[$i]->[$j]->[$k], " "; } print "\n
"; } }

print end_html;

Hash Each item in an array is indexed by a number (starting at 0) by default. However, if you wish to use a string to index array items instead of numbers, you need to use hashes. A hash is a Perl construct that allows a programmer to assign a unique name (or a “key”) to its value. Hash keys are usually strings like “PA”, “app”, and “124”. However, unlike Perl arrays, keys of a hash can be numbers or strings or a combination of them.

The following is the syntax to declare a hash in Perl.

%hashName=(key1, value1, key2, value2, ..., keyn, valuen);

205 When creating a Perl hash, it is necessary to enclose paris of key/value within paretheses. The number of items should be an even number because an element of a hash consists a key and a value. Notice that hash names begin with a percentage sign (%) in order to distinguish from arrays. For example:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%airport=("TPE", "Taipei", "LAX", "Los Angeles", "NRT", "Narita"); TPE is the index, while Taipei is the value

print end_html;

Notice that in the %airport hash elements are listed on separate lines. This is done so we can see what is being entered. The compiler does not mind if the elements are on one line or four lines. If you have a long hash, you may want to put each element on a separate line so you are positive you did not miss any elements. By the way, elements of a hash can be accessed only via their keys, and keys within a hash must be unique.

The syntax to retrieve hash values is:

$hashName{key}

For example,

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%airport=("TPE", "Taipei", "LAX", "Los Angeles", "NRT", "Narita");

print $airport{"TPE"};

print end_html;

Some books refer Perl hashes to “special kind of associative arrays” because keys in a Perl hash are not consecutive integers starting from 0. The term “” refers to an array whose keys are strings. The following illustrates how to create an associative array in Perl. The “state” array has three keys: “CA”, “PA”, and “WA”. They are strings. Unlike a regular Perl array which is prefixed with “@” sign, a Perl associative array is prefixed with “%” sign.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%state; $state{"CA"} = "California"; $state{"PA"} = "Pennsylvania"; $state{"WA"} = "Washington";

print $state{"PA"};

print end_html;

206 The following produces exactly the same output as the above, yet it creates a Perl “hash”.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%state =("CA", "California", "PA", "Pennsylvania", "WA", "Washington");

print $state{"PA"};

print end_html;

If a hash key or value is a string, surround it with a pair of quotations, even if they look numbers to you. In the following example, 714, 949, and 818 are numbers without the double quotes. Yet, they are actually enclosed by a pair of doublequotes and are considered string literals.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%area=("714", "Anahiem", "949", "Irvin", "818", "Torrance");

print $area{"818"}, "
"; print $area{949}, "
"; print $area{'714'};

print end_html;

Interestingly, the syntax to get a value from a Perl hash, as shown below, does not strictly require the use of quotes. The print $area{"949"}; line tells the computer to display the value of the item indexed by 949 (which is Irvin). However, print $area{949}; seems to work fine, too, as illustrated above.

$HashName{key};

Data of different types may co-exist in the same hash. In the following script, “zip” hash contains string an int types. Pay attention to the index 91210 and $zip{"91210"}. Ironically, both $zip{"91210"} and $zip{91210} work.

#!"X:\xampp\perl\bin\perl.exe use CGI qw(:standard);

print header, start_html;

%zip=(91210, "Hollywood", "91630", "Westwood", 90430, "Cypress");

print $zip{"91210"}, "\n
"; print $zip{"91630"}, "\n
"; print $zip{90430}, "\n
";

print end_html;

A hash key can by string literals that references a number. In the following example, “Beth” is the index of 94, “John” is the index of 95, and “Kathy” is the index of 89.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

207 print header, start_html;

%scores = ("Beth", 94, "John", 95, "Kathy", 89, "Peter", 88);

print $scores{"Beth"}, "\n
"; print $scores{"John"}, "\n
"; print $scores{"Kathy"}, "\n
"; print $scores{"Peter"}, "\n
"; print $scores{Peter}, "\n
";

print end_html;

To retrieve Kathy’s score, use $scores{"Kathy"};. Be sure to use curly braces rather than square brackets. Ironically, both $scores{"Peter"}and $scores{Peter} seems work.

In addition to the above method, Perl supports another way, known as an object-oriented approach, to define a hash. The syntax is:

%hashName = ("key" => "value" )

Interestingly, key work with or without the quotes, as shown below. The => operator automatically quotes the left side of the argument, so the enclosing of keys with quotes are optional.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%urls = ( CNN => "http://www.cnn.com", FOX => "http://www.fox.com", HBO => "http://www.hb0.com", PBS => "http://www.pbs.com" );

print $urls{CNN}, "\n
", $urls{"CNN"}, "\n
"; print $urls{PBS}, "\n
", $urls{"PBS"};

print end_html;

Recall that in one of the previous lectures, you learned to specify attribute of a given CGI.pm routine and you had seen something similar to the following statement. Yet, you may not notice that they are designed using object-oriented programming in Perl. Does the following make sense to you now?

start_html({ -title=>"my title", -bgcolor=>"red" });

The following example uses CGI.pm to creates a hyperlink that takes you to www.cnn.com.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%urls = ( CNN => "http://www.cnn.com", FOX => "http://www.fox.com", HBO => "http://www.hbo.com" );

print a({-href=>$urls{CNN}},"CNN"), br; print a({-href=>$urls{FOX}},"FOX"), br; print a({-href=>$urls{HBO}},"HBO"), br;

208

print end_html;

The output in a Web browser is:

Perl provides the keys construct, which returns an array consisting only of the keys of the named hash. The syntax is:

keys %hashname

In the following example, the @k = keys $urls; statement assigns the keys of every hash value to the @k array; therefore, they can be used to reference each of the hash value later. In the following example, $k[0], $k[1], $k[2], and $k[3] representes the elements of the @key array. They are in the order of “CNN”, “FOX”, “HBO”, and “PBS”.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%urls = ( CNN => "http://www.cnn.com", FOX => "http://www.fox.com", HBO => "http://www.hbo.com", PBS => "http://www.pbs.com");

@k = keys %urls;

print a({-href=>$urls{CNN}}, $k[1]), br; print a({-href=>$urls{FOX}}, $k[2]), br; print a({-href=>$urls{HBO}}, $k[0]), br; print a({-href=>$urls{PBS}}, $k[3]), br;

print end_html;

The following is the non-object-oriented version, for the sake of comparison. It produces exactly the same result as the above script.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%urls = ( "CNN", "http://www.cnn.com", "FOX", "http://www.fox.com", "HBO", "http://www.hbo.com", "PBS", "http://www.pbs.com" );

@k = keys %urls;

print a({-href=>$urls{CNN}}, $k[1]), br; print a({-href=>$urls{FOX}}, $k[2]), br; print a({-href=>$urls{HBO}}, $k[0]), br; print a({-href=>$urls{PBS}}, $k[3]), br;

209 print end_html;

The following example illustrates how to use a for loop to iterate through a Perl hash. The $state hash has three key=>value pairs. The @k = keys(%state) statement defines the @k array to retrieve only the keys from %state hash, namely, it is equivalent to a individual @k=("CA", "TX", "NV"); statemen. The instructor uses the for loop to display the keys and values of %state as a sentence.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%state=(CA => "California", TX => "Texas", NV => "Nevada");

@k = keys(%state);

for ($i=0; $i<@k; $i++) { print "$k[$i] is $state{$k[$i]}", br; }

print end_html;

The output is

NV is Nevada CA is California TX is Texas

The following is the non-object-oriented version.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%state=("CA", "California", "TX", "Texas", "NV", "Nevada");

@k = keys(%state);

for ($i=0; $i<@k; $i++) { print "$k[$i] is $state{$k[$i]}", br; }

print end_html;

The foreach loop is a control structure that can be sued to loop through a hash in Perl. This is probably a more efficient way to retrieve values from a hash. In the following example, the instructor uses a foreach loop to retrieve values from (keys %urls). Every value of a hash can be retrieved by enclosing its key in curly brackets in the format of $hashName{key}.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%urls = ( CNN => "http://www.cnn.com", FOX => "http://www.fox.com", HBO => "http://www.hbo.com",

210 PBS => "http://www.pbs.com");

foreach (keys %urls) { print a({-href=>$urls{$_}}, "$_"), br; }

print end_html;

The output in a Web browser is:

Here is a quick overview of some Perl consructs you can use when working with hashes.

delete $hashName{$key} Deletes the specified key/value pair, and returns the deleted value. exists $hashName{$key} Returns 1 (means true) if the specified key exists in the hash. values %hashName Returns a list of values for that hash

In the following example, the instructor uses the values construct to get a list of values from the %urls hash.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%urls = ( "CNN", "http://www.cnn.com", "FOX", "http://www.fox.com", "HBO", "http://www.hbo.com" );

foreach $v (values %urls) { print $v, br; }

print end_html;

Returns:

http://www.hb0.com http://www.cnn.com http://www.fox.com

The following example demonstrates how others work.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

%state=("CA", "California", "TX", "Texas", "NV", "Nevada");

print exists $state{'CA'}, "
";

211 print delete $state{'CA'}, "
"; print scalar %state;

print end_html;

Review 1. Given the following code block, which of the following refers to Maryland? Questions @states=("Maryland", "Michigan", "Oregon");

A. @states[0] B. @states[1] C. $states[0] . $states[1]

2. Given the following code block, you want to add Saturday to your days array. Which is the correct way to append to the array?

@days=("Monday", "Tuesday", "Wednesday", "Thursday", "Friday");

A. $days[4]="Saturday"; B. @days[4]="Saturday"; C. $days[5]="Saturday"; D. @days[5]="Saturday";

3. Given the following code block,

@cities=("Baltimore", "Boston");

which will print the following output?

Welcome to Baltimore!

A. print "Welcome to @cities{1}!"; B. print "Welcome to $cities[1]!"; C. print "Welcome to @cities{0}!"; D. print "Welcome to $cities[0]!";

4. Given the following code block, which displays http://www.cnn.com?

%urls = ( CNN => "http://www.cnn.com", FOX => "http://www.fox.com", HBO => "http://www.hb0.com" );

my ($key); $key = keys %urls;

A. print $urls{CNN}; B. print $urls{0}; C. print $urls(CNN); D. print $urls(0);

5. Given the following code, which of the following will print the words "CGI Town"?

%zipcode = (245, "Perl City", 52136, "CGI Town");

A. print $zipcode{52136}; B. print $zipcode(52136); C. print %zipcode(245); D. print $zipcode{245};

212

6. The output of the following code segment is __.

#!"X:\xampp\perl\bin\perl.exe" my %airport=("TPE","Taipei", "LAX","Los Angeles", "NRT","Narita");

print $airport{"NRT"};

A. "NRT" B. NRT C. "Narita" D. Narita

7. The output of the following code segment is __.

#!"X:\xampp\perl\bin\perl.exe" %zip=("714","Anahiem", "949","Irvine", "818","Torrance"); print $zip{949};

A. 949 B. "949" C. Irvine D. "Irvine"

8. Which can delete the specified key/value pair, and return the deleted value? A. stop() B. exit() C. delete() D. remove()

9. Given the following statements, the output is __.

@cis245 = qw(jack jenny jane joe); $size = @cis245; print $size;

A. $size B. size C. cis245 D. 4

10. The following code segment __.

@cis245 = qw(jack jenny jane joe);

A. creates a new array named cis245. B. $cis245[0] is jack C. is equivalent to @cis245=("jack", "jenny", "jane", "joe"); D. All of the above

213

Lab #7 Perl List, Array, and Hash

Preparation #1: Running the server and create default database 1. Insert the USB flash drive. Record the drive name: ______.

2. Close all the applications that may cause conflicts with XAMPP such as Skype IIS, Wampserver, VMware, etc.

3. Insert the USB that contains XAMPP. Determine the drive name (such as “F:\”).

4. Change to the “X:\xampp\” directory (where X must be the correct drive name) to find the “setup_xampp.bat” and then execute it. You should see:

###################################################################### # ApacheFriends XAMPP setup win32 Version # #------# # Copyright (C) 2002-2011 Apachefriends 1.7.7 # #------# # Authors: Kay Vogelgesang ([email protected]) # # Carsten Wiedmann ([email protected]) # ######################################################################

5. Read the option below the above lines. You should see one of the following:

Sorry, but ... nothing to do! Do you want to refresh the XAMPP installation? Press any key to continue . . . 1) Refresh now! x) Exit

6. If you got the “Sorry, but ...” option, skip to the next step to launch Apache with XAMPP Control Panel; otherwise, press 1 and then [Enter]. If re-configuration succeeds, you should see the following message.

XAMPP is refreshing now... Refreshing all paths in config files...

Configure XAMPP with awk for ‘Windows_NT’ ###### Have fun with ApacheFriends XAMPP! ######

Press any key to continue ...

7. In the “X:\xampp\” directory, click the “xampp-control.exe” file to launch XAMPP control panel.

8. Click the “Start” button next to Apache to start the Apache server.

Learning Activity #1:

214 1. In the “X:\xampp\htdocs\myperl” directory, use Notepad to create a new script file named lab7_1.pl with the following lines. Be sure to replace “X” with the correct drive name.

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

# list

foreach $c (A .. Z) { print lc($c), " "; }

foreach (0..9) { print $_, " "; }

print hr;

# array

@a; # declare $a[0] = "Apple"; # populate $a[1] = 6.1; $a[2] = 'k'; $a[3] = 2;

$size = @a; # get the total number of elements

for ($i = 0; $i < $size; $i++) { print $a[$i], "
"; }

@season = ("Spring", "Summer", "Fall", "Winter");

$size = @season;

$i = 0;

while ($i < $size) { print $season[$i], "
"; $i++; }

@x = (4, 7, 5, 8, 2, 0, 1, 9, 3, 6);

foreach (@x) { print $_, " "; }

print hr; # hash

%area = ("714", "Anahiem", "949", "Irvin", "818", "Torrance");

print $area{"818"}, "
"; print $area{949}, "
";

215 print $area{'714'}, "
";

%state = ("CA", "California", "PA", "Pennsylvania", "WA", "Washington");

print $state{"PA"}, "
"; print $state{"WA"}, "
"; print $state{"CA"}, "
";

%score = ("Beth"=>94, "John"=>95, "Kathy"=>89, "Peter"=>88);

@k = keys %score; $size = @k; # get size of k array

for ($i = 0; $i < $size; $i++) { print $score{$k[$i]}, "
"; }

print end_html;

3. Use Web browser to visit http://localhost/myperl/lab7_1.pl (where “localhost” is your computer), you should see the following window. Notice that you need to use http://localhost:81/myperl/lab7_1.pl if you modified the port number to resolve the port conflicts (as specified in Lab #1). The output looks:

4. Download the “assignment template”, and rename it to lab7.doc if necessary. Capture a screen shot similar to the above figure and paste it to a Word document named lab7.doc (or lab7.docx).

5. Open a Command Prompt, type x: and press [Enter] to change to the correct drive. Replace X with the correct drive name.

C:\Users\user>f:

6. Type cd X:\xampp\htdocs\myperl and press [Enter] to change to the “X:\xampp\htdocs\myperl” directory. Replace X with the correct drive name.

7. Type perl lab7_1.pl and press [Enter] to test the result. The output looks:

Content-Type: text/html; charset=ISO-8859-1

216 Untitled Document a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9


Apple
6.1
k
2
Spring
Summer
Fall
Winter
4 7 5 8 2 0 1 9 3 6
Torrance
Irvin
Anahiem
Pennsylvania
Washington
California
94
89
95
88

Learning Activity #2: 1. In the “X:\xampp\htdocs\myperl” directory, use Notepad to create a new script file named lab7_2.pl with the following lines:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

@arr1=("C#", "Java", "Perl", "PHP", "Python");

$size = @arr1; # get the total number of elements

print "I plan to learn:
", ul;

for ($i=0; $i < $size; $i++) { print li($arr1[$i]); }

print "", p, "I plan to study:
", ul;

@arr2 = qw(CIS MIS IST CET);

foreach $a (@arr2) { print li($a); }

print "", p, "The school teaches:
", ul;

%hash1 = ( "CIS218"=>"C# programming", "CIS223"=>"Java programming", "CIS245"=>"Perl programming", "CIS246"=>"PHP programming", "CIS247"=>"Python programming");

@k = keys(%hash1);

foreach $h (@k) { print li($h, $hash1{$h}); }

print "", p, "Available majors:
", ul;

%hash2 = ( "CIS", "Computer Information Systems", "MIS", "Management Information Systems", "IST", "Information Systems and Technologies",

217 "CET", "Computer Engineering and Technology");

@k = keys(%hash2); @v = values(%hash2);

$size = @k;

for ($i = 0; $i < $size; $i++) { print li, $k[$i], ": ", $v[$i]; }

print end_html;

2. Test the program. A sample output looks:

3. Capture a screen shot similar to the above figure and paste it to a Word document named lab7.doc (or lab7.docx).

Learning Activity #3: A simple search engine 1. In the “X:\xampp\htdocs\myperl” directory, use Notepad to create a new script file named lab7_3.pl with the following lines:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

print "

"; print "Keyword: "; print "

"; print "Enter a paragraph:
"; print "
";

if (param) { print hr;

$keyword = param("keyword");

218 @str = split(/\s/, param("str")); #pass user entry to gw to create an array

$result = undef; # declare an empty variable

$size = @str;

$i=0;

while ($i < $size) { $s = $str[$i];

$s =~ s/[[:punct:]]//g; #remove punctuation if any

if (lc($s) eq lc($keyword)) # convert to lowercase { $result .= "". $str[$i] ."". " "; } else { $result .= $str[$i] . " "; }

$i++; }

print $result; }

print end_html;

2. Test the program. Enter a long paragraph with some repeating words. A sample output looks:

and

3. Capture a screen shot similar to the above figure and paste it to a Word document named lab7.doc (or lab7.docx).

Learning Activity #4: Two-dimensional array 1. In the “X:\xampp\htdocs\myperl” directory, use Notepad to create a new script file named lab7_4.pl with the following lines:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

219 print "

";

@campus1; $campus1[0] = 'Pomona'; $campus1[1] = 'Perl'; $campus1[2] = 'Janet Chen';

@campus2; $campus2[0] = 'Long Beach'; $campus2[1] = 'PHP'; $campus2[2] = 'Lauren Lee';

@campus3; $campus3[0] = 'West Hills'; $campus3[1] = 'Python'; $campus3[2] = 'Helen Huang';

@course; $course[0] = \@campus1; $course[1] = \@campus2; $course[2] = \@campus3;

$size = @course; for ($i = 0; $i<$size; $i++) {

$s = @{$course[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $course[$i][$j] . "
"; }

} print "

";

@city1 = ('Houston', 'Austin', 'Dallas'); @city2 = ('Chicago', 'Peoria', 'Springfield'); @city3 = ('Seattle', 'Tocoma', 'Lakewood');

# array that contains arrays as elements @market = (\@city1, \@city2, \@city3);

$size = @market; for ($i = 0; $i<$size; $i++) {

$s = @{$market[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $market[$i]->[$j] . "
"; }

} print "

";

@brand = (['Car', 'Toyota', 'Nissan', 'Honda'], ['Smart Phone', 'HTC', 'Samsung', 'Motorola', 'Nokia'],

220 ['TV', 'Sony', 'Toshiba']);

$size = @brand;

for ($i = 0; $i<$size; $i++) {

$s = @{$brand[$i]}; # size of child array

for ($j = 0; $j<$s; $j++) { print $brand[$i]->[$j] . "
"; }

}

print "

";

print end_html;

2. Test the program.

3. Capture a screen shot similar to the above figure and paste it to a Word document named lab7.doc (or lab7.docx).

Learning Activity #5: Three-dimensional array 1. In the “X:\xampp\htdocs\myperl” directory, use Notepad to create a new script file named lab7_5.pl with the following lines:

#!"X:\xampp\perl\bin\perl.exe" use CGI qw(:standard);

print header, start_html;

# 3rd layer @cis245 = ("CIS245", "Perl Programming", "3"); @cis246 = ("CIS246", "PHP Programming", "3"); @cis247 = ("CIS247", "Python Programming", "3");

@tcm102 = ("TCM102", "Intro to Linux", "3"); @tcm103 = ("TCM103", "Linux Administration", "3"); @tcm104 = ("TCM104", "Linux Scripting", "3");

# 2nd layer @cis = (\@cis245, \@cis246, \@cis247); @tcm = (\@tcm102, \@tcm103, \@tcm104);

221 # 1st layer - parent @course = (\@cis, \@tcm); print "

";

$size = @course; for (my $i=0; $i < $size; $i++) {

$s1 = @{$course[$i]};

for (my $j=0; $j < $s1; $j++) {

$s2 = @{$course[$i]->[$j]};

for (my $k=0; $k < $s2; $k++) { print $course[$i]->[$j]->[$k], " "; } print "\n
"; } } print "

";

@food = ( [ ["apple", "orange", "banana"] ], [ ["brocolli", "spinach", "cabbage", "carrot", "onion"] ], [ ["shrimp", "crab"] ] );

$size = @food; for (my $i=0; $i < $size; $i++) {

$s1 = @{$food[$i]};

for (my $j=0; $j < $s1; $j++) {

$s2 = @{$food[$i]->[$j]};

for (my $k=0; $k < $s2; $k++) { print $food[$i]->[$j]->[$k], " "; } print "\n
"; } } print "

";

@cars = ( [

222 ["Toyota", "Japan"], ["Nissan", "Japan"], ], [ ["BMW", "Germany"], ["Audi", "Germany"], ] );

print $cars[0]->[0]->[0], "\n
"; print $cars[0]->[0]->[1], "\n
"; print $cars[0]->[1]->[0], "\n
"; print $cars[0]->[1]->[1], "\n
";

print $cars[1]->[0]->[0], "\n
"; print $cars[1]->[0]->[1], "\n
"; print $cars[1]->[1]->[0], "\n
"; print $cars[1]->[1]->[1], "\n
";

print "

";

print end_html;

2. Test the program. A sample output looks:

3. Capture a screen shot similar to the above figure and paste it to a Word document named lab7.doc (or lab7.docx).

Submittal 1. Complete all the 5 learning activities in this lab. 2. Create a .zip file named lab7.zip containing ONLY the following script files.  lab7_1.pl  lab7_2.pl  lab7_3.pl  lab7_4.pl  lab7_5.pl  lab7.doc (or lab7.docx) [You may be given zero point if this Word document is missing]

3. Upload the zipped file to Question 11 of Assignment 7 as the response.

Programming Exercise #07 1. Use Notepad to create a new file named “ex07.pl” with the following lines in it (be sure to replace YourFullNameHere with the correct one):

223 #!"X:\xampp\perl\bin\perl.exe" ## File name: ex07.pl ## Student: YourFullNameHere

2. Next to the above two lines, write Perl code that will create one array named "regions" with 5 elements "northwest", "southwest", "northeast", "southeast", and "mountains". Then, use a "for" loop to display each of the elements in the form of "regions[i] is xxxxx", as shown in the following figure.

3. Download the “programming exercise template”, and rename it to ex07.doc. Capture a screen shot similar to the above figure and paste it to a Word document named ex07.doc (or .docx). 4. Create a .zip file named ex07.zip with the following two files. Upload the .zip file for grading.  ex07.pl  ex07.doc (or .docx) [You may be given zero point if this Word document is missing]

Grading Criteria 1. Your code must meet the above requirements to earn credits. No partial credit is given. 2. You code must fully comply with the requirement to earn full credits. No partial credit is given.

224