320 likes | 475 Views
Perl: arrays. #!/usr/bin/perl -w # bind3.pl # # Here's an example that takes a unix path ($file) # and copies it to anothe variable ($filename) # Then, we search for one or more of any character {.+} # followed by a "/" character -- but we have to use the
E N D
#!/usr/bin/perl -w # bind3.pl # # Here's an example that takes a unix path ($file) # and copies it to anothe variable ($filename) # Then, we search for one or more of any character {.+} # followed by a "/" character -- but we have to use the # escape metacharacter "\" so that we don't end the match {\/}. # Finally, we are looking for one or more non-white spaces {(\S+) # at the end -- to pull off the the last file name "FOUND" # # # $path = "/home/tabraun/test/bob/FOUND"; $filename = $path; $filename =~ s/.+\/(\S+)/$1/; print "$filename\n";
#!/usr/bin/perl # randomSeq.pl # # Don't get too uptight over this line -- it is just setting # a "seed" for the rand() fuction with a value that approximates # a random number. If you must know, it takes a prccess ID ($$), # shifts its bit left 15 times, then add the process ID to the shifted # value, then does an bit-wise XOR (^) with the current time(). # print "Enter length of sequence to generate:"; $length = <STDIN>; srand(time() ^ ($$ + ($$ << 15)) ); while($length) { # stay in loop until have generated enough sequence $rand = int rand(4); # Interger number between (0-3) inclusive $rand =~ tr/0123/ACTG/; $length = $length-1; #decrease loop counter $seq = $seq . $rand; #keep the nucleotide I just created } # Since I am out of the loop, I must be done print "$seq\n";
Run Example • Show process ID
Lists and Arrays • list – ordered collection of scalars • array – a perl variable that contains a list • each element of an array is a separate scalar variable • values are ordered, from the first to the last • elements are indexed by small integers, starting at 0 "left-most" 0 1 2 3 4 5 35 12.4 "hello, world" indices 1.72e30 "bye\n" 69 "right-most"
Accessing Elements of an Array • $fred[0] = "yabba"; • $fred[1] = "dabba"; • $fred[2] = "doo"; • $fred[3] = 4; • $fred[3]++; • $fred[1] =~ s/b/B/g; • $fred = 32; #completely different scalar
Creating Elements • if you store into an array element that is beyond the end of the array, the array is automatically extended as needed (no limit as long as there is memory available) • intervening elements will be undef • $rocks[0] = 'bedrock'; • $rocks[1] = 'slate'; • $rocks[99] = 'chasm'; # 3 defined elements, 97 undef .
List Literals • shorthand for creating arrays (1,2,3) #list of 3 values, 1, 2, 3 (1, 2, 3,) # same thing, last comma ignored ("fred",4.5) # 2 values () # empty list (1..100) # list of integers, 1 thru 100 # aka "range operator" (1..5) #1, 2, 3, 4, 5 (5..1) # empty, only counts up (0, 2..6, 10) #(0, 2, 3, 4, 5, 6, 10) ($a..$b) # depends on $a and $b
Another List Shortcut qw -- stands for "quoted words" ("fred", "barney", "betty", "wilma", "dino") same as qw/ fred barney betty wilma dino / #same as above with less typing
List Assignment • list values may be assigned to variables ($fred, $barney, $dino) = ("finstone", "rubble", undef); • can use to swap ($fred, $barney) = ($barney, $fred); Note – you cannot do this in most other languages (C, Java, etc) • Extra right side values are ignored • Extra left side variables will be undef ($fred, $barney) = qw/ flintstone rubble slate /; # slate ignored ($wilma, $dino) = qw/flintstone/; #dino gets undef
List Assignment • can build array ($r[0], $r[1], $r[2]) = qw/ slate granite chalk/; • one final array shortcut -- @ @rocks = qw/ bedrock slate lava/; $rocks[2] =~ s/s/S/; @empty_array = (); @list = (1..10); # 10 elements of 1-10 @stuff = (@list, @rocks); #13 elements $dino = "dog"; @quarry = (@rocs, "diamond", @list, $dino); • Array names are replaced by the elements in its list
Copying an Array is Easy @copy = @quarry; # all elements are copied for($I=0;$I<$num;$I++) { $copy[$I] = $quarry[$I]; }
Array Manipulations • could add to arrays by storing them into elements with new, larger indices • however, this defeats the strengths of perl, and will actually result in slower code • extensive use of indices slows down perl
Array as a Stack • elements are added/removed from the "right" side of the list (portion with highest indices) • Syntax push ARRAY, LIST - returns new number of elements in array pop ARRAY - returns “right” most element of array/list @array = (5..9); # array has 5,6,7,8,9 $fred = pop(@array); # fred = 9, array = 5,6,7,8 $barney = pop @array; #barney = 8, array = 5,6,7 pop @array; # 7 is discarded, array = 5, 6
push (@array, 0); • push @array, 8; • @list = (5, 6, 7); • push (@array, @list);
An Array as a Queue • Elements are added/removed from the left (or portion with lowest indices) shift ARRAY - returns ‘left’ most element unshift ARRAY, list - returns new number of elements in array @array = qw/ dino fred barn /; $a = shift(@array); # @array = fred, barn $b = shift @array; # @array = barn shift @array; # @array is empty $c = shift @array; # @array still empty, $c = undef unshift(@array,5); #@array now has 5 @list = (1..4); unshift(@array,@list); # @array = 1,2,3,4,5
Mix and Match @array = (9..13); push(@array, 14); unshift(@array,8); $fourteen = pop(@array); $nine = shift @array; print "$array[2]";
Interpolating into Arrays Like scalars, array values my be interpolated into double-quoted strings @rocks = qw/ stone gravel rubble /; print "boulder @rocks marble\n"; #inserts spaces between elements of array print "$rocks[1]\n"; # gravel
Foreach loop revisited foreach SCALAR (ARRAY) { } -- steps through each item of an array executing one iteration each time thru the loop @rocks = qw /bedrock pebbles stone/; foreach $rock (@rocks) { print "One rock is $rock\n"; }
Control Loop Variable A change to the control loop variable actually changes the elements of the array. $rock = "Haggar"; #rock is stored and saved by perl @rocks = qw/ slate stone marble /; foreach $rock (@rocks) { $rock =~ s/(.*)/\U$1/; } print "@rocks\n"; # SLATE STONE MARBLE print "$rock\n"; #Haggar restored ???
Other Array Operators reverse ARRAY -- takes an array of items and reverses the order @fred = 5..10; @derf = reverse (@fred); 10 9 8 7 6 5 @fred = reverse @fred; #fred is now reversed too reverse SCALAR -- in a scalar context, such as the string ATGCC, reverse will reverse the order of the string -- CCGTA
Other Array Operators sort ARRAY -- takes a list of values and sorts them in character order (lexigraphically) @rocks = qw/ slate stone marble /; @nums = (97, 98, 99 100, 101); @sorted = sort (@rocks); #marble slate stone @nums = sorted (@nums); #100 101 97 98 99
Array-like Operator glob EXPR -- In list context, returns a (possibly empty) list of filename expansions on the value of EXPR such as the standard Unix shell /bin/csh would do Ex) @files = glob '*';
Examples • Multiple syntax for arrays
Other topics • sort • reverse • glob • split • system and ` ` • array growth/memory allocation • pop, push, shift, unshift • slice • building 2-d arrays • arrays of hashes and hashes of arrays • Other • @ARGV (modules, and module for long) • file tests • files and directories • cgi-bin • advanced sorting • strings
Side Note More on arrays in later lecture, however, question of arrays of arrays:
#!/usr/bin/perl @first = (1,2,3,4,5); @second = (10,20,30,40,50); @third = (100,200,300,400,500); # \@ is a "reference" @numbers = (\@first,\@second,\@third); foreach $i (@numbers) # i becomes a reference to an array { foreach $j (@$i) # @$ dereferences i (an reference to an aray) { # so j is an elemetn of an array print "$j is value in arrayArray\n"; } } print "\n"; #### I much prefer this notation print "$numbers[2][3]\n"; print "\n"; # and finally for ($i = 0; $i < @numbers; $i++) { $aref = $numbers[$i]; #so bizzare, my editor for ($j = 0; $j <= $#{$aref}; $j++) { #thinks this is comment print "$numbers[$i][$j]\n" # $#ARRAY returns index of last element } }
./arrayArray.pl 1 is value in arrayArray 2 is value in arrayArray 3 is value in arrayArray 4 is value in arrayArray 5 is value in arrayArray 10 is value in arrayArray 20 is value in arrayArray 30 is value in arrayArray 40 is value in arrayArray 50 is value in arrayArray 100 is value in arrayArray 200 is value in arrayArray 300 is value in arrayArray 400 is value in arrayArray 500 is value in arrayArray 400 1 2 3 4 5 10 20 30 40 50 100 200 300 400 500
Example Negative numbers: in the sample source code I provided, I use the following REGEXP ^\d+$ to verify that a "number" was entered. Note that this will not match a negative number (as in the example I ran during class) because it does not include a "-" Note, you should only set the seed ONCE – doing so more often would actually decrease the approximation of a random number srand (time() ^ ($$ + ($$ << 15)) ); Examples What is "random" – how would you verify that your output is random? You would expect each letter to occur about 25% of the time. ./randSeq.pl > look cat look | grep A | wc OR count the letters as you generate them and print