|
|
deadpickle wrote:
> I have edited my script and now I have ran into another problem. In the
> metar the cloud cover is rocorded as a 3 letter abbr. For this program
> I want it to run through the elements untill it hits one of these. But
> there is a ladder to how they should be printed. If OVC appears then I
> want that to be displayed, If BKN appears and OVC does not but FEW
> does, then I want BKN to be printed out. How can I do this? the code
> works for OVC but when I remove it , it prints nothing to the file.
>
> METAR code
> ----------------------------------------------------
> KCHS 131656Z 15009KT 10SM -RA FEW027 BKN044 24/20 A2994 RMK AO2 RAB44
> SLP137 P0000 T02440200
>
> Program Code
> ----------------------------------------------------
> #loads metar file and sets its elemetns into an array
> $file="KAKO.txt";
> open (IN, $file) || die("Could Not Open File");
> $metar=<IN>;
> close(IN);
> print("$metar\n");
> @metar=split(" ", $metar);
> #remove station name and time
> shift(@metar);
> shift(@metar);
> open(OUT, ">metar2.txt") || die("could Not Open File!");
> #loop through all elements
> foreach (@metar) { #Test for each element in the array
> if (substr($_,5,2) eq "KT") { #Test the elements to find the wind
> spd and dir
> print OUT (substr($_,0,3),"\n"); #wind dir
> print OUT (substr($_,3,2),"\n"); #wind spd
> };
> if (substr($_,0,3) eq "SLP") { #test of SLP
> print OUT (substr($_,3,3),"\n"); #SLP
> };
> if (substr($_,5,1) eq "G") { #test for wind gusts
> print OUT (substr($_,0,3),"\n"); #wind dir
> print OUT (substr($_,3,2),"\n"); #wind spd
> print OUT (substr($_,6,2),"\n"); #wind gust
> };
> if (substr($_,0,3) eq ("OVC" || "BKN" || "FEW" || "CLR")) { #test
> for cloud cover
> if (substr($_,0,3) eq "OVC") {
> print OUT (substr($_,0,3),"\n");
> }
> elsif (substr($_,0,3) eq "BKN") {
> print OUT (substr($_,0,3),"\n");
> }
> elsif (substr($_,0,3) eq "FEW") {
> print OUT (substr($_,0,3),"\n");
> }
> else {print OUT (substr($_,0,3),"\n")}
> };
> };
> close (OUT);
I have modified your code below (not that I do not write to a file and
I was obtaining the input lines from DATA). Code has not been
thoroughly
tested, as I am not sure of your requirements and you should do that.
Pay particular attention to %matches, which I believe you will want to
use
for your 'laddering'.
I have tried to comment the areas of the code that I modified
substantially,
so have a look at those. You should be able to get by your current
problem with this information.
Ken
#---------------------------------------------------------------
# I see that you still did not add the following two lines.
# Use them, they are your friend.
#---------------------------------------------------------------
use strict;
use warnings;
use English;
# append "\n" on each print
$OUTPUT_RECORD_SEPARATOR = "\n";
#loads metar file and sets its elemetns into an array
while (my $metar = <DATA> )
{
print("$metar");
#-----------------------------------------------------------
# remove station name and time
# I used a substitution rather than your split and shift
# so the lines setting @matches would ignore these
# fields.
#-----------------------------------------------------------
$metar =~ s/\w+\s+\w+\s+(.+)/$1/;
#-----------------------------------------------------------
# Determine what 'words' begin with the abbreviations
# of interest.
#-----------------------------------------------------------
my @matches = $metar =~ m/(?:^|\s+)(OVC|BKN|FEW|CLR)[^\s]/g;
#-----------------------------------------------------------
# Create a hash with the 3 letter abbreviations of interest
# as the key. You can then test to see if that abbreviation
# appeared as the first 3 letters of a 'word' on the
# line. I did not use this hash, but from your comments
# it would appear you want to be able to test this
#-----------------------------------------------------------
my %matches = map { $_ => 1 } @matches;
my @metar=split(" ", $metar);
foreach (@metar) {
# Test the elements to find the wind spd and dir
#--------------------------------------------------------
# Use index function in this case rather than substr,
# so we don't get warnings if string is shorter
# than 7 characters.
#--------------------------------------------------------
if (index ($_, 'KT', 5) == 5)
{
print 'wind dir: ',substr($_,0,3);
print 'wind spd: ',substr($_,3,2);
}
if (substr($_,0,3) eq "SLP") { #test of SLP
print 'SLP: ',substr($_,3,3); #SLP
};
if (index ($_,'G') == 5) { #test for wind gusts
print 'wind dir: ',substr($_,0,3);
print 'wind spd: ',substr($_,3,2);
print 'wind gust: ',substr($_,6,2);
};
# test for cloud cover
#--------------------------------------------------------------
# Your test:
# if (substr($_,0,3) eq ("OVC" || "BKN" || "FEW" || "CLR"))
# is an error similar to that in your original code:
# if ((length($t) && length($td)) == 2)
# For this line to work, it would be:
# if (substr($_,0,3) eq 'OVC' || substr($_,0,3) eq 'BKN' ||
# substr($_,0,3) eq 'FEW' || substr($_,0,3) eq 'CLR'))
# I elected to go with a regular expression
#--------------------------------------------------------------
/^(OVC|BKN|FEW|CLR)/ && do
{
my $type = $1;
if ($type eq "OVC") {
print substr($_,0,3);
}
elsif ($type eq "BKN") {
print substr($_,0,3);
}
elsif ($type eq "FEW") {
print substr($_,0,3);
}
else {
print substr($_,0,3)
}
};
}
}
__DATA__
KCHS 131656Z 15009KT 10SM -RA FEW027 BKN044 24/20 A2994 RMK AO2 RAB44
SLP137 P0000 T02440200
BKN044 24/20 BKN044 KCHS 131656Z 15009KT 10SM -RA FEW027 A2994 RMK AO2
RAB44 SLP137 P0000 T02440200 OVC4444
|
|