Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

RE: Re: Breaking a Loop

by Anonymous Monk
on Oct 10, 2000 at 22:39 UTC ( [id://36093]=note: print w/replies, xml ) Need Help??


in reply to Re: Breaking a Loop
in thread Breaking a Loop

Hi guys, thanks for the speedy reply. The problem i guess is that i only want the subroutine, or array sorted once, and it isnt defined until the END of the loop.. lemme attach the code, and hopefully it will help
#!/usr/local/bin/perl # Author: Dipul Patel # This Perl Script takes a home site chosen by the user, then calcula +tes # the distance from that home site to every site in the system and pr +ints # in a HTML table. #--------------------------------------------------------------------- # Process information for main site #--------------------------------------------------------------------- $lat_long = "/tmp/sitesLL"; $filepath = "/data1/PHL/neighbors"; $query_string = $ENV{'QUERY_STRING'}; @search = split(/&/,$query_string); @info = split(/=/, $search[0]); @siteinfo = split(/-/, $info[1]); print "Content-type: text/html\n\n"; #read in lat and long file open(LL, $lat_long); @lat_long = <LL>; close(LL); #Get long,lat,g,h,j for main site @dataline = grep /^$siteinfo[0]/, @lat_long; @dataparse = split(/\|/, $dataline[0]); ($sitelat, $sitelong) = split(/,/, $dataparse[3]); $g = $dataparse[4]; $h = $dataparse[5]; $j = $dataparse[6]; #--------------------------------------------------------------------- # Process information for every other site, one at a time #--------------------------------------------------------------------- #open directory and get sites names opendir DIR, $filepath; @allfiles = grep !/^\.\.?$/, readdir DIR; closedir DIR; @allfiles = sort @allfiles; $totalsite=@allfiles; @allfiles2=@allfiles; foreach $site(@allfiles) { chomp $site; @frst = split(/[a-z][a-z]/, $site); @cell = split(/[A-Z]/, $frst[1]); push(@othersiteinfo, $cell[0]); } #Open assiociated neighbor list file open(IN, "$filepath/$siteinfo[1]"); @data=<IN>; close(IN); #get sector numbers for neighbors foreach $line(@data){ #chomp $line; @information = split (/\|/, $line); push (@neighbor,$information[1]); } $n=-1; $temphigh = 0; while($n<$totalsite){ $n++; @dataline2 = grep /^$othersiteinfo[$n]/, @lat_long; @dataparse2 = split(/\|/, $dataline2[0]); ($sitelat2, $sitelong2) = split(/,/, $dataparse2[3]); $g2 = $dataparse2[4]; $h2 = $dataparse2[5]; $j2 = $dataparse2[6]; #--------------------------------------------------------------------- # calculate distance from main site to other sites #--------------------------------------------------------------------- $a=($g2-$g)*($g2-$g); $b=($h2-$h)*($h2-$h); $c=($j2-$j)*($j2-$j); $abc=($a+$b+$c); $sqabc=sqrt($abc); $distance=(3960*$sqabc); $distance = sprintf "%1.2f", $distance; $distance2=$distance; $distance3=$distance; $distance4=$distance; if ($temphighval >= $temphigh){ $temphigh=$temphighval; } if ( $distance > 10){ next; } # if ( $distance == 0){ # next; # } # The following code, first compares the sector number of the current + site to that of the neighbor list, # then it complies 2 arrays, one with all the neighbors, the other ar +ray with the other sites. $element = $othersiteinfo[$n]; if (grep {$_ eq $element} @neighbor) { @array3=($allfiles[$n],$distance2); push (@test1, @array3); push (@highval, $distance2); } else{ @array2=($allfiles[$n],$distance); push (@test2, @array2); } }#end whileloop my $done_sort=0; # or some more meaningful name while( $cond) { # probably some code here unless( $done_sort) { sort_the_array( @array); $done_sort=1; } # more code here } #create hash and sorted array for non-neighbors %distance=@test2; @sorted = sort { $distance{$a} <=> $distance{$b} } keys %distance; #extract sector numbers from sitename for use in hyperlinks. $k=0; @nonneighsect=@sorted; for ($h=0; $h<=$#nonneighsect; $h++) { $nonneighsect[$h] =~ s/\w{2}(\d{4})\w+/$1/; } #create hash and sorted array for neighbors %distance2=@test1; @sorted2 = sort { $distance2{$a} <=> $distance2{$b} } keys %distan +ce2; #extract sector numbers from sitename for use in hyperlinks. $j=0; @neighsect=@sorted2; for ($i=0; $i<=$#neighsect; $i++) { $neighsect[$i] =~ s/\w{2}(\d{4})\w+/$1/; } #-------------------- # the following code prints a table, with all the sites sorted first b +y neighbor, then distance. It also provides links # to automattically calculate distances for other sites, as well as ma +p them. #-------------------- print "<HTML>\n"; print "<HEAD><TITLE>Distance Tool</TITLE></HEAD>\n"; print "<TABLE BORDER=1 cellspacing=1 cellpadding=1 WIDTH =65%>\n"; print "<TR><TH Colspan = 4> Distance From $siteinfo[1] To:<TH>"; # print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com/cg +i-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$siteinfo[0]-$sitei +nfo[1]&rpt=Daily-Total&Lfactor=150000&sector=1\" target=_top>1</a></f +ont>\n"; # print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com/cg +i-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$siteinfo[0]-$sitei +nfo[1]&rpt=Daily-Total&Lfactor=150000&sector=2\" target=_top>2</a></f +ont>\n"; # print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com/cg +i-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$siteinfo[0]-$sitei +nfo[1]&rpt=Daily-Total&Lfactor=150000&sector=3\" target=_top>3</a></f +ont>\n"; print "<FONT SIZE =\-5>"; print "<TR><TH>Site<TH>Distance<TH>Neighbor<TH>Map(sector)\n"; foreach $site3 (@sorted2) { print " <TR><TD><FONT SIZE=\-5><A HREF=\"http://www-mat.ne +xtel.com/cgi-bin/rfn-cgi/distance.cgi?site=$neighsect[$j]-$site3\" >$ +site3<TD>$distance2{$site3}<TD align=center>YES</font>\n"; print " <TD align=center><FONT SIZE=\-5><A HREF=\"http://w +ww-mat.nextel.com/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site +=$neighsect[$j]-$site3&rpt=Daily-Total&Lfactor=150000&sector=1\" targ +et=_top>1</a></font>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$neighsect[$j]-$ +site3&rpt=Daily-Total&Lfactor=150000&sector=2\" target=_top>2</a></fo +nt>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$neighsect[$j]-$ +site3&rpt=Daily-Total&Lfactor=150000&sector=3\" target=_top>3</a></fo +nt>\n"; $j++; } foreach $site2 (@sorted) { print " <TR><TD><FONT SIZE=\-5><A HREF=\"http://www-mat.ne +xtel.com/cgi-bin/rfn-cgi/distance.cgi?site=$nonneighsect[$k]-$site2\" +>$site2<TD>$distance{$site2}<TD align=center>NO</font>\n"; print " <TD align=center><FONT SIZE=\-5><A HREF=\"http://w +ww-mat.nextel.com/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site +=$nonneighsect[$k]-$site2&rpt=Daily-Total&Lfactor=150000&sector=1\" t +arget=_top>1</a></font>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$nonneighsect[$k +]-$site2&rpt=Daily-Total&Lfactor=150000&sector=2\" target=_top>2</a>< +/font>\n"; print " <FONT SIZE=\-5><A HREF=\"http://www-mat.nextel.com +/cgi-bin/rfn-cgi/neighbormap2.cgi?frames=frames&site=$nonneighsect[$k +]-$site2&rpt=Daily-Total&Lfactor=150000&sector=3\" target=_top>3</a>< +/font>\n"; $k++; } print "</FONT>"; print "</TABLE>\n"; print "</HTML>\n";
now, what i want, is where it says
if ( $distance > 10){ next; }
i want the 10 to be replaced with the highest value of the array defined at the end of the loop:
if (grep {$_ eq $element} @neighbor) { @array3=($allfiles[$n],$distance2); push (@test1, @array3); push (@highval, $distance2); }
But.. that array is added to everytime the loop runs, and i need the highest value from it when it is complete, so i can specify the largest distance to map. I hope this helps.
Dipul Patel

Replies are listed 'Best First'.
RE: RE: Re: Breaking a Loop
by Adam (Vicar) on Oct 10, 2000 at 22:59 UTC
    So you don't want to sort the array, you want to find the max value in it. So write a subroutine to find the max value in your array and call that (just like chromatic suggested!)
    use strict; # ALWAYS!!!!!! # MaxElementInArray( @array ) sub MaxElementInArray { my $max = shift; my $next; $max = $next > $max ? $next : $max while $next = shift; return $max; } # MaxElementInArrayRef( \@array ) sub MaxElementInArrayRef { my $array_ref = shift; my $index = $#$array_ref; my $max = $$array_ref[$index]; $max = $$array_ref[$index] > $max ? $$array_ref[$index] : $max while --$index >= $[; return $max; }
    Update: While examining your code in response to your statement below, I've noticed quite a few style issues: You don't use strict, you are not using CGI.pm, and you are not using subroutines to improve the readability (and maintainability) of your code. I strongly suggest you look into these things. As for your issue of trying to use a number before you have calculated it... this reveals a failure to plan before coding. Now I suspect you will need to re-write much of this code just to get things in a causal order.
      Right, but there is still the problem that the array isnt defined until the end of the loop and that the sub routine has to be called within the loop. I need the max value of the final completed array, and returned into the loop..:-\.. when i wrote a subroutine it kept running it before it was called within the loop, and i would never get the final max value until the very end of the loop, by which point it was too late. thanks
      Dipul Patel
        You can't know something before you know it, unless you use Time::Machine.

        Time to rethink your algorithm. Say in english what you want to do. Avoid the word "loop" or "array". Just talk about what you want done, because you are now hopelessly down in the guts of the implementation with muddy thinking, and no-one can help you from there.

        -- Randal L. Schwartz, Perl hacker

RE: RE: Re: Breaking a Loop
by Anonymous Monk on Oct 10, 2000 at 23:31 UTC
    Oh yeah, i forgot to mention, this is my second week of learning perl hehe :). Adam, where exactly should i place the code you gave me? I dont understand where to put it, and where/which one to call. Thanks
    Dipul Patel
      You may wish to be aware of a rather serious security hole in this script. I have detailed it here. You should read perlsec to learn the basics of these issues, and I would also suggest picking up a copy of "CGI Programming with Perl, Second Edition", by O'Reilly Press.

      Cheers,
      Ovid

      Join the Perlmonks Setiathome Group or just go the the link and check out our stats.

Log In?
Username:
Password:

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

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

    No recent polls found