#################### # Problem 1 ########## $foo = "Toast is yummy."; # Use the quick and dirty approach by globally replacing all characters with # the upper-case equivalent. $foo =~ tr/[a-z]/[A-Z]/g; # Alternatively, we can use the built-in perl case-conversion function to # accomplish the same thing. $foo = uc ($foo); # Using tr/// is quick, dirty, and illegible, but gets the job done. Using # uc keeps the program clean, and leaves us free to deal with the logic rather # than the implementation. #################### # Problem 2 ########## # Open the file. We could check to make sure the file exists and write a # warning if it doesn't, but this is just sample code. open (INFILE, ") { # Separate the line into columns by tab character @cols = split (/\t/, $line); # Swap columns 2 and 3 $tmp = $cols[2]; $cols[2] = $cols[1]; $cols[1] = $tmp; # I've designed this to be record independent. This program will work for # any number of columns as long as there is a single tab between each column foreach $column (@cols) { if ($column eq $cols[0]) { # If this is the first column, print out the column print "$column"; } else { # Otherwise we print a tab followed by the column print "\t$column"; } } } # We play nice and close the file close (INFILE); #################### # Problem 3 ########## # Having done a fair amount of work for Problem 2, we now generalize it to # handle different columns based on the input. # sample function call &swap_columns (1, 2); # subroutine definition sub swap_columns { my ($col1, $col2) = @_; # Now, since I'm guessing that the function &swap_columns (1, 2) is supposed # to swap the first and second columns, and since perl arrays begin with 0, # we adjust $col1 and $col2 down so that the operation occurs as desired. $col1--; $col2--; # Open the file. We could check to make sure the file exists and write a # warning if it doesn't, but this is just sample code. open (INFILE, ") { # Separate the line into columns by tab character @cols = split (/\t/, $line); # Swap columns $col1 and $col2 $tmp = $cols[$col2]; $cols[$col2] = $cols[$col1]; $cols[$col1] = $tmp; # I've designed this to be record independent. This program will work for # any number of columns as long as there is a single tab between each column foreach $column (@cols) { if ($column eq $cols[0]) { # If this is the first column, print out the column print "$column"; } else { # Otherwise we print a tab followed by the column print "\t$column"; } } } # We play nice and close the file close (INFILE); } #################### # Problem 4 ########## # We simplify the original code in two ways. First, we reduce the ugly for() # loop with a foreach() loop (which handles indexing and so on for us). Next, # we reduce the printf() call to print() which lets us format everything in a # single string. @words = ("good", "bad", "ugly", "nice"); foreach $word (@words) { print "I have been very $word\n"; } #################### # Problem 5 ########## # First, we parameterize this so that we can select any value we please $desired_key = "bar"; $desired_doc = 3; # Next, we build the hash %words = ( "foo" => ["foodoc1", "foodoc2", "foodoc3"], "bar" => ["bardoc1", "bardoc2", "bardoc3"], "baz" => ["bazdoc1", "bazdoc2", "bazdoc3"], "qux" => ["quxdoc1", "quxdoc2", "quxdoc3"] ); # This part is a little messy. We find the array referenced by $desired_key in # %words. Next, we reference it as an array @{} and give it the subscript of # $desired_doc - 1 (because arrays start at 0). We assign everything to $res # and print out the result. $res = @{$words{$desired_key}}[$desired_doc - 1]; print "\n$res\n"; #################### # Problem 6 ########## # We limit the allowable filenames severely, but the general idea here is to prevent # the script from being taken in by quote, asterisk, or other special characters. $string = "d24-3_a+3.txt"; # The nasty regex below matches as described in the usage text printed if we have # an illegal filename if ((! $string =~ /^[\w\d-_+.]{1,120}$/) || ($string eq ".") || ($string eq "..")) { print "\n The filename $string contains illegal characters. Filenames may only contain words, digits, and the following characters: -, _, +, and ., must be a minimum of 1 and a maximum of 120 characters, and may not be . or .. :)\n"; } else { # otherwise, everything is fine print "\nThe filename $string is OK\n"; } #################### # Problem 7 ########## # This is a beauty :) # The first thing the program does is strip the carriage-return from the input # so all the program is working with is a numeric value (assuming a numeric is # entered). The program begins a for() loop. # This for() loop is the heart of the code. For all values except 0, it # reports the one value. For 0 it reports sequentially the values 1-12. For # the singular values, the assignment portion of the loop notes that $m != 0 # so returns $m to $i. Since this means $i <= $m, it prints once and exits. # For $m == 0, the assignment portion of the loop simultaneously assigns $m = 12 # and returs the result of comparing the value assigned (12) to 12. Since this # is true, it returns 1, which is assigned to $i. But it also assigned 12 to # $m, so we now have an index of 1 and a final value of 12. The loop cycles # from 1 to 12, printing out reports as it goes.