For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > November 2006 > Stuff a hash from two source files









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Stuff a hash from two source files
banker123

2006-11-21, 6:57 pm

I am trying to populate a hash from two source files. The code below
only populates the last elements from the source files. I woul like to
populate the hash with all the elements foiund in the source files.

!/usr/bin/perl
use strict;
use warnings;

while ( <data1> ) {
($box,$priority)=split;
}
while ( <data2> ) {
($lockbox,$group)=split;
}

my %data = ( $box => { group => "$group" , priority => "$priority"} );

data1
712480 3
712481 2
712482 1

data2
712480 firstgreen
712481 firstblack
712482 firstblue

Paul Lalli

2006-11-21, 6:57 pm

banker123 wrote:
> I am trying to populate a hash from two source files. The code below
> only populates the last elements from the source files.


That's all you told it to do.

> I woul like to
> populate the hash with all the elements foiund in the source files.
>
> !/usr/bin/perl
> use strict;


Please don't lie to us just to avoid us yelling about not using strict
and warnings. Your code does not compile with strict enabled. Post
your real code.

> use warnings;
>
> while ( <data1> ) {


There is no such filehandle.

> ($box,$priority)=split;


No such variables were ever declared.

> }
> while ( <data2> ) {


There is no such filehandle.

> ($lockbox,$group)=split;


No such variables were ever declared.

> }
>
> my %data = ( $box => { group => "$group" , priority => "$priority"} );


perldoc -q quoting


In addition to all the compilation problems, your central problem is
that your algorithm makes no sense. You read in all lines from one
file, overwriting the contents of two variables each time through.
Then you read in all lines from another file, overwriting the contents
of two other variables each time through. Then you finally declare a
hash, and populate it with exactly one key/value pair, that uses three
of those variables - which of course have only the last values read in
for each.

Step one: *actually* enable strict and warnings.
Step two: declare your hash before opening any files.
Step three: figure out what you actually want to make this hash look
like. You've given no information of any kind that would tell us how
the lines in one file relate to the lines in the other file, so there's
no way of knowing how you want the structure to end up.

Paul Lalli

John Bokma

2006-11-21, 6:57 pm

"banker123" <bradbrockman@yahoo.com> wrote:

> I am trying to populate a hash from two source files. The code below
> only populates the last elements from the source files. I woul like

to
> populate the hash with all the elements foiund in the source files.
>
> !/usr/bin/perl
> use strict;
> use warnings;
>
> while ( <data1> ) {
> ($box,$priority)=split;
> }
> while ( <data2> ) {
> ($lockbox,$group)=split;
> }
>
> my %data = ( $box => { group => "$group" , priority => "$priority"} );


Post real code, not something you typed in, untested:

"use" not allowed in expression at C:\Documents and Settings\John\My
Documents\use.pl line 2, at end of line
syntax error at C:\Documents and Settings\John\My Documents\use.pl line
2, near "perl
use strict"
BEGIN not safe after errors--compilation aborted at C:\Documents and
Settings\John\My Documents\use.pl line 3.

Even if I consider the first line a copy mistake, and add the # I get:


Global symbol "$box" requires explicit package name at C:\Documents and
Settings\John\My Documents\use.pl line 6.
Global symbol "$priority" requires explicit package name at C:\Documents
and Settings\John\My Documents\use.pl line 6.
Bareword "data1" not allowed while "strict subs" in use at C:\Documents
and Settings\John\My Documents\use.pl line 8.
Global symbol "$lockbox" requires explicit package name at C:\Documents
and Settings\John\My Documents\use.pl line 9.
Global symbol "$group" requires explicit package name at C:\Documents
and Settings\John\My Documents\use.pl line 9.
Bareword "data2" not allowed while "strict subs" in use at C:\Documents
and Settings\John\My Documents\use.pl line 12.
Global symbol "$box" requires explicit package name at C:\Documents and
Settings\John\My Documents\use.pl line 12.
Global symbol "$group" requires explicit package name at C:\Documents
and Settings\John\My Documents\use.pl line 12.
Global symbol "$priority" requires explicit package name at C:\Documents
and Settings\John\My Documents\use.pl line 12.
Bareword "group" not allowed while "strict subs" in use at C:\Documents
and Settings\John\My Documents\use.pl line 12.
Bareword "priority" not allowed while "strict subs" in use at C:
\Documents and Settings\John\My Documents\use.pl line 12
..


Maye you thought that just manually adding use strict and use warnings
made things right?

Post real code.

Finally, how can you expect to get each item if you don't store the data
while you loop over your data?

--
John Experienced Perl programmer: http://castleamber.com/

Perl help, tutorials, and examples: http://johnbokma.com/perl/
John Bokma

2006-11-21, 6:57 pm

John Bokma <john@castleamber.com> wrote:

> Maye


Aye, those damn pirates now stole the key next to the v :-(

--
John Experienced Perl programmer: http://castleamber.com/

Perl help, tutorials, and examples: http://johnbokma.com/perl/
banker123

2006-11-21, 6:57 pm

My actual code.

#!/usr/bin/perl
#use strict;
#use warnings;

open ('info', 'C:/sort.txt') or die "Cannot open file: $!";
open ('box', 'C:/box.txt') or die "Cannot open file: $!";

my %data;
while ( <info> ) {
($box,$prior)=split;
}
while ( <box> ) {
($lockbox,$group)=split;
}
$data {$box} = { group => $group , prior => $prior} ;

for my $table ( sort by_type keys %data ) {
my @data = ($table, @{ $data{$table} } {qw/group prior/});
print "@data\n";
}

sub by_type {
$data{$a}{prior} <=> $data{$b}{prior};
}

Paul Lalli

2006-11-21, 6:57 pm

banker123 wrote:
> My actual code.
>
> #!/usr/bin/perl
> #use strict;
> #use warnings;


This is plugging your fingers in your ears and shouting "LA LA LA I
CAN'T HEAR YOU!!!!". If you don't want Perl to tell you what you're
doing wrong, why are you bothering to ask us what you did wrong?

>
> open ('info', 'C:/sort.txt') or die "Cannot open file: $!";
> open ('box', 'C:/box.txt') or die "Cannot open file: $!";
>
> my %data;
> while ( <info> ) {
> ($box,$prior)=split;
> }
> while ( <box> ) {
> ($lockbox,$group)=split;
> }
> $data {$box} = { group => $group , prior => $prior} ;


So you didn't bother to listen to the suggestions that either John or I
gave you? Why bother asking us?

Good bye.
Paul Lalli

banker123

2006-11-21, 6:57 pm

> This is plugging your fingers in your ears and shouting "LA LA LA I
> CAN'T HEAR YOU!!!!". If you don't want Perl to tell you what you're
> doing wrong, why are you bothering to ask us what you did wrong?


Same result, few changes made after turning on strict and warnings as
suggested, and declaring the hash.

#!/usr/bin/perl
use strict;
use warnings;

open ('info', 'C:/sort.txt') or die "Cannot open file: $!";
open ('box', 'C:/box.txt') or die "Cannot open file: $!";

my %data;
while ( <info> ) {
my ($box,$prior)=split;

while ( <box> ) {
my ($lockbox,$group)=split;
$data {$box} = { group => $group , prior => $prior} ;
}
}

for my $table ( sort by_type keys %data ) {
my @data = ($table, @{ $data{$table} } {qw/group prior/});
print "@data\n";
}

sub by_type {
$data{$a}{prior} <=> $data{$b}{prior};
}

John Bokma

2006-11-21, 6:57 pm

"banker123" <bradbrockman@yahoo.com> wrote:

>
> Same result, few changes made after turning on strict and warnings as
> suggested, and declaring the hash.
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> open ('info', 'C:/sort.txt') or die "Cannot open file: $!";
> open ('box', 'C:/box.txt') or die "Cannot open file: $!";
>
> my %data;
> while ( <info> ) {
> my ($box,$prior)=split;
>
> while ( <box> ) {
> my ($lockbox,$group)=split;
> $data {$box} = { group => $group , prior => $prior} ;
> }
> }
>
> for my $table ( sort by_type keys %data ) {
> my @data = ($table, @{ $data{$table} } {qw/group prior/});
> print "@data\n";
> }
>
> sub by_type {
> $data{$a}{prior} <=> $data{$b}{prior};
> }



Cannot open file: No such file or directory at C:\Documents and Settings
\John\My Documents\foo.pl line 5.

perldoc -f open

Also, if you report an error, it might be useful to provide some
additional info, e.g.

my $filename = ....
.... or die "Can't open '$filename' for reading: $!";

^ errmesg
^ ^
what file action that failed

You got one out of 3.

(And if your files are really directly on drive C: ... aargh)


--
John Experienced Perl programmer: http://castleamber.com/

Perl help, tutorials, and examples: http://johnbokma.com/perl/
DJ Stunks

2006-11-21, 6:57 pm

banker123 wrote:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> open ('info', 'C:/sort.txt') or die "Cannot open file: $!";
> open ('box', 'C:/box.txt') or die "Cannot open file: $!";
>
> my %data;
> while ( <info> ) {
> my ($box,$prior)=split;
>
> while ( <box> ) {
> my ($lockbox,$group)=split;
> $data {$box} = { group => $group , prior => $prior} ;
> }
> }
>
> for my $table ( sort by_type keys %data ) {
> my @data = ($table, @{ $data{$table} } {qw/group prior/});
> print "@data\n";
> }
>
> sub by_type {
> $data{$a}{prior} <=> $data{$b}{prior};
> }


okay, now we're getting somewhere. code that compiles.

what you're doing above is going through every line of <box> for each
line of <info>. what I think you want to be doing is building the
'prior' key value pair as you go through the info file, then adding the
'group' key value pair to the hash for each box as you go through each
line of <box>.

something like this: (untested)

my %data;
while (<info> ) {
($box, $prior) = split;
$data{$box}{prior} = $prior;
}

while (<box> ) {
($box,$group) = split;
$data{$box}{group} = $group;
}

-jp

banker123

2006-11-21, 6:57 pm


DJ Stunks wrote:
> what you're doing above is going through every line of <box> for each
> line of <info>. what I think you want to be doing is building the
> 'prior' key value pair as you go through the info file, then adding the
> 'group' key value pair to the hash for each box as you go through each
> line of <box>.


Exactly!

> something like this: (untested)
>
> my %data;
> while (<info> ) {
> ($box, $prior) = split;
> $data{$box}{prior} = $prior;
> }
>
> while (<box> ) {
> ($box,$group) = split;
> $data{$box}{group} = $group;


Worked great, thanks!

Alan_C

2006-11-23, 3:56 am

"DJ Stunks" <DJStunks@gmail.com> writes:
> banker123 wrote:
<snip>[color=darkred]
> okay, now we're getting somewhere. code that compiles.

<snip>
> something like this: (untested)

<snip>
> ($box,$group) = split;
> $data{$box}{group} = $group;


al@AB60R:~$ tst_hash
712482 firstblue 1
712481 firstblack 2
712480 firstgreen 3

I see that this removes dupes, appends each single digit to each appropriate
line, sorted by the single digits. Do I have that right? (my output is above,
there)

I understand the part that I did in the below code. But I do not understand
each code line below that I've appended an #?? onto.

I s any sort of help that would in turn help me to understand these lines
that I do not grasp (explanations, terminologies of what for me to study,
perldocs, etc.) Thanks.


#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

# open ('INFO', 'C:/sort.txt') or die "Cannot open file: $!";
# open ('BOX', 'C:/box.txt') or die "Cannot open file: $!";

############ important notice #################
# where <INFO> be/is the first 3 lines of DATA
# and <BOX> be/is the last 3 lines of DATA
my %data;
my @box_items; # gather_for_BOX
my ($box, $prior, $group);
# while (<INFO> ) {
my $i = 0; # gather_for_BOX
while (<DATA> ) {
########## gather_for_BOX ############
$i++;
if ($i > 3) {
push @box_items, $_;
next;
}
########### end of gather_for_BOX ###########
($box, $prior) = split;
$data{$box}{prior} = $prior; #??
}
# print @box_items;

# while (<BOX> ) {
foreach ( @box_items ) {
($box,$group) = split;
$data{$box}{group} = $group; #??
}

for my $table ( sort by_type( keys %data )) {
my @data = ($table, @{ $data{$table} } {qw/group prior/}); #??
print "@data\n";
}

sub by_type {
$data{$a}{prior} <=> $data{$b}{prior}; #??
}
__DATA__
712480 3
712481 2
712482 1
712480 firstgreen
712481 firstblack
712482 firstblue

--
Alan.
boyd

2006-11-23, 7:58 am

In article <87hcwq8xx5.fsf@AB60R.localdomain>,
Alan_C <mtbr0228AT@sbcglobalDOT.net> wrote:


> $data{$box}{prior} = $prior; #??

This is called a hash of hashes (HOH). The perldoc's perlreftut and
perldsc are good. This line could also be written as
$data{$box}->{prior} = ...
> }
> # print @box_items;
>
> # while (<BOX> ) {
> foreach ( @box_items ) {
> ($box,$group) = split;
> $data{$box}{group} = $group; #??

Same comment as above
> }
>
> for my $table ( sort by_type( keys %data )) {
> my @data = ($table, @{ $data{$table} } {qw/group prior/}); #??

This is called a hash slice. It is equivalent to
my @data = ($table, $data{$table}->{group}, $data{$table}->{prior} )

> print "@data\n";
> }
>
> sub by_type {
> $data{$a}{prior} <=> $data{$b}{prior}; #??

Same comment as first one
> }
> __DATA__
> 712480 3
> 712481 2
> 712482 1
> 712480 firstgreen
> 712481 firstblack
> 712482 firstblue


Hope that helps.

Boyd
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com