perl code for if-elsif-else logic

perl code for if-elsif-else logic

am 02.06.2011 07:06:54 von Anirban Adhikary

Hi list

I have wirtten the following perl code which has some configuration
params such as prefix,suffix,midfix and nofix. The logic is filenames
will be selected based on prefix,suffix and midfix pattern.After the
fiter through above 3 patterns if file names exists with nofix
patterns it will be removed from the final list.

use strict;
use warnings;

#my $pfx ="CAT";
my $pfx = '';
my $sfx = '.Z' ;
my $mfx = 'r';
my $nfx= "dmp.Z,Q.Z,dat.Z,ctl.Z,A.Z";
my @fnames = ("CAT_arcdf231456_dmp.Z","ABCD_1234.txt","FILE_STAT.Z","CAT_ qwerty.Z");

my($re_pfx,$re_sfx,$re_mfx,$re_nfx);
my(@pre_fix,@sfx_fix,@mid_fix,@not_fix);

if((length($pfx)) > 0 and $pfx !~ /^\s+$/) {
@pre_fix = split(/,/,$pfx);
#find_largest_element(@pre_fix);
$re_pfx = join "|",@pre_fix;
$re_pfx = qr/$re_pfx/;
}
if((length($sfx)) > 0 and $sfx !~ /^\s+$/) {
@sfx_fix = split(/,/,$sfx);
$re_sfx = join "|",@sfx_fix;
$re_sfx = qr/$re_sfx/;
}

if((length($mfx)) > 0 and $mfx !~ /^\s+$/) {
@mid_fix = split(/,/,$mfx);
$re_mfx = join "|",@mid_fix;
$re_mfx = qr/$re_mfx/;
}


if((length($nfx)) > 0 and $nfx !~ /^\s+$/) {
@not_fix = split(/,/,$nfx);
$re_nfx = join "|", @not_fix;
$re_nfx = qr/$re_nfx/;
}
my @listed;

foreach my $fname(@fnames) {
if($fname =~ /^.*?$re_nfx$/) {
#print "FILE NAME [$fname] is not a valid file \n";
next;
}elsif ($fname =~ /^$re_pfx/){
push(@listed,$fname);
}elsif ($fname =~ /^.*$re_sfx$/) {
push(@listed,$fname);
}elsif ($fname =~ /^.*$re_mfx.*$/) {
push(@listed,$fname);
}elsif() {
push(@listed,$fname);
}else {
push(@listed,$fname);
}

}


for(@listed) {
print $_,"\n";
}

prefix,suffix and midfix can be defined and can not be.
So in the above scenario file ABCD_1234.txt should not be selected
because it is not matching $sfx but I m not able to filter this.

Thanks & Regards in advance
Anirban Adhikary.

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: perl code for if-elsif-else logic

am 02.06.2011 07:48:06 von Shlomi Fish

Hi Anirban,

a few comments on your code.

On Thursday 02 Jun 2011 08:06:54 Anirban Adhikary wrote:
> Hi list
>=20
> I have wirtten the following perl code which has some configuration
> params such as prefix,suffix,midfix and nofix. The logic is filenames
> will be selected based on prefix,suffix and midfix pattern.After the
> fiter through above 3 patterns if file names exists with nofix
> patterns it will be removed from the final list.
>=20
> use strict;
> use warnings;
>=20

It's good you're using strict and warnings.

> #my $pfx =3D"CAT";
> my $pfx =3D '';
> my $sfx =3D '.Z' ;
> my $mfx =3D 'r';
> my $nfx=3D "dmp.Z,Q.Z,dat.Z,ctl.Z,A.Z";
> my @fnames =3D
> ("CAT_arcdf231456_dmp.Z","ABCD_1234.txt","FILE_STAT.Z","CAT_ qwerty.Z");
>=20
> my($re_pfx,$re_sfx,$re_mfx,$re_nfx);
> my(@pre_fix,@sfx_fix,@mid_fix,@not_fix);
>=20
> if((length($pfx)) > 0 and $pfx !~ /^\s+$/) {
> @pre_fix =3D split(/,/,$pfx);
> #find_largest_element(@pre_fix);
> $re_pfx =3D join "|",@pre_fix;
> $re_pfx =3D qr/$re_pfx/;
> }
> if((length($sfx)) > 0 and $sfx !~ /^\s+$/) {
> @sfx_fix =3D split(/,/,$sfx);
> $re_sfx =3D join "|",@sfx_fix;
> $re_sfx =3D qr/$re_sfx/;
> }
>=20
> if((length($mfx)) > 0 and $mfx !~ /^\s+$/) {
> @mid_fix =3D split(/,/,$mfx);
> $re_mfx =3D join "|",@mid_fix;
> $re_mfx =3D qr/$re_mfx/;
> }
>=20

1. You have quite a lot of duplicate code here. You can extract it into a=20
function call, a hash and/or a loop.

2. You may wish to use http://perldoc.perl.org/functions/quotemeta.html .

3. You should have a space between the "if" and the "(".

4. You can just say =ABif (length($mfx) and $mfx !~ /\A\s+\z/)=BB.

>=20
> if((length($nfx)) > 0 and $nfx !~ /^\s+$/) {
> @not_fix =3D split(/,/,$nfx);
> $re_nfx =3D join "|", @not_fix;
> $re_nfx =3D qr/$re_nfx/;
> }
> my @listed;
>=20

You should have an empty line between "}" and the "my @listed";

> foreach my $fname(@fnames) {
> if($fname =3D~ /^.*?$re_nfx$/) {
> #print "FILE NAME [$fname] is not a valid file=20
\n";
> next;
> }elsif ($fname =3D~ /^$re_pfx/){
> push(@listed,$fname);
> }elsif ($fname =3D~ /^.*$re_sfx$/) {
> push(@listed,$fname);
> }elsif ($fname =3D~ /^.*$re_mfx.*$/) {
> push(@listed,$fname);
> }elsif() {
> push(@listed,$fname);
> }else {
> push(@listed,$fname);
> }
>=20

1. Your indentation here is bad.

2. You can combine the elsif into several clauses using "or" or "||".

3. It's better not to cuddle the else's and elsif's:

} elsif ($fname =3D~ /^$re_pfx/) {
push(@listed,$fname);
} elsif ($fname =3D~ /^.*$re_sfx$/) {


Regards,

Shlomi Fish

=2D-=20
=2D--------------------------------------------------------- -------
Shlomi Fish http://www.shlomifish.org/
=46irst stop for Perl beginners - http://perl-begin.org/

I hope that you agree with me that 99.9218485921% of the users wouldn't bot=
her
themselves with recompilation (or any other manual step for that matter) to
make their games run 1.27127529900685765% faster ;-) -- Nadav Har'El

Please reply to list if it's a mailing list post - http://shlom.in/reply .

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: perl code for if-elsif-else logic

am 02.06.2011 10:56:32 von jwkrahn

Anirban Adhikary wrote:
> Hi list

Hello,

> I have wirtten the following perl code which has some configuration
> params such as prefix,suffix,midfix and nofix. The logic is filenames
> will be selected based on prefix,suffix and midfix pattern.After the
> fiter through above 3 patterns if file names exists with nofix
> patterns it will be removed from the final list.
>
> use strict;
> use warnings;
>
> #my $pfx ="CAT";
> my $pfx = '';
> my $sfx = '.Z' ;
> my $mfx = 'r';
> my $nfx= "dmp.Z,Q.Z,dat.Z,ctl.Z,A.Z";

Are these values supplied by you, in the program, or are they supplied
by a user from outside the program?

If they are defined inside the program then you could just assign the
regular expressions here.


> my @fnames = ("CAT_arcdf231456_dmp.Z","ABCD_1234.txt","FILE_STAT.Z","CAT_ qwerty.Z");
>
> my($re_pfx,$re_sfx,$re_mfx,$re_nfx);
> my(@pre_fix,@sfx_fix,@mid_fix,@not_fix);
>
> if((length($pfx))> 0 and $pfx !~ /^\s+$/) {

I would probably write that as:

if ( defined $pfx && $pfx =~ /\S/ ) {


> @pre_fix = split(/,/,$pfx);

This array only needs to be visible inside this scope so you should
define it here instead of at file scope. Also, your string(s) may
contain regular expression meta-characters so you need to quotemeta the
string(s):

my @pre_fix = map quotemeta, split /,/, $pfx;


> #find_largest_element(@pre_fix);
> $re_pfx = join "|",@pre_fix;

If you are not using find_largest_element() then you don't really need
the array:

$re_pfx = join '|', map quotemeta, split /,/, $pfx;


> $re_pfx = qr/$re_pfx/;

A prefix only occurs at the start of a string so:

$re_pfx = qr/\A$re_pfx/;


> }
> if((length($sfx))> 0 and $sfx !~ /^\s+$/) {
> @sfx_fix = split(/,/,$sfx);
> $re_sfx = join "|",@sfx_fix;
> $re_sfx = qr/$re_sfx/;

A suffix only occurs at the end of a string so:

$re_sfx = qr/$re_sfx\z/;


> }
>
> if((length($mfx))> 0 and $mfx !~ /^\s+$/) {
> @mid_fix = split(/,/,$mfx);
> $re_mfx = join "|",@mid_fix;
> $re_mfx = qr/$re_mfx/;
> }
>
>
> if((length($nfx))> 0 and $nfx !~ /^\s+$/) {
> @not_fix = split(/,/,$nfx);
> $re_nfx = join "|", @not_fix;
> $re_nfx = qr/$re_nfx/;

It appears that nofix only occurs at the end of a string so:

$re_nfx = qr/$re_nfx\z/;


> }
> my @listed;
>
> foreach my $fname(@fnames) {
> if($fname =~ /^.*?$re_nfx$/) {

The '^.*?' at the front just adds complexity that you don't need, only
the end=of-string anchor is required:

if ( $fname =~ /$re_nfx$/ ) {


> #print "FILE NAME [$fname] is not a valid file \n";
> next;
> }elsif ($fname =~ /^$re_pfx/){

Because $pfx contains the string '' the value of $re_pre will be
undefined so when I run your code I get these messages:

Use of uninitialized value $re_pfx in regexp compilation at your_code.pl
line 60.

You may want to test for defined() before trying to execute the regular
expressions.


> push(@listed,$fname);
> }elsif ($fname =~ /^.*$re_sfx$/) {

The '^.*' at the front just adds complexity that you don't need, only
the end=of-string anchor is required:

} elsif ( $fname =~ /$re_sfx$/ ) {


> push(@listed,$fname);
> }elsif ($fname =~ /^.*$re_mfx.*$/) {

The '^.*' at the front and the '.*$' at the end just adds complexity
that you don't need:

} elsif ( $fname =~ /$re_mfx/ ) {


> push(@listed,$fname);
> }elsif() {

The empty conditional is a syntax error so this elsif block should be
removed.

> push(@listed,$fname);
> }else {
> push(@listed,$fname);
> }
> }

Each block after the initial if block executes the statement
push(@listed,$fname); so your loop could be simplified to:

for my $fname ( @fnames ) {
next if $fname =~ /$re_nfx$/;
push @listed, $fname;
}


> for(@listed) {
> print $_,"\n";
> }
>
> prefix,suffix and midfix can be defined and can not be.
> So in the above scenario file ABCD_1234.txt should not be selected
> because it is not matching $sfx but I m not able to filter this.

So, in summery, this looks like it does what you require:

my ( $re_pfx, $re_sfx, $re_mfx, $re_nfx );

if ( defined $pfx && $pfx =~ /\S/ ) {
my @pre_fix = map quotemeta, split /,/, $pfx;
#find_largest_element( @pre_fix );
$re_pfx = join '|', @pre_fix;
$re_pfx = qr/\A$re_pfx/;
}

if ( defined $sfx && $sfx =~ /\S/ ) {
$re_sfx = join '|', map quotemeta, split /,/, $sfx;
$re_sfx = qr/$re_sfx\z/;
}

if ( defined $mfx && $mfx =~ /\S/ ) {
$re_mfx = join '|', map quotemeta, split /,/, $mfx;
$re_mfx = qr/$re_mfx/;
}

if ( defined $nfx && $nfx =~ /\S/ ) {
$re_nfx = join '|', map quotemeta, split /,/, $nfx;
$re_nfx = qr/$re_nfx\z/;
}

my @listed;

for my $fname ( @fnames ) {
if ( defined $re_nfx && $fname =~ $re_nfx ) {
#print "FILE NAME [$fname] is not a valid file \n";
next;
}
elsif ( defined $re_pfx && $fname =~ $re_pfx ) {
push @listed, $fname;
}
elsif ( defined $re_sfx && $fname =~ $re_sfx ) {
push @listed, $fname;
}
elsif ( defined $re_mfx && $fname =~ $re_mfx ) {
push @listed, $fname;
}
}

for ( @listed ) {
print "$_\n";
}




John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/