[31715] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 2978 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Jun 8 16:09:36 2010

Date: Tue, 8 Jun 2010 13:09:16 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Tue, 8 Jun 2010     Volume: 11 Number: 2978

Today's topics:
        convert integer to string <cartercc@gmail.com>
    Re: convert integer to string <ralph@happydays.com>
    Re: convert integer to string <uri@StemSystems.com>
    Re: convert integer to string <cartercc@gmail.com>
    Re: convert integer to string <glex_no-spam@qwest-spam-no.invalid>
    Re: convert integer to string <glex_no-spam@qwest-spam-no.invalid>
    Re: convert integer to string <ben@morrow.me.uk>
    Re: convert integer to string <cartercc@gmail.com>
    Re: convert integer to string <uri@StemSystems.com>
    Re: convert integer to string <uri@StemSystems.com>
    Re: convert integer to string <cartercc@gmail.com>
    Re: convert integer to string <cartercc@gmail.com>
    Re: convert integer to string <willem@turtle.stack.nl>
    Re: convert integer to string <glex_no-spam@qwest-spam-no.invalid>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Tue, 8 Jun 2010 11:10:00 -0700 (PDT)
From: ccc31807 <cartercc@gmail.com>
Subject: convert integer to string
Message-Id: <87c9ec51-0b61-4eab-8ac7-5dc47d1a60de@c33g2000yqm.googlegroups.com>

This is embarrassing!

I read an input file, split each row on the separators, pick out the
unique key (which consists of seven digits), create a hash element on
the key, and read the other values into an anonymous hash. This has
worked for years without a hitch.

Yesterday, my user requested the app to print a calculated field,
which is a list of names contained in a secondary file. I thought, "No
problem, I'll just create a new element in my anonymous hash,
concatenate each name unless the name already matched the string, and
print it out." Didn't work, but the errors seemed to be random and
arbitrary.

After a couple of hours, I used bdf's trick to print out the hash, and
discovered much to my embarrassment that the keys weren't the same. In
the main loop where I created the hash, the keys were as expected and
consisted of seven characters which are all digits. HOWEVER, in the
loop where I created the additional hash element, the keys with
leading zeros did not match. Here is an example of the hash:

0123456 => HASH(deadbeed)
  id => 0123456
  name => joe
  gender => male
  new_field =>
123456 =>  HASH(deadbeef)
  new_field => list of concatenated strings

I read the main file and create the main hash on the unique key, one
element of which is 'new_field' with an initial value of ' '. Then, I
read a secondary file which contains the key and ATTEMPT to
concatenate an element to the main hash element new_field. Instead, it
creates a new hash element with the numeric value of the unique key
instead of the string value.

So, I guess my question is how I convert an integer to a string to
preserve the leading zeros.

According to MJD on his infrequently asked questions page, the answer
is, "Try using a whip." But that doesn't tell me what kind of whip.
http://perl.plover.com/IAQ/IAQlist.html#how_can_i_force_perl_to_treat_a_number_as_a_string

CC.


------------------------------

Date: Tue, 08 Jun 2010 14:19:10 -0400
From: Ralph Malph <ralph@happydays.com>
Subject: Re: convert integer to string
Message-Id: <cde2b$4c0e899f$40779ac3$10782@news.eurofeeds.com>

> So, I guess my question is how I convert an integer to a string to
> preserve the leading zeros.
>
> According to MJD on his infrequently asked questions page, the answer
> is, "Try using a whip." But that doesn't tell me what kind of whip.
> http://perl.plover.com/IAQ/IAQlist.html#how_can_i_force_perl_to_treat_a_number_as_a_string
The whip I usually use is string concatenation or variable interpolation 
within double quotes.
Something like

my $number=5;
my $string="000".$number;

Surely there are several ways to do this.
This always works for me! :)



------------------------------

Date: Tue, 08 Jun 2010 14:26:10 -0400
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: convert integer to string
Message-Id: <87bpbl2xfh.fsf@quad.sysarch.com>

>>>>> "c" == ccc31807  <cartercc@gmail.com> writes:

  c> After a couple of hours, I used bdf's trick to print out the hash, and
  c> discovered much to my embarrassment that the keys weren't the same. In
  c> the main loop where I created the hash, the keys were as expected and
  c> consisted of seven characters which are all digits. HOWEVER, in the
  c> loop where I created the additional hash element, the keys with
  c> leading zeros did not match. Here is an example of the hash:

what trick? use Data::Dumper and no trick is needed.

  c> 0123456 => HASH(deadbeed)
  c>   id => 0123456

that is an OCTAL literal. when parsed into perl it will be converted to
an integer and later printed in decimal. if those are always keys which
means strings, never print or use them without quotes. don't think of
them as numbers but strings with all digits.

  c> So, I guess my question is how I convert an integer to a string to
  c> preserve the leading zeros.

if you already have corrupted numbers, use sprintf to pad them with
zeros. but i suspect you will still have nasty errors as you will have
converted from the literal octal value now to a decimal. you can sprintf
the number back in octal to compensate. the proper solution is to never
let perl see those as literal octal numbers but always as strings. i
dunno what your code is doing (as you didn't post any) to make this
happen. are you doing an eval on some incoming data? that is a no-no! do
a proper parse and you can keep those keys as strings.

uri

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


------------------------------

Date: Tue, 8 Jun 2010 11:45:01 -0700 (PDT)
From: ccc31807 <cartercc@gmail.com>
Subject: Re: convert integer to string
Message-Id: <cc429097-c3b0-4bfd-b1ac-810f63000017@y11g2000yqm.googlegroups.com>

On Jun 8, 2:26=A0pm, "Uri Guttman" <u...@StemSystems.com> wrote:
> dunno what your code is doing (as you didn't post any) to make this
> happen. are you doing an eval on some incoming data? that is a no-no! do
> a proper parse and you can keep those keys as strings.

This is what I'm doing.

The main file looks like this:
0123456|joe|male|etc ...

which I manipulate as follows:
my ($id, $name, $gender, @rest) =3D split /\|/;
$main_hash{$id} =3D {
  id =3D> $id,
  name =3D> $name.
  gender =3D> $gender,
  rest =3D> @rest,
  new_value =3D> ' ',
 };

The secondary file looks like this:
0123456|this|etc ...
0123456|is|etc ...
0123456|a|etc ...
0123456|list|etc ...
0123456|of|etc ...
0123456|strings|etc ...

which I manipulate as follows:
my ($id, $string, @rest) =3D split /\|/;
$main_hash{$id}{new_value} .=3D $string unless $main_hash{$id}
{new_value} =3D~ /$string/; #the strings can be duplicated but I only
want one of each

So, should I double quote the $id when I use it as a hash key? That
strikes me as idiosyncratic even for Perl.

CC.


------------------------------

Date: Tue, 08 Jun 2010 14:18:58 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: convert integer to string
Message-Id: <4c0e97a2$0$87068$815e3792@news.qwest.net>

ccc31807 wrote:
> On Jun 8, 2:26 pm, "Uri Guttman" <u...@StemSystems.com> wrote:
>> dunno what your code is doing (as you didn't post any) to make this
>> happen. are you doing an eval on some incoming data? that is a no-no! do
>> a proper parse and you can keep those keys as strings.
> 
> This is what I'm doing.
> 
> The main file looks like this:
> 0123456|joe|male|etc ...
> 
> which I manipulate as follows:
> my ($id, $name, $gender, @rest) = split /\|/;
> $main_hash{$id} = {
>   id => $id,
>   name => $name.
>   gender => $gender,
>   rest => @rest,
>   new_value => ' ',
>  };
> 
> The secondary file looks like this:
> 0123456|this|etc ...
> 0123456|is|etc ...
> 0123456|a|etc ...
> 0123456|list|etc ...
> 0123456|of|etc ...
> 0123456|strings|etc ...
> 
> which I manipulate as follows:
> my ($id, $string, @rest) = split /\|/;
> $main_hash{$id}{new_value} .= $string unless $main_hash{$id}
> {new_value} =~ /$string/; #the strings can be duplicated but I only
> want one of each
> 
> So, should I double quote the $id when I use it as a hash key? That
> strikes me as idiosyncratic even for Perl.
> 
> CC.

Provide actual code that we can run that shows your issue and so we can
see what's happening.


------------------------------

Date: Tue, 08 Jun 2010 14:22:18 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: convert integer to string
Message-Id: <4c0e986a$0$89877$815e3792@news.qwest.net>

ccc31807 wrote:
> This is embarrassing!
> 
> I read an input file, split each row on the separators, pick out the
> unique key (which consists of seven digits), create a hash element on
> the key, and read the other values into an anonymous hash. This has
> worked for years without a hitch.
> 
> Yesterday, my user requested the app to print a calculated field,
> which is a list of names contained in a secondary file. I thought, "No
> problem, I'll just create a new element in my anonymous hash,
> concatenate each name unless the name already matched the string, and
> print it out." Didn't work, but the errors seemed to be random and
> arbitrary.
> 
> After a couple of hours, I used bdf's trick to print out the hash, and
> discovered much to my embarrassment that the keys weren't the same. In
> the main loop where I created the hash, the keys were as expected and
> consisted of seven characters which are all digits. HOWEVER, in the
> loop where I created the additional hash element, the keys with
> leading zeros did not match. Here is an example of the hash:

Most folks really don't need to know the backstory. Post your code,
your results, your expectations, and your questions.


------------------------------

Date: Tue, 8 Jun 2010 20:06:46 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: convert integer to string
Message-Id: <6vg2e7-0k42.ln1@osiris.mauzo.dyndns.org>


Quoth ccc31807 <cartercc@gmail.com>:
> On Jun 8, 2:26 pm, "Uri Guttman" <u...@StemSystems.com> wrote:
> > dunno what your code is doing (as you didn't post any) to make this
> > happen. are you doing an eval on some incoming data? that is a no-no! do
> > a proper parse and you can keep those keys as strings.
> 
> This is what I'm doing.
> 
> The main file looks like this:
> 0123456|joe|male|etc ...
> 
> which I manipulate as follows:
> my ($id, $name, $gender, @rest) = split /\|/;
> $main_hash{$id} = {

'%main_hash' is an appallingly bad name for a variable. Why is it there?
What's it got in it? (In this case, probably, something like '%people'
might be better.)

>   id => $id,
>   name => $name.
>   gender => $gender,
>   rest => @rest,

This line does not do what you think it does.

>   new_value => ' ',
>  };
> 
> The secondary file looks like this:
> 0123456|this|etc ...
> 0123456|is|etc ...
> 0123456|a|etc ...
> 0123456|list|etc ...
> 0123456|of|etc ...
> 0123456|strings|etc ...
> 
> which I manipulate as follows:
> my ($id, $string, @rest) = split /\|/;
> $main_hash{$id}{new_value} .= $string unless $main_hash{$id}
> {new_value} =~ /$string/; #the strings can be duplicated but I only

You want \Q\E here.

> want one of each
> 
> So, should I double quote the $id when I use it as a hash key? That
> strikes me as idiosyncratic even for Perl.

Works for me:

    ~% perl -E'
        my %main_hash;
        {
            my $line = "0123456|joe|male|etc";
            my ($id, $name, $gender) = split /\|/, $line;
            $main_hash{$id} = {
                id => $id,
                name => $name,
                gender => $gender,
                new_value => " ",
            };
        }
        for my $line ("0123456|this|etc", "0123456|is|etc") {
            my ($id, $string) = split /\|/, $line;
            $main_hash{$id}{new_value} .= $string
                unless $main_hash{$id}{new_value} =~ /\Q$string/;
        }
        for (keys %main_hash) {
            say "$_: $main_hash{$_}{new_value}";
        }
    '
    0123456: this

(There's only one entry because "this" =~ /is/.)

So you must be doing something else.

Ben



------------------------------

Date: Tue, 8 Jun 2010 12:27:48 -0700 (PDT)
From: ccc31807 <cartercc@gmail.com>
Subject: Re: convert integer to string
Message-Id: <b6f2e8d6-2514-4d9a-875e-37eba0b532b0@a30g2000yqn.googlegroups.com>

On Jun 8, 3:18=A0pm, "J. Gleixner" <glex_no-s...@qwest-spam-no.invalid>
wrote:
> Provide actual code that we can run that shows your issue and so we can
> see what's happening.

Here is the working code in my test script. Unfortunately, I can't
post the data files. Note that this code does some other things and
contains debugging statements.

open FAC, '<', "FAC_${term}.csv", or die "Cannot open FAC, $!";
chomp ($header =3D <FAC>);
while (<FAC>)
{
	next unless /\w/;
	chomp;
	my ($changed, $last, $first, $middle, $id2, $region, $contract,
$addy1, $addy2, $csz, $mail, $trs, @courses) =3D  parse_line(',', $bool,
$_);
	print "id2 is [$id2] and facid is [$facid]\n";
	if ($facid !~ /\?/) { next unless $id2 eq $facid; }
	$fac{$id2} =3D {
	id2 =3D> $id2,
	contract =3D> $contract,
	first =3D> $first,
	middle =3D> $middle,
	last =3D> $last,
	addy1 =3D> $addy1,
	addy2 =3D> $addy2,
	csz =3D> $csz,
	mail =3D> $mail,
	trs =3D> $trs,
	courses =3D> @courses,
	xlist =3D> '',
	}
}
close FAC;

open SEC, '<', "$sections_file", or die "Cannot open SEC, $!";
chomp ($header =3D <SEC>);
while (<SEC>)
{
	next unless /\w/;
	chomp;
	s/'/\\'/g;
   my ($last, $first, $middle, $id1, $filename, $crs_id, $site, $loc,
$glcode, $level, $count, $status, $section, $title, $hours, $xlist,
$total, $travel, $contract) =3D parse_line(',', 0, $_);
	next if $contract =3D~ /N/;
	$sec{$crs_id} =3D {
	crs_id =3D> $crs_id,
	filename =3D> $filename,
	id1 =3D> $id1,
	site =3D> $site,
	loc =3D> $loc,
	glcode =3D> $glcode,
	level =3D> $level,
	count =3D> $count,
	status =3D> $status,
	section =3D> $section,
	title =3D> $title,
	hours =3D> $hours,
	xlist =3D> $xlist,
	total =3D> $total,
	travel =3D> $travel,
	contract =3D> $contract,
	};
	$xlist{$id1} .=3D "$section " if $xlist =3D~ /\d/ and $xlist !~ /
$section/;
	$fac{$id1}{xlist} .=3D "$section " if $xlist =3D~ /\d/;
}
close SEC;





------------------------------

Date: Tue, 08 Jun 2010 15:28:18 -0400
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: convert integer to string
Message-Id: <87bpbl1fzh.fsf@quad.sysarch.com>

>>>>> "c" == ccc31807  <cartercc@gmail.com> writes:

  c> On Jun 8, 2:26 pm, "Uri Guttman" <u...@StemSystems.com> wrote:
  >> dunno what your code is doing (as you didn't post any) to make this
  >> happen. are you doing an eval on some incoming data? that is a no-no! do
  >> a proper parse and you can keep those keys as strings.

  c> This is what I'm doing.

  c> The main file looks like this:
  c> 0123456|joe|male|etc ...

  c> which I manipulate as follows:
  c> my ($id, $name, $gender, @rest) = split /\|/;
  c> $main_hash{$id} = {
  c>   id => $id,
  c>   name => $name.
  c>   gender => $gender,
  c>   rest => @rest,

that is wrong as it will put the whole array there. you need a ref to
that array or an anon ref.

  c>   new_value => ' ',
  c>  };

  c> The secondary file looks like this:
  c> 0123456|this|etc ...
  c> 0123456|is|etc ...
  c> 0123456|a|etc ...
  c> 0123456|list|etc ...
  c> 0123456|of|etc ...
  c> 0123456|strings|etc ...

  c> which I manipulate as follows:
  c> my ($id, $string, @rest) = split /\|/;
  c> $main_hash{$id}{new_value} .= $string unless $main_hash{$id}
  c> {new_value} =~ /$string/; #the strings can be duplicated but I only
  c> want one of each

  c> So, should I double quote the $id when I use it as a hash key? That
  c> strikes me as idiosyncratic even for Perl.

in that limited code i don't see where the keys would be interpreted as
literal numbers. there must be something else going on which is doing
that. perl won't lose leading zeroes in strings without doing some
number conversions. are you sure you never look at those kays as
numbers? like use == to check them or similar? since they seem to be
fixed size you can always use the string comparison ops safely.

uri

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


------------------------------

Date: Tue, 08 Jun 2010 15:31:28 -0400
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: convert integer to string
Message-Id: <877hm91fu7.fsf@quad.sysarch.com>

>>>>> "c" == ccc31807  <cartercc@gmail.com> writes:

  c> On Jun 8, 3:18 pm, "J. Gleixner" <glex_no-s...@qwest-spam-no.invalid>
  c> wrote:
  >> Provide actual code that we can run that shows your issue and so we can
  >> see what's happening.

  c> Here is the working code in my test script. Unfortunately, I can't
  c> post the data files. Note that this code does some other things and
  c> contains debugging statements.

  c> open FAC, '<', "FAC_${term}.csv", or die "Cannot open FAC, $!";
  c> chomp ($header = <FAC>);
  c> while (<FAC>)
  c> {
  c> 	next unless /\w/;
  c> 	chomp;
  c> 	my ($changed, $last, $first, $middle, $id2, $region, $contract,
  c> $addy1, $addy2, $csz, $mail, $trs, @courses) =  parse_line(',', $bool,
  c> $_);
  c> 	print "id2 is [$id2] and facid is [$facid]\n";
  c> 	if ($facid !~ /\?/) { next unless $id2 eq $facid; }
  c> 	$fac{$id2} = {
  c> 	id2 => $id2,
  c> 	contract => $contract,
  c> 	first => $first,
  c> 	middle => $middle,
  c> 	last => $last,
  c> 	addy1 => $addy1,
  c> 	addy2 => $addy2,
  c> 	csz => $csz,
  c> 	mail => $mail,
  c> 	trs => $trs,
  c> 	courses => @courses,

same bug as i pointed out in another post. you need a ref or anon array
there. that is very wrong. who knows what it is doing to your app?

  c> 	xlist => '',
  c> 	}

uri

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


------------------------------

Date: Tue, 8 Jun 2010 12:34:09 -0700 (PDT)
From: ccc31807 <cartercc@gmail.com>
Subject: Re: convert integer to string
Message-Id: <bf3d9af6-752a-4256-a340-54fe7ca31745@y11g2000yqm.googlegroups.com>

On Jun 8, 3:06=A0pm, Ben Morrow <b...@morrow.me.uk> wrote:
> '%main_hash' is an appallingly bad name for a variable. Why is it there?
> What's it got in it? (In this case, probably, something like '%people'
> might be better.)


Sorry. I posted the code where I populated the two hashes, named %fac
and %sec.

> You want \Q\E here.

Trying that now.

> So you must be doing something else.

Not intentionally.

CC.


------------------------------

Date: Tue, 8 Jun 2010 12:40:35 -0700 (PDT)
From: ccc31807 <cartercc@gmail.com>
Subject: Re: convert integer to string
Message-Id: <49ff8b65-37af-408d-9450-f4931960c108@j4g2000yqh.googlegroups.com>

On Jun 8, 3:31=A0pm, "Uri Guttman" <u...@StemSystems.com> wrote:
> =A0 c> =A0 =A0 =A0 =A0 courses =3D> @courses,
>
> same bug as i pointed out in another post. you need a ref or anon array
> there. that is very wrong. who knows what it is doing to your app?

@courses contains a list of numeric keys. If I:
print "Courses: [@courses]\n";
it will output something like this:
Courses: [23456 34567 45678]

This is NOT the problem here. What this does is make the hash element
$fac{$id}{courses} contain a scalar value like this:
'23456 34567 45678' This works perfectly and does exactly what I want
it to.

But thanks for pointing this out, CC.


------------------------------

Date: Tue, 8 Jun 2010 20:05:00 +0000 (UTC)
From: Willem <willem@turtle.stack.nl>
Subject: Re: convert integer to string
Message-Id: <slrni0t8jc.bpb.willem@turtle.stack.nl>

ccc31807 wrote:
) On Jun 8, 3:31?pm, "Uri Guttman" <u...@StemSystems.com> wrote:
)> ? c> ? ? ? ? courses => @courses,
)>
)> same bug as i pointed out in another post. you need a ref or anon array
)> there. that is very wrong. who knows what it is doing to your app?
)
) @courses contains a list of numeric keys. If I:
) print "Courses: [@courses]\n";
) it will output something like this:
) Courses: [23456 34567 45678]
)
) This is NOT the problem here. What this does is make the hash element
) $fac{$id}{courses} contain a scalar value like this:
) '23456 34567 45678' This works perfectly and does exactly what I want
) it to.

No, it doesn't.

It would if you spelled it like this:

   courses => "@courses",

But now, it would make:

  $fac{$id}{courses} contain '23456', and
  $fac{$id}{34567} contain '45678'.

And count yourself lucky that there are an odd number of elements,
otherwise the following keys and values would be swapped around.


SaSW, Willem
-- 
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT


------------------------------

Date: Tue, 08 Jun 2010 15:06:15 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: convert integer to string
Message-Id: <4c0ea2b8$0$87071$815e3792@news.qwest.net>

ccc31807 wrote:
> On Jun 8, 3:18 pm, "J. Gleixner" <glex_no-s...@qwest-spam-no.invalid>
> wrote:
>> Provide actual code that we can run that shows your issue and so we can
>> see what's happening.
> 
> Here is the working code in my test script. Unfortunately, I can't
> post the data files. Note that this code does some other things and
> contains debugging statements.

How can we run this?

Create a short example we can run that shows the issue. Just
populate an array or two with example data and use that
in place of your files.

Narrow your example code down to the issue, get rid of all the other
stuff and you might find the problem on your own.


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests. 

#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V11 Issue 2978
***************************************


home help back first fref pref prev next nref lref last post