hash help....

J

jim.goodman

please no flames... i am trying to post a thoughtful question with all
the right info so that we don't have to do this twice... :eek:)!

i want to read data from a file.... here is a sample of the data.....

1 St. Helena Napa Valley
2 Santa Lucia Highlands Monterey Bay Area
3 Oakville Napa Valley
4 Howell Mountain Napa Valley
7 Russian River Valley Sonoma
8 Santa Barbara County South Central Coast
11 Oakville Napa Valley
13 Russian River Valley Sonoma
15 Alexander Valley Sonoma
16 Ojai Valley South Central Coast
20 Valpolicella Veneto
22 Chianti Tuscany
28 Asti Piedmont
33 Chianti Tuscany
34 Shenandoah Valley of California Sierra Foothills
36 Oakville Napa Valley
37 Green Valley Central Valley
38 Yamhill Valley Willamette Valley
42 Santa Barbara County South Central Coast
45 Rutherford Napa Valley
49 St. Emilion Bordeaux
50 St. Emilion Bordeaux
51 Haut-Medoc Bordeaux
52 St. Emilion Bordeaux
53 St. Emilion Bordeaux
54 St. Emilion Bordeaux
55 Haut-Medoc Bordeaux
56 Carneros Sonoma
57 Medoc Bordeaux


each column is serated by a tab with the \n at teh end of the line....
what i want is for column tow (subregion) to be teh key and colunm 3
(region) to be the data for the key.... i have to update which
subregions are in which regions so i only want each subregion once
(using hash's and keys to keep it unique, see guys, i learned from my
last question.... <again a smile>). so later i have another script that
will update "st. emilion" in the Db as being in "Bordeaux", relating
them....

here is the code i have been working with... please understand that it
isn't complete/doesn't work. the closest i got to it working was so
many "tiral and errors" ago (mostly errors) that i don't remeber what i
did to get it to its closest point.... and therefore giving me
output.... but i think you can understand exactly what i am looking
for.....

thanks a million for any help.

-jim

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

my $org_stuff = '/Users/goodman/Desktop/wine/test.txt'; #data file
open ORG_STUFF, $org_stuff or die "Can't open $org_stuff : $!"; # open
data or error
my %org; # declare hash

while( <ORG_STUFF> ) {
chomp;
my $org_data = ( split /\t/ )[ -2 ];
$org{ $org_data } = (); # don't care about values
}

close ORG_STUFF;
for my $org_data ( sort keys %org ) {
print "$org_data\n";
}
__END__
 
R

Robert Gamble

please no flames... i am trying to post a thoughtful question with all
the right info so that we don't have to do this twice... :eek:)!

i want to read data from a file.... here is a sample of the data.....

1 St. Helena Napa Valley
2 Santa Lucia Highlands Monterey Bay Area
3 Oakville Napa Valley

[snip 50 additional lines]
each column is serated by a tab with the \n at teh end of the line....
what i want is for column tow (subregion) to be teh key and colunm 3
(region) to be the data for the key.... i have to update which
subregions are in which regions so i only want each subregion once
(using hash's and keys to keep it unique, see guys, i learned from my
last question.... <again a smile>). so later i have another script that
will update "st. emilion" in the Db as being in "Bordeaux", relating
them....

here is the code i have been working with... please understand that it
isn't complete/doesn't work. the closest i got to it working was so
many "tiral and errors" ago (mostly errors) that i don't remeber what i
did to get it to its closest point.... and therefore giving me
output.... but i think you can understand exactly what i am looking
for.....

thanks a million for any help.

-jim

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

my $org_stuff = '/Users/goodman/Desktop/wine/test.txt'; #data file
open ORG_STUFF, $org_stuff or die "Can't open $org_stuff : $!"; # open
data or error
my %org; # declare hash

while( <ORG_STUFF> ) {
chomp;
my $org_data = ( split /\t/ )[ -2 ];

Are you sure the file actually contains tabs? If it doesn't then split
won't return more than one field and $org_data will remain
uninitialized. Try something like this:

my $fields = split /\t/;
print "Split into $fields fields\n";
if ($fields == 3) {
$org{$_[-2]} = 1;
}
$org{ $org_data } = (); # don't care about values
}

close ORG_STUFF;
for my $org_data ( sort keys %org ) {
print "$org_data\n";
}
__END__

If you are still having problems, be sure to include exactly what is
happening and how this differs from your expectations.

Robert Gamble
 
B

Brian McCauley

Robert said:
my $fields = split /\t/;
if ($fields == 3) {
$org{$_[-2]} = 1;
}

Please don't advise people to use split in a scalar context (or indeed
any other deprecated feature).

Please do advise people to compile with wanings enabled.
 
P

Paul Lalli

please no flames...

The best way to avoid people "flaming" you is not to ask them not to
flame you... it's to give them *no reason* to flame you.
i am trying to post a thoughtful question with all
the right info so that we don't have to do this twice... :eek:)!

I understand the humor value you attempted in this statement, but your
phrasing urks me a bit. "We" do not have to do this twice. "We" do
not *have* to do it even once. Anyone who decides to help you does so
of his/her own free will and generosity, nothing more.
i want to read data from a file.... here is a sample of the data.....

1 St. Helena Napa Valley
2 Santa Lucia Highlands Monterey Bay Area
3 Oakville Napa Valley

each column is serated by a tab with the \n at teh end of the line....
what i want is for column tow (subregion) to be teh key and colunm 3

Please at least run your post through a spell checker (better, of
course, would be to actually proofread your post before hitting
"Send"). The above two lines contain enough spelling errors so as to
make the post difficult to read on a single pass.
(region) to be the data for the key.... i have to update which
subregions are in which regions so i only want each subregion once
(using hash's and keys to keep it unique, see guys, i learned from my
last question.... <again a smile>). so later i have another script that
will update "st. emilion" in the Db as being in "Bordeaux", relating
them....

Okay so far....
here is the code i have been working with... please understand that it
isn't complete/doesn't work.

"doesn't work" is the worst of all possible error descriptions. *HOW*
does it "not work"? In what way to the results differ from your
expectations? Bad output? No output? Compiler error? Infinite loop?
Computer bursts into flames?

Making it needlessly difficult to help you is a sure way to get less
help and more flames, polite requests to the contrary notwithstanding.
the closest i got to it working was so
many "tiral and errors" ago (mostly errors) that i don't remeber what i
did to get it to its closest point.... and therefore giving me
output.... but i think you can understand exactly what i am looking
for.....

Yes, but we have *no idea* from your description what is going wrong
right now. Why would you fail to include that information?
thanks a million for any help.

You can best thank everyone by reading the Posting Guidelines for this
group, and then following them.
#!/usr/bin/perl
use strict;
use warnings;
GOOD!

my $org_stuff = '/Users/goodman/Desktop/wine/test.txt'; #data file
open ORG_STUFF, $org_stuff or die "Can't open $org_stuff : $!"; # open

Please use lexical filehandles, not global barewords.
Please get into the habbit of using the three-argument form of open(),
even if it makes no difference in this particular example
GOOD that you are checking open() for success!
data or error
my %org; # declare hash

while( <ORG_STUFF> ) {
chomp;
my $org_data = ( split /\t/ )[ -2 ];
$org{ $org_data } = (); # don't care about values

In general, I recommend setting the value to be 1, rather than
undefined as you did above. It might not make a difference in your code
now, but it can if you ever do make use of the values.
}

close ORG_STUFF;
for my $org_data ( sort keys %org ) {
print "$org_data\n";
}
__END__

Okay. So again, WHAT is the problem? What is this code doing or not
doing that you want to change? Until you tell us that, it's rather
unlikely anyone will be able to conclusively help you.

Paul Lalli

P.S. If you consider any of the above a "flame", you need to go back,
re-read everything I said, and critically evaluate what I said, why I
said it, and how your post would be perceived before and after the
changes I suggested.
 
P

Paul Lalli

Robert said:
(e-mail address removed) wrote:
while( <ORG_STUFF> ) {
chomp;
my $org_data = ( split /\t/ )[ -2 ];

Are you sure the file actually contains tabs? If it doesn't then split
won't return more than one field and $org_data will remain
uninitialized. Try something like this:

my $fields = split /\t/;
print "Split into $fields fields\n";
if ($fields == 3) {
$org{$_[-2]} = 1;
}

No, do *not* try anything like that. That "feature" of split() is
depreciated and dangerous. Never split() in a scalar context.

read `perldoc -f split` for more information

my @fields = split /\t/;
print "Split into " . @fields . " fields\n";
if (@fields == 3) {
$org{$fields[-2]} = 1;
} else {
print "Invalid format of line:\n$_\n";
}

Paul Lalli
 
R

Robert Gamble

Brian said:
Robert said:
my $fields = split /\t/;
if ($fields == 3) {
$org{$_[-2]} = 1;
}

Please don't advise people to use split in a scalar context (or indeed
any other deprecated feature).

Sorry, is this better?:

my @fields = split /\t/;
my $num_fields = scalar(@fields);
print "Split into $num_fields fields\n";
if ($num_fields == 3) {
$org{$fields[-2]} = 1;
}
Please do advise people to compile with wanings enabled.

The OP did have warnings enabled in his example, he obviously did not
need to be advised to do so here.

Robert Gamble
 
A

A. Sinan Unur

please no flames... i am trying to post a thoughtful question

This is not a flame.

....
did to get it to its closest point.... and therefore giving me
output.... but i think you can understand exactly what i am looking
for.....

No, I really cannot figure out exactly what you are looking for. Why not
state the question properly, without requiring your readers to guess the
question?

You should include any data in the __DATA__ section of your script to
make it easy for us to run code. This is explained in the posting
guidelines.

Is this what you are trying to do?

#!/usr/bin/perl

use strict;
use warnings;

my %subregions;

while ( <DATA> ) {
chomp;
last unless length;
my (undef, $subregion, $region) = split /\t/;
$subregions{$subregion} = $region;
}

print "$_ => $subregions{$_}\n" for sort {
$subregions{$a} cmp $subregions{$b}
} keys %subregions;

__DATA__
1 St. Helena Napa Valley
2 Santa Lucia Highlands Monterey Bay Area
3 Oakville Napa Valley
4 Howell Mountain Napa Valley
7 Russian River Valley Sonoma
8 Santa Barbara County South Central Coast
11 Oakville Napa Valley
13 Russian River Valley Sonoma
15 Alexander Valley Sonoma
16 Ojai Valley South Central Coast
20 Valpolicella Veneto
22 Chianti Tuscany
28 Asti Piedmont
33 Chianti Tuscany
34 Shenandoah Valley of California Sierra Foothills
36 Oakville Napa Valley
37 Green Valley Central Valley
38 Yamhill Valley Willamette Valley
42 Santa Barbara County South Central Coast
45 Rutherford Napa Valley
49 St. Emilion Bordeaux
50 St. Emilion Bordeaux
51 Haut-Medoc Bordeaux
52 St. Emilion Bordeaux
53 St. Emilion Bordeaux
54 St. Emilion Bordeaux
55 Haut-Medoc Bordeaux
56 Carneros Sonoma
57 Medoc Bordeaux



--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
J

jim.goodman

ok, 'cause maybe i didn't explain myself cleearly enough....

i have an input file, see example... i have code, see bad example of
non working code! what i want to do is read the input file and get
each subregion once with its corresponding data (e.g. St. Emilion
Bordeaux).

only once did i get output and it was only one column... i can get
either column and make 'em unique (keys in the hash), but i can't get a
key and data....

what i don't know is the syntax to grab data from the input and put it
in a hash, and i don't know the sytax to print the hash key and its
data....

i don't think i could get any more detailed than that... if i could, i
think i would be able to answer my own question.... :eek:)
 
J

jim.goodman

i don't know if this is what i am trying to do... when i run it i get
this output.... :eek:)

Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 1.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 2.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 3.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 4.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 5.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 6.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 7.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 8.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 9.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 10.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 11.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 12.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 13.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 14.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 15.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 16.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 17.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 18.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 19.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 20.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 21.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 22.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 23.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 24.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 25.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 26.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 27.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 28.
Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 29.
Use of uninitialized value in concatenation (.) or string at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 16, <DATA> line 29.
=>
 
A

A. Sinan Unur

i don't know if this
What?

is what i am trying to do... when i run it

When you run what?
i get this output.... :eek:)

Use of uninitialized value in hash element at
/Users/goodman/Desktop/Wine/Scripts/test.pl line 12, <DATA> line 1.

If you ran the exact code I posted including the __DATA__ section, that
should not happen. On the other hand, if the tabs got converted to
spaces, then the split will not work.

By the way, I won't be seeing your posts again.

Sinan

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
 
J

John W. Krahn

[snip data]

each column is serated by a tab with the \n at teh end of the line....
what i want is for column tow (subregion) to be teh key and colunm 3
(region) to be the data for the key.... i have to update which
subregions are in which regions so i only want each subregion once
(using hash's and keys to keep it unique, see guys, i learned from my
last question.... <again a smile>). so later i have another script that
will update "st. emilion" in the Db as being in "Bordeaux", relating
them....

Change:

while( <ORG_STUFF> ) {
chomp;
my $org_data = ( split /\t/ )[ -2 ];
$org{ $org_data } = (); # don't care about values
}

To:

while( <ORG_STUFF> ) {
chomp;
my ( $org_data, $region ) = ( split /\t/ )[ -2, -1 ];
$org{ $org_data } = $region;
}




John
 
B

Brian McCauley

Robert said:
Brian said:
Robert said:
my $fields = split /\t/;
if ($fields == 3) {
$org{$_[-2]} = 1;
}

Please don't advise people to use split in a scalar context (or indeed
any other deprecated feature).

Sorry, is this better?:

my @fields = split /\t/;
my $num_fields = scalar(@fields);
print "Split into $num_fields fields\n";
if ($num_fields == 3) {
$org{$fields[-2]} = 1;
}

Better. But is still seems unduely complicated. One of my pet hates is
code the purpose of which is to conceal problems. If you are going to
consider at all what should happen when program gets unexpected input
then you should do something about it and not silently ignore it.

Note: I am _not_ saying that all code always needs to check that its
input is valid, but if you _do_ check you should do something more
helpful than silently skip the invalid input.
The OP did have warnings enabled in his example, he obviously did not
need to be advised to do so here.

In which case, had the split returned a single value, the OP would have
got a warning. So that wasn't the problem.
 
R

Robert Gamble

Brian said:
Robert said:
Brian said:
Robert Gamble wrote:
my $fields = split /\t/;

if ($fields == 3) {
$org{$_[-2]} = 1;
}

Please don't advise people to use split in a scalar context (or indeed
any other deprecated feature).

Sorry, is this better?:

my @fields = split /\t/;
my $num_fields = scalar(@fields);
print "Split into $num_fields fields\n";
if ($num_fields == 3) {
$org{$fields[-2]} = 1;
}

Better. But is still seems unduely complicated. One of my pet hates is
code the purpose of which is to conceal problems.

What is unduely complicated about it? It seems pretty straight-forward
to me, please enlighten me. Your charge of attempting to conceal
problems is uncalled for.
If you are going to
consider at all what should happen when program gets unexpected input
then you should do something about it and not silently ignore it.

The purpose of the example is to determine if the correct number of
fields is being read. The example prints the number of fields, I
wouldn't call that being silent. If the number of fields reported
isn't correct the user can clearly see this. I didn't see the need of
printing out a special warning if the result isn't 3, the intent of the
example is clear and doing so would be unduely complicated.
Note: I am _not_ saying that all code always needs to check that its
input is valid, but if you _do_ check you should do something more
helpful than silently skip the invalid input.

There is absolutely no need for that in this example.
In which case, had the split returned a single value, the OP would have
got a warning. So that wasn't the problem.

Were you standing behind the OP when he ran this example? If not, how
do you know that no warnings were produced?

Robert Gamble
 
B

Brian McCauley

Robert said:
Brian said:
Robert said:
Brian McCauley wrote:
Robert Gamble wrote:
my $fields = split /\t/;

if ($fields == 3) {
$org{$_[-2]} = 1;
}

Please don't advise people to use split in a scalar context (or indeed
any other deprecated feature).

Sorry, is this better?:

my @fields = split /\t/;
my $num_fields = scalar(@fields);
print "Split into $num_fields fields\n";
if ($num_fields == 3) {
$org{$fields[-2]} = 1;
}

Better. But is still seems unduely complicated. One of my pet hates is
code the purpose of which is to conceal problems.

What is unduely complicated about it?

The if().
It seems pretty straight-forward
to me, please enlighten me. Your charge of attempting to conceal
problems is uncalled for.

I was referring to the if() in the above code. I was assuming that the
print() was a diagnostic and would be removed in then final code. The
if(), however, would be likely to get left in the final code and all it
does is says "does the input have the required number of columns, if
not then silently ignore it".
The purpose of the example is to determine if the correct number of
fields is being read. The example prints the number of fields, I
wouldn't call that being silent. If the number of fields reported
isn't correct the user can clearly see this. I didn't see the need of
printing out a special warning if the result isn't 3, the intent of the
example is clear and doing so would be unduely complicated.

You are mixing up development phase and production phase. In the
production phase the print() would be removed. If the if() was left
then the user would get no warning about invalid input. If you removed
the if() then invalid input with <2 columns would cause warnings.
Invalid input with >3 columns would silently be accepted.
There is absolutely no need for that in this example.

So you now agree that your code was unduely complicated. The if() in
your code is doing something that, in your own words, "there is
absolutely no need for".
Were you standing behind the OP when he ran this example? If not, how
do you know that no warnings were produced?

He didn't report that it did. He seemed sane enough that I took this
too mean that there weren't. If you thought perhaps he did get
warnings and hadn't mentioned them then it would be simpler to say "did
you get any warnings?" rather than suggest he add a diagnostic print.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,112
Latest member
BrentonMcc
Top