Perl hashes, compound data structures, formatting output, and special variables

Preview:

Citation preview

Perl

hashes, compound data structures, formatting output, and special variables

Hashes

• Like arrays, except the indices are strings• Called associative arrays in perl• declaring a hashmy %hash• Like arrays, use the $ when accessing a

slice of the hash• example: $hash{"Jim"} = 1;• Strings as keys. Perl allows you leave off

the quotes, so long as they are no special characters and/or whitespace—print $hash{jim}; #legal—print $hash{jim ward}# not legal

– print $hash{"jim ward"}# must use quotes (either kind)

Hashing (2)

• initializing an hash—A couple of ways to do it—%stuff = ( "Jim" => "faculty",

"Allyson" => "faculty","Fred" => "student");

—%stuff = ("Jim", "faculty", "Allyson", "faculty", "Fred", "student");

print "$stuff{"Allyson"}; # prints faculty

• Hashes of hashes (like 2D arrays)$2hash{"Jim"}{"Ward"} = "faculty";

Keys to the hash

• Getting the keys (indices) to the hash—use the command: keys—keys return a list

@arr = keys %hash;

• To print the values in the hashforeach $key (keys %hash) { print "$key $hash{$key} \n";}

keys to the hash (2)

• for 2D hashes, it more complex. —Need to use indirection.

foreach $key1 (keys %hash) { #first level keysforeach $key2 (keys %{ $hash{$key1} }) {

#note the indirection for the 2nd level keys

print "$hash{$key1}{$key2} \n"; }}

keys to the hash (3)

• For very large hashes it may be quicker to get the key and value at the same time

• each returns the key and the value in a hash

while ( ($key, $value) = each %stuff)print "$key $value \n";

}output:Jim facultyAllyson facultyFred student

exists and hashes

• like array, you can check to see if there is a value for a given key—you don't need to check exists when using keys

operator, since it only returns keys with valuesif (exists $stuff{"Barney"} ) {

statements;}

• deleting key from a hash$stuff{"Jim"} = ""; #sets the value to ""

—exists will return true for this key, there is a value

delete $stuff{"Jim"}; #removes it from the hash—exists will return false for this key.

exists and hashes (2)

• Clearing the entire hash%stuff = (); #efficient and quick• ORundef %stuff

delete $hash{keys %hash}; —slow but gets the job done.

Hashes and arrays together

• You can have hashed arrays and arrays of hashes

• $hash{key}[index] = valueYou data might look something like thisflintstones: fred barney wilma dinojetstons: george jane elroysimpsons: homer marge bart lisa• the key is the last name, the array is all

the first names.

Hashes and arrays together (2)

• another example—student name as the key—grades on there assignments as the array.—their e-mail address as the item in the array.

$grade{"Jim"} = [ 12,30,12,'seker@uwyo.edu'];

– NOTE: the @ means an array, use ' or backslash it.

print $grade{"Jim"}[$#{ $grade{"Jim"}}]; —output: seker@uwyo.edu

• To access index 1 of all the hash, use keysforeach $key (keys %grade) {

print "$grade{$key}[1] \n";}

Hashes and arrays together (3)

• arrays of hashes—not very common

• $arr[index]{key}• initializing

@arr = ( { husband => "barney", wife =>"betty"} { husband => "george", wife

=>"jane"} );

—print $arr[1]{wife}; output: jane

• You can create very complex structures such a hash of an array of a hash—$hash{key1}[index]{key2};

• Depends on your needs.

Formatting output

• Allow you generate reports and varying other things—keywords are borrowed from FORTRAN—and more legible then PRINT USING in BASIC—has three types of lines

– comment line– "picture" line, giving the format– argument line, supplying values to the previous

picture line

format NAME = formating.

Formatting output (2)

• Designed to work with files, so the format name and filehandle should be the same name—Can be used with STDOUT as well.

• To create a header, use NAME_TOP—_TOP must be capped otherwise perl won't use

it as a header, by default.

• To trigger a format, use the write command—write FILEHANDLE;

—write ; #for standard out

example formatformat EX1_TOP =Name Username Phone-----------------------------------------------------------.format EX1 = #comment I need three value fields@<<<<<<<<<<< @<<<<<< @<<<<<<<<#use these variables when write is called.$name, $userame, $phone.

open EX1, ">example.txt";$name = "jim"; $username = "seker"; $phone = "766-6031"write EX1;close EX1;

example format (2)

• To write to STDOUT$ofh = select(STDOUT);$^ = "EX1_TOP";$~ = "EX1";select($ofh);

#assuming code from previous slidewrite; #prints out line of formatted output

Format Characters

• < left justification• > right justification• | center• @ normal value file

—Note, if you value is too big for the field it will truncated.

• # (after @) numeric field—. can be used to anchor the decimal point

Another Format example

• format EX2 = @>>>>>>>> @###.## @<<<<<<<<#right justified number left justified$name, $num, $acc_name.• if the integer part of a number is to big,

then it will printed, using the space from the right side of the decimal point (and even the decimal point), before truncating the number.—so 123456.123 would print as 123456—1234567 as 123456

printf statement

• less efficient than a print statement—In other words don't use it when a print will do

• printf FILEHANDE FORMAT, LIST—format statement, similar to c/c++—%% a percent sign—%c a character—%s a string—%d, %u a signed integer, a unsigned integer—%o, %x a unsigned octal, unsigned hex—%e floating point in scientific notation—%f floating point in fixed decimal notation—%b unsigned integer, in binary—%n special, stores the # of characters output so far

intothe next variable in the argument list

printf statement

• Flags in the format, between % and conversion character—spaceprefix positive number with a space—+ prefix positive number with a plus sign—- left-justify with the field—0 uses zeros, not spaces to right-

justify—# prefix nonzero octal with "0"

prefix nonzero hex with "0x"—number minimum field width—.number precision, number of digits after .

– Note: Num1.Num2, then num1 should include space for the period and num2

—l interpret integer as a C type long—h interpret integer as C type short

printf examples

• printf "hi %s ", $str; #$str = "Jim"—output: "hi Jim"

• printf "The answer is %6.2f",$val—output: the answer is 123.12

• printf "The answer is %+6.2f",$val—output: the answer is +123.12

• printf "The answer is %09.2f",$val—output: the answer is 000123.12

sprintf statement (formating strings)

• same as the printf, except it returns a string

• string = sprintf FORMAT, LIST

• $str = sprintf "The answer is %09.2f",$val—$str = "the answer is 000123.12"

• $v1 = 213; $v2 = 12;• $str = sprintf "%03d%03d",$v1, $v2;

—$str = "213012"—Since, strings can be converted to numbers

easily, also have the number 213,012

Exercise 6

• Read a File/STDIN where the line has comma delimited. The first field is a name, then followed by 4 numbers.

• Output:—header: Name Grade1 Grade2 Grade3 Grade 4—Use formatted output print the name and

grades in columns.

• Input: (example)Jim Ward, 20, 19, 8, 12Fred Jones, 13, 2, 14, 20Jane Doe, 20, 12, 20, 20

Special variables in Perl

• There are any number of special variables in perl.—You seen a couple that just deal with

formatted output and error messages from open commands

—Typically they use only special characters in their names or are the same name as c/c++ special variables and all capped.

—We only going to cover a some of the more common ones and some more when we cover regular expressions.

Special variables in Perl

• command line arguments—There are placed into an array @ARGV—$ARGV[0] is the first parameter—$ARGV[1] is the second parameter—etc…—$0 is the program name

• Optional variables?! —What perl calls anonymous variables

– They make the code less readable, but are used pretty commonly.

– Since perl allows for much a statements to be optional include some variables, it has anonymous variables to replace them.

—The anonymous scalar variable is $_—The anonymous array variable is @_

– accessed as $_[index]

—The anonymous hash variable is %_

Arguments Example

• range.pl#!/usr/bin/perl

foreach ($ARGV[0] .. $ARGV[1]) { print "$_\n";}

• Another script that calls it.open FP, "range.pl 1 5|";while ($line = <FP>) { # OR while(<FP>)

print $line; # print $_;}close FP;• Output from second script12345

$_ and @_

• $_ exampleforeach (@arr) { print $_; #$_ contains each element.}• @_split ':',$x;print "$_[0] … \n"; #@_ holds the list of values• @_ and $_ togethersplit ':';

—@_ holds split values, $_ used as the string to split.

—Actually split can be called by without arguments, by default, splits on a space.

Input and $_

• The common practices is to use the $_ for input

<STDIN>; #legal statement, $_ holds the value

• The variable can be skipped and $_ gets the input.

while( chomp(<FP>) ) { #remove EOL as well.

print $_;}

• $_ and @_ lead to unreadable code—It makes some quick and dirty code.—Sometimes difficult to update later as well.

• We'll see more of $_ (and associated variables) when we get to regular expressions (string manipulation).

environment variables

• %ENV—$ENV{PATH} = "/bin:/usr/bin";

• Changing them changes how perl interacts with the O/S.

• To see all of themforeach $key (keys %ENV) {

print "$key = %ENV{$key} \n";}

UID, GID and PID variables

• $< real UID• $> effective UID• $( real GID

—in windows: space separated list of groups

• $) effective GID—in windows: space separated list of groups

• $$ process number PID—while you can change this variable it has no

effective.

variables that effect input and output

• input separator• $/ default end of line marker• exampleundef $/;$_ = <FILEHANDLE>;

—$_ contains the whole (or rest of the) file;

• safer version{

local $/;$_ = <FILEHANDLE>;

}

variables that effect input and output (2)

• be careful changing $/—$/ = ' '; # while treat consecutive blank lines

as if they didn't exist;

• $\ output separator—$\ default is nothing—$\ = "\n";—now perl will print an newline after each print.

• $, output field separator printed between elements in a list—default empty (print @arr produces element

with all together—$, = ' '; print @arr; #output each element

with a space between them.

variables that effect input and output (3)

• $" output field separator for interpolated lists into strings—default ' ';—$" = "\n";

– Now each element is printed with a newline between them.

• Example:print (1,2,3); #prints "123"$, = '*';$\ = "\n";print (1,2,3); #prints "1*2*3\n"

some other special variables

• $! —last error message (not cleared on successful

operations)

• $^T—time the script started (in integer, see time

function)

• %INC—a hash containing entries for the filename perl

has loaded via do FILE, require, and use

• @INC—a list of directories where PERL modules may

be found.

map operator

• (LIST) = map BLOCK/expr @arr;• Takes an array, putting 1 slice at a time

into $_, then runs the BLOCK for that element. returns a list (flattings 2D arrays into 1D arrays) comprising the results.

• @result = map { split ' ' } @lines;

• @num = (1..10);• @squares = map {$_**2} @num;

• @new = map chomp, @old;

map operator (2)

@ans = map {if ($_ < -5) {

0;} elsif ($_ == 32) { (3,2);} else {

$_; }

} @nums;

map operator (3)

• map function can written as a foreach loop• Using the previous example:foreach $val (@num) {

if ($val < -5) { push @ans, 0;} elsif ($value == 32) {

push @ans, (3,2);} else {

push @ans, $val;}

QA&

Recommended