390 likes | 570 Views
hashes, compound data structures, formatting output, and special variables. Perl. Hashes. Like arrays, except the indices are strings Called associative arrays in perl declaring a hash my %hash Like arrays, use the $ when accessing a slice of the hash example: $hash{"Jim"} = 1;
E N D
hashes, compound data structures, formatting output, and special variables Perl
Hashes Like arrays, except the indices are strings Called associative arrays in perl declaring a hash my %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 hash foreach $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 keys foreach $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 faculty Allyson faculty Fred 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 values if (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 OR undef %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] = value You data might look something like this flintstones: fred barney wilma dino jetstons: george jane elroy simpsons: 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 keys foreach $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 format format 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 slide write; #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 into the next variable in the argument list
printf statement Flags in the format, between % and conversion character space prefix 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 (formatting 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, 12 Fred Jones, 13, 2, 14, 20 Jane 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 script 1 2 3 4 5
$_ and @_ $_ example foreach (@arr) { print $_; #$_ contains each element. } @_ split ':',$x; print "$_[0] … \n"; #@_ holds the list of values @_ and $_ together split ':'; @_ 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 them foreach $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 example undef $/; $_ = <FILEHANDLE>; $_ contains the whole (or rest of the) file; safer version { local $/; $_ = <FILEHANDLE>; }
variables that effect input and output (2) be careful changing $/ $/ = ' '; # will 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; Note Expr may also be a Regex Takes an array, putting 1 slice at a time into $_, then runs the BLOCK for that element. returns a list (flatting 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; Better version with Trinary operator @ans = map { ($_ < -5) ? 0: ($_ == 32) ? (3,2): $_ } @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; }
Grep Similar in nature to map @arr = grep Block OR expr, LIST Again expr can be regex. Example: @new = grep ($_<1 || $>31, @numbers);
Q A &