and if the lat and lon are identical either group them on the same line OR, create a new file that would list (from the example above)
60.000 270.000 (2)
50.000 180.000 (1)
is there a way to do this? I've tried looking at the has function but i just cannot get it to work. Im a perl beginner.
Thanks!!!
perl_diver
06-04-2009, 05:18 PM
Post whatever code you have tried so far even if it does not work. That way people can at least get a sense about how much perl understanding you do have. Only posting your programming requirements and showing no effort makes it look like you just want someone to write your code for you, and this has the ring of school work to it.
donal0516
06-04-2009, 05:56 PM
The code i have been trying to play with is as follows:
#!/usr/bin/perl
my %hash;
open (MYFILE, "All_origins.txt");
while (<MYFILE>) {
my ($lat, $lon) = split(/\\s*/);
if (exists $hash{$lat$lon}) {
$hash{$lat$lon} .= ",$lat$lon";
next;
}
$hash{$latlon} = $latlon;
}
for (keys %hash) { print "$_ $hash{$_}\n"; }
exit;
close (MYFILE);
the ideal outcome would be the example from the previous post
i.e:
lat lon (#)
but right now i cant even get the lat lon groups to one line.
perl_diver
06-04-2009, 06:27 PM
You should use "strict" and "warnings" when writing perl scripts, especially for new perl programmers. But anyway..... the code you posted should be returning an error (or errors). What is the error you get?
donal0516
06-04-2009, 06:30 PM
no errors, just a list of random lats and lons with commas between
i changed it to this and got the output i listed above.
!/usr/bin/perl
my %hash;
open (MYFILE, "All_origins.txt");
while (<MYFILE>) {
my ($lat, $lon) = split(/\\s*/);
if (exists $hash{$lat}) {
$hash{$lat} .= ",$lon";
next;
}
$hash{$lat} = $lon;
}
for (keys %hash) { print "$_ $hash{$_}\n"; }
exit;
close (MYFILE);
perl_diver
06-04-2009, 07:05 PM
im sorry, it was putting out errors.
....
What is the error you get?
donal0516
06-04-2009, 07:09 PM
from the code that you said should be putting out an error, these are the errors produced
Scalar found where operator expected at ./counter.pl line 7, near "$lat$lon"
(Missing operator before $lon?)
Scalar found where operator expected at ./counter.pl line 8, near "$lat$lon"
(Missing operator before $lon?)
syntax error at ./counter.pl line 7, near "$lat$lon"
Execution of ./counter.pl aborted due to compilation errors.
perl_diver
06-04-2009, 07:18 PM
Perl is trying to help you but it can't always tell exaclty what the error is or even exactly where it is. But in this case its sort of staring you inthe face:
near "$lat$lon"
in fact that is exactly the error, you have no double-quotes around $let$lon so that perl can combine them into a string and use them as a hash key. So lets fix that and move on. I am going to add three very useful pragmas to your script: strict, warnings, diagnostics
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
my %hash;
open (MYFILE, "All_origins.txt");
while (<MYFILE>) {
my ($lat, $lon) = split(/\s*/);
if (exists $hash{"$lat$lon"}) {
$hash{"$lat$lon"} .= ",$lat$lon";
next;
}
$hash{"$latlon"} = "$latlon";
}
for (keys %hash) { print "$_ $hash{$_}\n"; }
exit;
close (MYFILE);
Run that and see what happens. Note that I fixed another error in your code, see if you can find it.
donal0516
06-04-2009, 07:25 PM
it appears that this code is neglecting the longitude
and i saw that you changed split(/\\s*/) to split(/\s*/)
perl_diver
06-04-2009, 08:10 PM
I can only assume you did not run the code I posted because you should have gotten another error. I was hoping you would pick up the error (the one I did not correct). You did find the one I corrected: \\s*. So if you did not run the code I posted, what did you run?
perl_diver
06-04-2009, 08:18 PM
anyway... here is the problem with the last code I posted. THsi line taken from your original code:
$hash{"$latlon"} = "$latlon";
There is no $ symbol before 'lon', should be:
$hash{"$lat$lon"} = "$lat$lon";
Otherwise you will get an error about $latlon not being packaged. Also, while I did correct \\s* in split, your real split pattern should be \s+ whcih means one or more spaces instead of zero or more spaces. But all this is really academic, which was the point since you are learning perl. If all you wanted to do was count duplicate lines in the file your code is too verbose, this will siffice:
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
my %hash;
open (MYFILE, "All_origins.txt") or die "$!";
while (<MYFILE>) {
chomp;
$hash{$_}++;
}
close (MYFILE);
for (sort {$hash{$b} <=> $hash{$b} } keys %hash) {
print "$_ ($hash{$_})\n";
}
exit;
The splitting of the line into two tokens is not necessary unless there is a variable number of spaces between the lat and the lon. And of course your code wasn't even counting anything but I assume you were going to get to that after getting your initial code to run.
Nedals
06-04-2009, 08:27 PM
the ideal outcome would be the example from the previous post. i.e: lat lon (#)
Seem that you are making this much more difficult than it need be.
my %hash;
#open (MYFILE, "All_origins.txt");
while (<DATA>) {
chomp;
if (exists $hash{$_}) { $hash{$_}++ } else { $hash{$_} = 1 }
}
for (keys %hash) { print "$_ \($hash{$_}\)\n"; }
#close (MYFILE);
exit;
perl diver,
Great minds think alike. :) You posted while I was writing.
donal0516
06-04-2009, 08:28 PM
this line
$hash{"$latlon"} = "$latlon";
was changed to
$hash{"$lat$lon"} = "$lat$lon";
i dont think that $lat$lon is going to get what i want, i want to match the lat lon string to any other lat lon string that is identical but the lat lon strings are
50.000 240.000
so there is a space between the two. $lat$lon doesnt do that. When i run the code now, i recieve no errors. but the output puts out something like
so it appears that it is correctly identifying the matching lats but not lons and not outputting the correct thing.
By the way this is not a hw assignment. This is for my graduate research, i normally work in IDL but when i need to do some regular expressions or text manipulation i try to use perl or shell scripts. But i havent learned much perl.
Here is the code as i am running it now
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
my %hash;
open (MYFILE, "All_origins.txt");
while (<MYFILE>) {
my ($lat, $lon) = split(/\s*/);
if (exists $hash{"$lat$lon"}) {
$hash{"$lat$lon"} .= ",$lat$lon";
next;
}
$hash{"$lat$lon"} = "$lat$lon";
}
for (keys %hash) { print "$_ $hash{$_}\n"; }
exit;
close (MYFILE);
donal0516
06-04-2009, 08:33 PM
thank you both for the help it works properly now, i posted as you all were posting so disregard my last post. thanks again!
perl_diver
06-04-2009, 10:27 PM
Like I said, /\s*/ is not the correct split pattern, you want to use /\s+/. Otherwise /\s*/ will split the lines into the individual characters and your code is returning only the first two matches from the split, so a line like this:
50.000 240.000
will return this:
$lat = 5
$lon = 0
perl_diver
06-04-2009, 10:28 PM
thank you both for the help it works properly now, i posted as you all were posting so disregard my last post. thanks again!
Cool. You're welcome. :)
webdeveloper.com
Copyright Internet.com Inc., All Rights Reserved.