Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > testing whether a number is an integer

Reply
Thread Tools

testing whether a number is an integer

 
 
ccc31807
Guest
Posts: n/a
 
      11-09-2010
This is probably a Dumb Question, but I'll ask it anyway.

I have a number, which I use to validate an array, like this:
$number = scalar($@array) / 3;
If $number is an integer, the array is perfect and can be processed.
If it isn't, it's malformed and must be written to an error log.

Some languages have a predicate like is(integer()) which tests the
obvious. Does Perl have a built-in is_integer() equivalent, or will
have have to install something like Test::Numeric?

Thanks, CC.
 
Reply With Quote
 
 
 
 
Uri Guttman
Guest
Posts: n/a
 
      11-09-2010
>>>>> "c" == ccc31807 <(E-Mail Removed)> writes:

c> This is probably a Dumb Question, but I'll ask it anyway.
c> I have a number, which I use to validate an array, like this:
c> $number = scalar($@array) / 3;

that isn't legal code. $@array makes no sense. i will assume you meant
just @array

c> If $number is an integer, the array is perfect and can be processed.
c> If it isn't, it's malformed and must be written to an error log.

c> Some languages have a predicate like is(integer()) which tests the
c> obvious. Does Perl have a built-in is_integer() equivalent, or will
c> have have to install something like Test::Numeric?

simple math will do it for you. the int func will truncate something to
an integer. so it $foo/3 is an int, its int() value will be the same.

my $int = @array/3 # no need for scalar() as / provides scalar context

if ( $int == int( $int ) ) { ...

uri

--
Uri Guttman ------ http://www.velocityreviews.com/forums/(E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      11-09-2010
"Uri Guttman" <(E-Mail Removed)> writes:
>>>>>> "c" == ccc31807 <(E-Mail Removed)> writes:

>
> c> This is probably a Dumb Question, but I'll ask it anyway.
> c> I have a number, which I use to validate an array, like this:
> c> $number = scalar($@array) / 3;
>
> that isn't legal code. $@array makes no sense. i will assume you meant
> just @array
>
> c> If $number is an integer, the array is perfect and can be processed.
> c> If it isn't, it's malformed and must be written to an error log.
>
> c> Some languages have a predicate like is(integer()) which tests the
> c> obvious. Does Perl have a built-in is_integer() equivalent, or will
> c> have have to install something like Test::Numeric?
>
> simple math will do it for you. the int func will truncate something to
> an integer. so it $foo/3 is an int, its int() value will be the same.
>
> my $int = @array/3 # no need for scalar() as / provides scalar context
>
> if ( $int == int( $int ) ) { ...


I'd say the condition you're really testing is whether the number of
elements in @array is a multiple of 3. So I might write something
like this:

die "Malformed array\n" if scalar @array % 3 != 0;
$number = scalar @array / 3;

I know you want better error handling that die(); this is just
an example.

And yes, I know the "scalar" operator is not strictly necessary.
IMHO it makes the code more readable.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      11-10-2010
"Uri Guttman" <(E-Mail Removed)> wrote:
>>>>>> "c" == ccc31807 <(E-Mail Removed)> writes:

>
> c> This is probably a Dumb Question, but I'll ask it anyway.
> c> I have a number, which I use to validate an array, like this:
> c> $number = scalar($@array) / 3;
> c> If $number is an integer,
> c> the array is perfect and can be processed.
> c> If it isn't, it's malformed and must be written to an error log.


Is this a complicated way of testing if the number of elements in @array
is a multiple of 3?

Then why don't you use the modulo operator?
print "Not a multiple of 3 elements" if @array % 3;

jue
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      11-10-2010
"Uri Guttman" <(E-Mail Removed)> wrote:
>simple math will do it for you. the int func will truncate something to
>an integer. so it $foo/3 is an int, its int() value will be the same.
>
>my $int = @array/3 # no need for scalar() as / provides scalar context
>
>if ( $int == int( $int ) ) { ...


While probably not a problem in this case I would be _VERY_ wary of
using this code in general. Any rounding error caused by binary
arithmetic will bite you and therefore I would not ever use it, not even
if the division should yield an integer in the case of success.

Why not simply use modulo? It is meant for exactly this purpose and it
does not suffer from rounding errors.

jue
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      11-10-2010
Jürgen Exner <(E-Mail Removed)> wrote:
>"Uri Guttman" <(E-Mail Removed)> wrote:
>>>>>>> "c" == ccc31807 <(E-Mail Removed)> writes:

>>
>> c> This is probably a Dumb Question, but I'll ask it anyway.
>> c> I have a number, which I use to validate an array, like this:
>> c> $number = scalar($@array) / 3;
>> c> If $number is an integer,
>> c> the array is perfect and can be processed.
>> c> If it isn't, it's malformed and must be written to an error log.

>
>Is this a complicated way of testing if the number of elements in @array
>is a multiple of 3?
>
>Then why don't you use the modulo operator?
> print "Not a multiple of 3 elements" if @array % 3;


Coming to think of it I have a very strong feeling that this is another
X-Y problem, caused by choosing a poor data structure.

If the number of elements in that array must be a multiple of 3 then
(unless there are some extraordinary circumstances) this implies that
the data is not a plain list of single elements but it is a list of
triplets. Had the OP used a proper data structure to represent this
fact, e.g. an array of triplets(*), then the integrity of his data would
be ensured by the data structure and we would not have this discussion
in the first place.

*: each triplet could be a hash or an array with 3 elements, depending
on the kind of data in each triplet.

jue
 
Reply With Quote
 
ccc31807
Guest
Posts: n/a
 
      11-10-2010
On Nov 9, 10:18*pm, J rgen Exner <(E-Mail Removed)> wrote:
> J rgen Exner <(E-Mail Removed)> wrote:
> >"Uri Guttman" <(E-Mail Removed)> wrote:
> >>>>>>> "c" == ccc31807 *<(E-Mail Removed)> writes:

>
> >> *c> This is probably a Dumb Question, but I'll ask it anyway.
> >> *c> I have a number, which I use to validate an array, like this:
> >> *c> $number = scalar($@array) / 3;
> >> *c> If $number is an integer,
> >> *c> the array is perfect and can be processed.
> >> *c> If it isn't, it's malformed and must be written to an error log.

>
> >Is this a complicated way of testing if the number of elements in @array
> >is a multiple of 3?

>
> >Then why don't you use the modulo operator?
> > * *print "Not a multiple of 3 elements" if @array % 3;

>
> Coming to think of it I have a very strong feeling that this is another
> X-Y problem, caused by choosing a poor data structure.
>
> If the number of elements in that array must be a multiple of 3 then
> (unless there are some extraordinary circumstances) this implies that
> the data is not a plain list of single elements but it is a list of
> triplets. Had the OP used a proper data structure to represent this
> fact, e.g. an array of triplets(*), then the integrity of his data would
> be ensured by the data structure and we would not have this discussion
> in the first place.
>
> *: each triplet could be a hash or an array with 3 elements, depending
> on the kind of data in each triplet.
>
> jue


This is a source file from a database of student courses. The source
file contains records like this:
ID,LAST,FIRST,MIDDLE,MAJOR, ... [COURSES]
where [COURSES] depends on the student enrollment in the term, which
can be from zero up to possible 7 or 8, and would be as follows:
ENG-101,BIO-202,ART-303,ABCD,BCDE,CDEF,N,N,X
These values are triplets, with all the courses first, then all the
sections, then all the statuses.

When I parse the line, I collect the individual data items into loop
variables like this:
my ($id, $last, $first, $middle, $major ... , @courses) =
parse_line();
The @courses array then contains the enrollment info. I divide it by
3, which gives me the number of courses. I then munge the @courses
data (actually by turning it into a series of strings like this:
"ENG-101-ABC-N")
The other data goes into a hash keyed on the ID, so I can print the
reports like this:

foreach my $k (keys %students)
{
print OUT qq($k,$students{$k}{last}, ... \n);
}

The vast majority of the time the @courses array is perfect, but
rarely it is malformed in some way, thus requiring me to check the
format of the array.

I have been doing it by moding by 3 and checking to see if the result
is not zero, but it strikes me that, if I could check to see if the
result of the division by 3 is an integer, I wouldn't have to resort
to the extra step.

CC.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-10-2010
ccc31807 <(E-Mail Removed)> writes:
[snip]
> The vast majority of the time the @courses array is perfect, but
> rarely it is malformed in some way, thus requiring me to check the
> format of the array.
>
> I have been doing it by moding by 3 and checking to see if the result
> is not zero, but it strikes me that, if I could check to see if the
> result of the division by 3 is an integer, I wouldn't have to resort
> to the extra step.


There's an extra step either way: either you need to check whether
the number of fields is a multiple of 3, or you need to check
whether the result of dividing that number by 3 is an integer.

There is, of course, More Than One Way To Do It. I suggest that
checking whether the number of fields is a multiple of 3 expresses
the intent more clearly.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      11-10-2010
On Wed, 10 Nov 2010 06:25:45 -0800 (PST), ccc31807 <(E-Mail Removed)> wrote:

>This is a source file from a database of student courses. The source
>file contains records like this:
>ID,LAST,FIRST,MIDDLE,MAJOR, ... [COURSES]
>where [COURSES] depends on the student enrollment in the term, which
>can be from zero up to possible 7 or 8, and would be as follows:
>ENG-101,BIO-202,ART-303,ABCD,BCDE,CDEF,N,N,X
>These values are triplets, with all the courses first, then all the
>sections, then all the statuses.
>
>When I parse the line, I collect the individual data items into loop
>variables like this:
>my ($id, $last, $first, $middle, $major ... , @courses) =
>parse_line();
>The @courses array then contains the enrollment info. I divide it by
>3, which gives me the number of courses. I then munge the @courses
>data (actually by turning it into a series of strings like this:
>"ENG-101-ABC-N")
>The other data goes into a hash keyed on the ID, so I can print the
>reports like this:
>
>foreach my $k (keys %students)
>{
> print OUT qq($k,$students{$k}{last}, ... \n);
>}
>
>The vast majority of the time the @courses array is perfect, but
>rarely it is malformed in some way, thus requiring me to check the
>format of the array.
>
>I have been doing it by moding by 3 and checking to see if the result
>is not zero, but it strikes me that, if I could check to see if the
>result of the division by 3 is an integer, I wouldn't have to resort
>to the extra step.
>


Whatever you are doing to get the courses array populated should
be valid before population.

A clear sign of bad validation or parsing technique is that you
actually have to do a modulo on the finished array.
The finished array should be pristeen.
If you have a remainder, the entire array is flawed.
The place to find flaws is before the array is populated, not after.
Craft a better parsing strategy.

-sln
 
Reply With Quote
 
ccc31807
Guest
Posts: n/a
 
      11-10-2010
On Nov 10, 12:46*pm, (E-Mail Removed) wrote:
> Whatever you are doing to get the courses array populated should
> be valid before population.


I'm not 'doing' anything before populating the array. I'm reading a
file line by line, placing all the singular datums in appropriate
variables ($id, $last, $first, etc.), and whatever is left over I glob
into an array. I don't know how many items remain in the line at this
point -- it could be nothing.

> A clear sign of bad validation or parsing technique is that you
> actually have to do a modulo on the finished array.
> The finished array should be pristeen.


In theory, yes. However, in practice the 'array' is simply a list of
however many datums remain in the line. I guess I could test the line
before parsing to see how many 'items' it contains, but that would
really be an extra step.

> If you have a remainder, the entire array is flawed.
> The place to find flaws is before the array is populated, not after.
> Craft a better parsing strategy.


Such as? Here's my logic. You tell me if you see a better way. Assume
that each line looks like this:
123,Smith,John,Q,ENG-101,BIO-202,ART-303,ABCD,BCDE,CDEF,N,N,X

my %students;
while (<INFILE>)
{
next unless /\w/;
chomp;
my ($id, $last, $first, $middle, @courses) = parse_line();
$students{$id} = {
last => $last,
first => $first,
middle => $middle,
};
my $number = scalar(@courses) / 3;
my $mod = scalar(@courses) % 3;
unless ($mod == 0) { warn "MALFORMED $_\n"; }
else {
# munge @courses based on the value of $number
# construct a $course variable for each section and status
# then do something like this
push @{$students{$id}{courses}}, $course;
}
}

I would like to replace the unless test with something like this:
(is_integer($number)) Ideas?

CC.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FAQ 4.73 How do I determine whether a scalar is a number/whole/integer/float? PerlFAQ Server Perl Misc 0 03-30-2011 04:00 PM
FAQ 4.73 How do I determine whether a scalar is a number/whole/integer/float? PerlFAQ Server Perl Misc 0 01-30-2011 11:00 PM
testing whether a double is a whole number David Marsh C Programming 3 07-03-2005 04:13 PM
Testing whether imported function failed Python 0 06-08-2004 04:12 PM
check whether a given number is an integer Reddy ASP .Net 2 01-23-2004 03:19 PM



Advertisments