Archive for the Perl Category

Atoms in Regular Expressions

Posted in Perl with tags , , on December 14, 2008 by vinaychilakamarri

I read about something interesting today. There is a term called ‘Atom’  when you are dealing with regular expressions. Knowing the importance of  how you formulate a regular expression becomes important because some
expressions might turn out as something you usually don’t anticipate. Talking about quantifiers in the context of  atoms, the importance of atoms becomes more vivid when you consider this example: ha{6}, (ha){6}. Although
they seem to be very similar, the additional parentheses treat ‘ha’ as a single atom and match only those words whose pattern contains ‘ha’ for 6 consecutive times. The former expression tries to match only those patterns in which ‘h’ is followed by 6 a’s. Let’s say I wanted to match a word that starts with ‘pre’ and ends with ‘tion’

These are some of the possibilities that I should be expecting:
premonition
predilection
prediction
etc.

So, a possible expression can be:

^(pre)+([a-z]*|[A-Z]*|\\s)*(ion)+\$

Any word that beings with the atom “pre”, in which the atom “pre” Must occur at least one time and can occur more than one time after the beginning, and there can be 0 or many characters in the middle, starting from a-z OR A-Z OR space characters with a quantifier *, which indicates that the characters can occur 0 or more times, with an external quantifier that ensures that the letter case is ignored during the match, and it only matches the patterns that end with the atom, “ion”, which is specified by the concluding $

Example 2:

^?[0-9]+(ord)+\$?

Says that the atom ‘ord’ has to be preceded at least once by a number. The + quantifier after [0-9] signifies that the numbers can be repeated any number of times. Also the ^? signifies that the numbers need not start from the beginning of the pattern in question. Also what the “\$?” means is that the pattern need not essentially end with the atom “ord”

Advertisements

Subtle things in perl part 2: The difference between ‘or’ and ||

Posted in Perl on July 27, 2008 by vinaychilakamarri

In perl, both ‘or’ and || mean the same thing. But they act in different ways when used in certain circumstances. For example, lets say we are trying to open a file for read and write operations. It’s always a good idea to handle the IO errors and we do this in the following way:

………………..
$file = shift;
open FILE, $file or die “Couldn’t open the file $file”; #note this
…………………

The second step can also be written in this way:
open FILE, $file || die “Couldn’t open the file $file”; #note this

But when the execution of this program happens, you will never see the message in ‘die’, if you use a || instead of ‘or’. Reason for this is that the || operator has a precedence level higher than that of ‘or’ and since
the ‘open FILE, $file’ returns a value after an attempt to execute, the || is always true and die is never reached
.

The actual reason as Martin, one of the commentators  puts it,

The actual reason is that the operator precedence for the double pipe is higher than the comma, so perl is resolving the double pipe first, which chooses the first true result of its two parameters, in this case $file and the die statement. As long as $file is a nonempty string it counts as true and always gets returned by the double pipe.

So it is always advisable to use ‘or’ instead of ||. If you want to use ‘||’, you can do it by using the
pen file with parathesis which ensures the precedence of the operators.

open (FILE, $file) || die “Couldn’t open the file $file”;

Playing with shift , @_ , $_

Posted in Perl on July 22, 2008 by vinaychilakamarri

The ‘Shift’ function pops the first element of an array and returns the popped item to the left side variable. There is a way to write cryptic code with “shift”, to impress your family (yep.. only family, sorry). Perl has some internal default variables that get initialized when in some sub routine. Lets say you’re passing an array of elements to some sub routine. You don’t need an explicit variable like in some languages to store that passed variable. You can directly use the implicit variables for getting the passed parameters. Let’s write a subroutine using some implicit variables and “shift”:

sub printFileContent {

foreach(@_){

printInsideThings ($_);
}
}

sub printInsideThings {
open FILE,$_;
while($line = <FILE>){
print $line;
}
}

printFileContent (“C:\\Data\\virtual-hosting-howto.html”,”C:\\Data\\virtual-boasting-howto.html”);

As I pass a list of files, the ‘@_’ of my first sub is already initialized with the list of strings that I passed.
So I used ‘foreach’ and passed the “$_” to another subroutine. The ‘$_’ will be initialized to the list item for
each iteration over the list. The other sub takes the string, and using a ‘$_’, which is initialized with the passed value by default, it opens the file and initializes a global variable ‘FILE’ and prints the content line by line in the while loop. The ‘< >’ opens the file and reads it line by line for you (uber cool tool eh?). Other ways we can do the later subroutine:

sub printInsideThings {
open FILE,shift;
while(<FILE>){
print ;
}
}

Look at the while loop there. Perl uses the ‘$_’ so implicitly that you don’t even have to specify it. That loop initializes the ‘$_’ for every iteration and assigns it the line it reads from the file. The “print;” is equivalent to “print $_;” Again, the ‘shift’ in that file opener takes out the first of the ‘@_’ and passes it for parsing stuff

This one prints the contents of a single file that is passed:

sub openFu{
open FILE, shift;
while(<FILE>){
print;
}
}

openFu “c:\\data\\virtual-hosting-howto.html”;

Subtle things in perl

Posted in Perl on July 13, 2008 by vinaychilakamarri

There are some untold things in Perl, that really caught my attention. Firstly, we can assign an array to a scalar variable. Doing so will initialize that scalar to the size of that array. There is also an explicit function for this. Here is what I am talking about:

@arr = qw(i can be a bad guy);

$var = @arr;

print “$var”;

This will print 6. In the same way we can also use an inbuilt function for this. The function is called ‘scalar’

$var = scalar(@arr); assigns the size of the array. In the same way we can also initialize a variable to a list. But the variable will get initialized to the last variable of that list. For example:

$var = (1,2,3,4); will initialize $var to 4.

Pyramid in perl

Posted in Perl on July 6, 2008 by vinaychilakamarri

Lets say you want to print something like this:
                          A
                         ABA
                        ABCBA
                       ABCDCBA
                      ABCDEDCBA
                     ABCDEFEDCBA
                   ABCDEFGFEDCBA
                  ABCDEFGHGFEDCBA
                 ABCDEFGHIHGFEDCBA
                ABCDEFGHIJIHGFEDCBA
               ABCDEFGHIJKJIHGFEDCBA
              ABCDEFGHIJKLKJIHGFEDCBA
             ABCDEFGHIJKLMLKJIHGFEDCBA
            ABCDEFGHIJKLMNMLKJIHGFEDCBA
           ABCDEFGHIJKLMNONMLKJIHGFEDCBA
         ABCDEFGHIJKLMNOPONMLKJIHGFEDCBA
        ABCDEFGHIJKLMNOPQPONMLKJIHGFEDCBA
       ABCDEFGHIJKLMNOPQRQPONMLKJIHGFEDCBA
      ABCDEFGHIJKLMNOPQRSRQPONMLKJIHGFEDCBA
     ABCDEFGHIJKLMNOPQRSTSRQPONMLKJIHGFEDCBA
    ABCDEFGHIJKLMNOPQRSTUTSRQPONMLKJIHGFEDCBA
   ABCDEFGHIJKLMNOPQRSTUVUTSRQPONMLKJIHGFEDCBA

Here is the code I wrote:

# !/usr/bin/perl
@array = (‘A’ .. ‘Z’);
$in = <>;
chomp($in);
if($in < 0)
{
print “Can’t proceed”;
}
else{
for($i = 0 ; $i < $in ; $i++)
{
@tmp = (”);
for($k = scalar(@array); $k > $i; $k–)
{
print ” “;
}
for($j = 0 ; $j < $i; $j++)
{
push(@tmp,@array[$j]);
print “@array[$j]”;
}
pop(@tmp);
@revtmp = reverse(@tmp);
foreach(@revtmp)
{ print “$_” ;}
print “\n”;
}
}

This is a rough attempt at the problem. It can be:
1. Checked for input validity

2. Enhanced with what ever you want to ice on top of it.

Have fun!

Copying and deleting files in multiple directories with perl.

Posted in Perl with tags , , on July 1, 2008 by vinaychilakamarri

Now I came out with a simple program for doing this. I was faced with a situation where I had to copy a file in 20 different folders in order to test some code that I was writing. I also had to change data and copy the file again many times. I figured that this process would kill me. I wanted to automate this process so that i don’t have to struggle further. Initially I played with Batch scripting.. never liked it 😦 And all of sudden I remembered about my old time dabbling with perl.. now that flash of idea came in as a real perl from the sky!. Here is the code:

#!c:/Perl/bin/perl.exe
print “Which file to copy: “;
$fl = <>;
chomp($fl);
use File::Copy;
opendir DIR, “.”; # . is the current directory

while ( $filename = readdir(DIR) )
{
if(-d $filename && $filename ne ‘.’ && $filename ne ‘..’)
{
print “Copied $fl to: ” , $filename,”\n”;
copy($fl,$filename);
}
}

Here I list the directories using ‘opendir’ on the current directory (here is where my 20 folders were). You could also take an input for this from the user. And for each item in the list returned, I copy the file in that directory with a ‘copy’ function. I filtered the “.”, “..” from the list for I don’t need to copy my files there. The “-d” checks for directory.

In the same manner, we can also delete files from the directories:

#!c:/Perl/bin/perl.exe
print “Which file to delete: “;
$fl = <>;
chomp($fl);
opendir DIR, “.”; # . is the current directory

while ( $filename = readdir(DIR) )
{
if(-d $filename && $filename ne ‘.’ && $filename ne ‘..’)
{
print “Deleted $fl in: ” , $filename,”\n”;
unlink(“$filename\\$fl”);
}
}

#observer the unlink function here. You have to specify the path of the file for each iteration. “\\” is a slash with an escape.