Click here to get back home

Why reading the FAQs is good (example)

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
Why reading the FAQs is good (example) Marc Bissonnette 05-25-2008
Posted by Marc Bissonnette on May 25, 2008, 10:10 pm
Please log in for more thread options
So I was commenting some code I wrote for a friend who's new to perl and
I came across the following in my code:

# replace decimals with 999999999 in order to check for non-numerical
# data, then switch it back (this is a lazyman's shortcut)

        $in =~ s/\./999999999/;
        if ($in =~ /\D/) {
                push @missing,'Hours contains non-numerical data';
                $missing = 1;
        }
        $in=~s/999999999/\./;

And I realized I've been too lazy with this for too long. So my first
thought was to post here with "how do I test for non-numerical in decimal
number data?" but, of course, that violates the "How to ask intelligent
questions in CPLM", so I googled it.

Came up with a bunch of non-relevant results until I saw a similar
question and the answer was "Your answer is in perldoc perldata"

So I did exactly that. Of course, the answer *is* right there:

warn "not a decimal number" unless /^-?\d+\.?\d*$/;

Which got me thinking - I take waaaay too many long-trips when there is
stuff in the regex language that would make my life easier, so I realized
that I need to understand the above, rather than just copy/paste into
code.

So, here's my understanding of

/^-?\d+\.?\d*$/;

/         start the search pattern
^         match the beginning of the line
-?         match a minus sign once or not at all
\d+         match a digit character zero or more times
\.?         match a decimal once or not at all
\d         match a digit character
*$         all to the end of the line
/         end the search pattern

Erm... I'm not so sure it's all stuck in my head.
I *think* this means
"Warn unless the input *only* matches minus signs, digit
characters and decimals, from the beginning to the end of the string"

Is that about right ?

I tried the above with the following in test.pl just to try to reinforce
it in my mind:

$foo = '3.5'; # no warning
$foo = '5'; # no warning
$foo = '-1'; # no warning
$foo = '4x4'; # warning - non-digit
$foo = '--3.2' # warning - more than one minus
$foo = '3.5.5' # warning - more than one decimal

Now that section of my code is:

        if ($in !~ /^-?\d+\.?\d*$/) {
                push @missing,'Hours contains non-numerical data';
                $missing = 1;
        }

Comments and general pointing and laughing welcome. :)

--
Marc Bissonnette
Looking for a new ISP? http://www.canadianisp.com
Largest ISP comparison site across Canada.

Posted by Uri Guttman on May 25, 2008, 11:09 pm
Please log in for more thread options

MB> So, here's my understanding of

MB> /^-?\d+\.?\d*$/;

MB> /         start the search pattern
MB> ^         match the beginning of the line

beginning of string in this case.

MB> -?         match a minus sign once or not at all
MB> \d+         match a digit character zero or more times

one or more times. you must have digits before the decimal point.
MB> \.?         match a decimal once or not at all
MB> \d         match a digit character
MB> *$         all to the end of the line

that is \d* which is zero or more digits. then comes $ which is end of
the string (or before an ending newline.

MB> /         end the search pattern
MB> I *think* this means
MB> "Warn unless the input *only* matches minus signs, digit
MB> characters and decimals, from the beginning to the end of the string"

well it has its flaws. it matches most numbers but what about just
fractional numbers like .9? it fails there since it requires digits
before any decimal point. also it doesn't allow a leading + sign.

look at Regexp::Common on cpan. i am sure it has a number validation
regex in there. it is trickier than your example here as it allows all
number formats (including exponents).

MB> Now that section of my code is:

MB>         if ($in !~ /^-?\d+\.?\d*$/) {
MB>                 push @missing,'Hours contains non-numerical data';
MB>                 $missing = 1;
MB>         }

the $missing = 1 is a red flag as boolean flags are poor coding IMO. you
have @missing which supposedly contains error strings so just check that
if it isn't empty.

MB> Comments and general pointing and laughing welcome. :)

MUAHAHAHAHAHAHHAH!!!

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

Posted by Marc Bissonnette on May 25, 2008, 11:31 pm
Please log in for more thread options

>
> MB> So, here's my understanding of
>
> MB> /^-?\d+\.?\d*$/;
>
> MB> / start the search pattern
> MB> ^ match the beginning of the line
>
> beginning of string in this case.
>
> MB> -? match a minus sign once or not at all
> MB> \d+ match a digit character zero or more times
>
> one or more times. you must have digits before the decimal point.
> MB> \.? match a decimal once or not at all
> MB> \d match a digit character
> MB> *$ all to the end of the line
>
> that is \d* which is zero or more digits. then comes $ which is end of
> the string (or before an ending newline.
>
> MB> / end the search pattern
> MB> I *think* this means
> MB> "Warn unless the input *only* matches minus signs, digit
> MB> characters and decimals, from the beginning to the end of the
> string"
>
> well it has its flaws. it matches most numbers but what about just
> fractional numbers like .9? it fails there since it requires digits
> before any decimal point. also it doesn't allow a leading + sign.

I noticed that when I was goofing around with it locally;
In readin your points and thinking about it (now that I understand it a
bit better), this seems to work (leading pluses or minuses, as well as
leading decimals, such as .5

/^\+?-?\d?\.?\d*$/

> look at Regexp::Common on cpan. i am sure it has a number validation
> regex in there. it is trickier than your example here as it allows all
> number formats (including exponents).

I'll definitely take a peek in there when the need arises - For now, I'm
helping a friend out by trying to automate some of their purchase orders,
packing slips and job accounting summaries, so I think the numerical data
will suffice being limited to positives and negatives :)

>
> MB> Now that section of my code is:
>
> MB> if ($in !~ /^-?\d+\.?\d*$/) {
> MB> push @missing,'Hours contains non-numerical data';
> MB> $missing = 1;
> MB> }
>
> the $missing = 1 is a red flag as boolean flags are poor coding IMO.
> you have @missing which supposedly contains error strings so just
> check that if it isn't empty.

Ya know, that thought honestly popped in my mind as soon as I hit send :)

It's an ingrained bad habit I'll have to work myself out of.

> MB> Comments and general pointing and laughing welcome. :)
>
> MUAHAHAHAHAHAHHAH!!!

:)

Better a MUAHAHAHAHHAHA than a RTFM :)


--
Marc Bissonnette
Looking for a new ISP? http://www.canadianisp.com
Largest ISP comparison site across Canada.

Posted by Marc Bissonnette on May 25, 2008, 11:37 pm
Please log in for more thread options
keyboard. This was the result:


(snip)

>> well it has its flaws. it matches most numbers but what about just
>> fractional numbers like .9? it fails there since it requires digits
>> before any decimal point. also it doesn't allow a leading + sign.
>
> I noticed that when I was goofing around with it locally;
> In readin your points and thinking about it (now that I understand it
> a bit better), this seems to work (leading pluses or minuses, as well
> as leading decimals, such as .5
>
> /^\+?-?\d?\.?\d*$/

Apologies for following up my own post: I just realized the above has a
flaw: It matches on or zero beginning digits (.4 or 0.4) but not two digits
or more (22.4)

This works better:

/^\+?-?(\d?|\d+)\.?\d*$/

--
Marc Bissonnette
Looking for a new ISP? http://www.canadianisp.com
Largest ISP comparison site across Canada.

Posted by Uri Guttman on May 26, 2008, 12:09 am
Please log in for more thread options

MB> keyboard. This was the result:


>> /^\+?-?\d?\.?\d*$/

MB> Apologies for following up my own post: I just realized the above has a
MB> flaw: It matches on or zero beginning digits (.4 or 0.4) but not two
digits
MB> or more (22.4)

MB> This works better:

MB> /^\+?-?(\d?|\d+)\.?\d*$/

the middle part is silly. it matches 0 or 1 digit OR one or more
digits. that is the same as 0 or more digits which is \d* all by itself.

but you can't use \d*\.?\d* as that will match the empty string (as will
your regex above). everything in yours is optional. look at this:

perl -ne 'print "yes\n" if /^\+?-?(\d?|\d+)\.?\d*$/'

yes
+
yes
+-
yes

note that the blank line was input. as i said, matching decimal numbers
is not trivial. use regexp::common as it has solved that problem.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

Similar ThreadsPosted
Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, April 21, 2005, 1:25 pm
Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, April 22, 2005, 3:33 pm
Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, April 24, 2005, 6:50 pm
Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, May 1, 2005, 11:27 am
Good documentation or good source examples for Image::Magick or converter from commandline to perl April 1, 2008, 5:23 pm
small mistake: http://perl.plover.com/FAQs/Namespaces.html July 3, 2007, 5:27 pm
QC: good function? July 16, 2004, 12:24 am
need a good tutorial August 25, 2004, 11:31 pm
2 methods to get the domains's IP,but neither of them is good. August 1, 2004, 1:56 pm
Good way to un-chomp an array August 13, 2004, 9:10 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap