Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Nested foreach loops

by NetWallah (Canon)
on Sep 08, 2016 at 02:42 UTC ( [id://1171354]=note: print w/replies, xml ) Need Help??


in reply to Nested foreach loops

Perhaps something like this (You need to provide the 'distance' sub):
use strict; use warnings; my (@gsm_site, @umts_site); while (<DATA>) { my ($name1,$lon1,$lat1, $name2,$lon2,$lat2) = split /[\s"]*,["\s]*/ +, $_; next unless $lat1 and $lon1; # Avoid title lines push @gsm_site, {NAME=>$name1, LAT=>$lat1, LON=>$lon1}; push @umts_site,{NAME=>$name2, LAT=>$lat2, LON=>$lon2}; } for my $g (@gsm_site){ $g->{NEAREST} = $umts_site[0]; # Initial assumption til +l we know better $g->{DIST_TO_NEAREST} = distance($g->{LAT},$g->{LON}, $g->{NEARE +ST}{LAT},$g->{NEAREST}{LON}, "K"); for my $u (@umts_site[1..$#umts_site]){ my $this_distance = distance($g->{LAT},$g->{LON}, $u->{LAT},$ +u->{LON}, "K"); next unless $this_distance < $g->{DIST_TO_NEAREST}; $g->{NEAREST} = $u; $g->{DIST_TO_NEAREST} = $this_distance; } } # Print them out for my $g (@gsm_site){ print "$g->{NAME}, $g->{NEAREST}->{NAME}, $g->{DIST_TO_NEAREST},\n" +; } __DATA__ NameA Longitude Latitude NameB Longitude Latitude 10001_NI0001, 36.79887354, -1.26122956, " WL3762", 34.52328889 , -1.00 +7941667 NI0006, 36.86998613, -1.295393144, " NM5286", 36.83137418, -1.17262637 +2 NI0066, 36.82748524, -1.25734101, " EC4140", 37.4580536, -0.53351668,
Note - you should really use a module like Text::CSV, instead of the split hack, above.

        ...it is unhealthy to remain near things that are in the process of blowing up.     man page for WARP, by Larry Wall

Replies are listed 'Best First'.
Re^2: Nested foreach loops
by keienn (Novice) on Sep 09, 2016 at 22:06 UTC
    Thank you Monks, for your great help. I did try NetWallah's code,thanks O great Abbot. I am however getting some errors originating from the subroutine which am sharing here as you had suggested. I previously got such errors while trying different loops but avoided tinkering with the subroutine which works as it is. What should i change in the new code? Here are the exceptions am getting and the subroutine code;

    The errors, the line 5852 is the last line in my CSV file
    C:\MyScripts\2G3Gdistance.pl
    Argument "Longitude" isn't numeric in subtraction (-) at
    C:\MyScripts\2G3Gdistance.pl line 53, <COMBINED> line 5852 (#1)
    Argument "Latitude" isn't numeric in multiplication (*) at
    C:\MyScripts\2G3Gdistance.pl line 80, <COMBINED> line 5852 (#1)
    Use of uninitialized value $lon2 in subtraction (-) at
    C:\MyScripts\2G3Gdistance.pl line 53, <COMBINED> line 5852 (#2)
    (W uninitialized) An undefined value was used as if it were already
    defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
    To suppress this warning assign a defined value to your variables.
    Use of uninitialized value $deg in multiplication (*) at
    C:\MyScripts\2G3Gdistance.pl line 80, <COMBINED> line 5852 (#2)
    Uncaught exception from user code:
    Can't take sqrt of -4.44089e-016 at C:\MyScripts\2G3Gdistance.pl line 71, <COMBINED> line 5852.
    main::acos(1) called at C:\MyScripts\2G3Gdistance.pl line 55
    main::distance(-0.433525648, 36.968599085, -0.433525648, 36.96859909, "K") called at C:\MyVolume\Development\MyScripts\2G3Gdistance.pl line 150

    The subroutine code

    my $pi = atan2(1,1) * 4; sub distance { my ($lat1, $lon1, $lat2, $lon2, $unit) = @_; my $theta = $lon1 - $lon2; my $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad +($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); $dist = acos($dist); $dist = rad2deg($dist); $dist = $dist * 60 * 1.1515; if ($unit eq "K") { $dist = $dist * 1.609344; } elsif ($unit eq "N") { $dist = $dist * 0.8684; } return ($dist); } #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +: #::: This function get the arccos function using arctan function :: +: #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +: sub acos { my ($rad) = @_; my $ret = atan2(sqrt(1 - $rad**2), $rad); return $ret; } #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +: #::: This function converts decimal degrees to radians :: +: #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +: sub deg2rad { my ($deg) = @_; return ($deg * $pi / 180); } #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +: #::: This function converts radians to decimal degrees :: +: #::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +: sub rad2deg { my ($rad) = @_; return ($rad * 180 / $pi); } print distance(32.9697, -96.80322, 29.46786, -98.53506, "K") . " Kilom +eters\n";
      Argument "Longitude" isn't numeric in subtraction (-) at C:\MyScripts\ +2G3Gdistance.pl line 53, <COMBINED> line 5852 (#1) Argument "Latitude" isn't numeric in multiplication (*) at C:\MyScript +s\2G3Gdistance.pl line 80, <COMBINED> line 5852 (#1)

      These are clearly the results of you trying to perform arithmetic on the values obtained from your data file's header row. Don't do that. Only start processing the actual data from row 2 onwards.

      Use of uninitialized value $lon2 in subtraction (-) at C:\MyScripts\2G3Gdistance.pl line 53, <COMBINED> line 5852 (#2)

      This suggests that you have not parsed the data file correctly because $lon2 remains undefined. I suggest that you print out the values of all the arguments to distance() as soon as you retrieve them in order to determine how the parsing has failed and then correct that. The later errors are likely propagations of this problem.

      Do take a look through the Basic debugging checklist if you have not already done so. It will help you clear up such similar problems in future.

        Great Monks I finally did get the code to give the solution I wanted. It still gives the 'uninitialized value' warnings which i have suppressed, but i now know they come about because of the empty cells in the CSV file being used in a calculation. These I will deal with eventually.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1171354]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-24 19:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found