Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^2: perl typecasting

by perl_junkie (Acolyte)
on Feb 05, 2008 at 00:21 UTC ( [id://666156]=note: print w/replies, xml ) Need Help??


in reply to Re: perl typecasting
in thread perl typecasting

These are the 2 validation subroutines I have used for integer and decimal data type checks. I am preparing to load the data into DB2 database after this process, so the data types are defined accordingly. I am not too good with regular expressions, so have tried to code to the best of my knowledge using other functions.

############# SUB-ROUTINE TO CHECK FOR INTEGER TYPE ############## #check for small int, big int and int data types and return a 0 if cor +rect # else return a 1 sub int_chk { my $input = shift; $input = $input+0; if ($data_type eq 'SMALLINT') { if ($input > -32768 && $input < 32768) { return $positive; } else { return $negative; } } elsif ($data_type eq 'INTEGER') { if ($input > -2147483648 && $input < 2147483647) { return $positive; } else { return $negative; } } elsif ($data_type eq 'BIGINT') { if ($input > -9223372036854770000 && $input < 9223372036854770000) { return $positive; } else { return $negative; } } else { return $negative; } } ############ SUB-ROUTINE TO CHECK FOR DECIMAL TYPE ############## sub decimal_chk { #Here, I get a decimal input and separate it into 2 separate integers # say 123.45 split into 123 and 45 # I need to check if -999 < 123 < 999 and -99 < 45 < 99 . my $data=shift; my $index=index($data,".")+1; $main=substr($data,0,$index-1); #print "Integer part is $main\n"; if ($index > 0) { $prec=substr($data,$index,length($data)-($index)); } else { $prec=''; } $u_len=length($main); $l_len=length($prec); $upper=9; $lower=9; for ($u_count = 1; $u_count < $u_len; $u_count++) { $upper=$upper."9"; } for ($l_count = 1; $l_count < $l_len; $l_count++) { $lower=$lower."9"; } # 123.45 will be declared as decimal(5,2), 2 being the decimal length if ($main > (-1*$upper) && $main < $upper) { if ($prec > (-1*$lower) && $prec < $lower) { if (($u_len <= ($data_precision-$data_dec_len)) && ($l_len <= +$data_dec_len)) # Final length check with specified lengths { return $positive; } else { return $negative; } } else { return $negative; } } else { return $negative; } }

Replies are listed 'Best First'.
Re^3: perl typecasting
by TGI (Parson) on Feb 05, 2008 at 03:11 UTC

    I carefully read your code and made a few tweaks to it. You are making a good start. Read and reread the docs, ask questions and keep working at it. I strongly recommend that you take the time to understand regexes. They are a very, very, useful and powerful tool.

    I noticed some problems with your code as I read it.

    • You have inconsistent use of inclusive vs exclusive comparisons.
    • Your algorithm for floating point validation would allow numbers like '12. 3' (that's a space between the . and the 3) to pass.
    • There are a number of variables that seem to come from nowhere. Are they globals?
    • You are using C style for loops.

    For loops in perl are usually done as follows:

    # You had for ($l_count = 1; $l_count < $l_len; $l_count++) { $lower=$lower."9"; } # Try this instead: for my $l_count ( 1..$l_len ) { $lower=$lower."9"; } # To build up a string like this you should be using the 'x' operator my $lower = '9' x $l_len;

    Here's your code with my tweaks applied. What follows is untested, but should work.

    use constant MATCH => 1; # Return value for good match use constant FAIL => 0; # Retrun value for failed match use constant MIN => 0; # Index of minimum value for integer checks use constant MAX => 1; # Index of maximum value for integer checks ############# SUB-ROUTINE TO CHECK FOR INTEGER TYPE ############## #check for small int, big int and int data types and return a 0 if cor +rect # else return a 1 sub int_chk { my $input = shift; my $data_type = shift; # Where was this coming from in your code? $input = $input+0; # Test for integerness if ( $input != int( $input ) ) { return FAIL; } # Use a hash lookup to simplify your code. my %check = ( # type MIN + MAX SMALLINT => [ -32768, 32767 ], INTEGER => [ -2147483648, 2147483647 ], BIGINT => [ -9223372036854770000, 9223372036854770000 ], ); # Test for range if ( exists $check{$data_type} ) { my $match = ( $input >= $check{$data_type}[MIN] # I used inclusive range +s here and $input <= $check{$data_type}[MAX] ) ? MATCH : FAIL; return $match; } else { return FAIL; } die "Unreachable code executed"; } sub decimal_chk { my $input = shift; my $whole_places = shift || 3; # Set a default value my $decimal_places = shift || 2; # for each of these args return $input =~ / ^ # Start of input -? # Optional minus sign \d{0,$whole_places} # 1-? whole number digits ( \. # Manadatory decimal point \d{0,$decimal_places} # 1-? decimal places )? # decimal section is optional $ # End of input /x ? MATCH : FAIL ; # x modifier allows comments and whitespac +e }


    TGI says moo

      TGI, I really appreciate you taking time off to review my code. Thanks..!!!

      I am working on my regex skills now. I should get better at it in the coming weeks.

      The variables I have not defined are globals.. sorry I should have mentioned that... Your code looks much cleaner and easier to debug than mine...!!!! Thanks a lot...!!!!!

      I have got a lot of people telling me about using the modules. Can anyone give me info on how I can check this. Everytime I use this, I get this error message.

      "Can't locate Regexp/Common.pm in @INC (@INC contains: /etrade/pkgs/perl/5.8.0_crm/lib/perl5 /etrade/pkgs/perl/5.8.0_crm/lib/perl5/site_perl /etrade/pkgs/perl/5.8.0_crm/lib/site_perl /usr/perl5/5.00503/sun4-solaris /usr/perl5/5.00503 /usr/perl5/site_perl/5.005/sun4-solaris /usr/perl5/site_perl/5.005 .) at dm.pl line 3."

        I see part of the problem already with the text of the error message you posted.

        Your @INC (the array of directories to search for libraries) includes libraries from three different perl installations

        1. /etrade/pkgs/perl/5.8.0_crm/
        2. /usr/perl5/5.00503/
        3. /usr/perl5/site_perl/5.005/

        It looks to me like:

        • Your PERL5LIB environment variable is wrong or at least incorrect for the perl instance you are running.
        • Your perl installs may be damaged.
        • You need to find out which perl you are using. Try which perl or whereis perl in your shell to find it.

        Check the output of perl -V.

        I recommend asking your sysadmin for help getting the perl environment straightened out.

        If that doesn't work, try starting another thread asking for help on specifically this problem. Include the output of perl -V in your post.

        You really do want to use strict and warnings. Also, diagnostics is handy when you are starting out.


        TGI says moo

        Thanks for giving me your company name, software versions, and directory structure. That was smart.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://666156]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2024-04-19 21:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found