Philip Ankrah
Philip Ankrah

Reputation: 35

Output file is blank

I don't know why the following code outputs a blank file. I am running Windows 8. I've received help from this community for previous perl help and this is just what I've been able to put together with the help I've received. However, I can't figure out where this script goes awry.

#! perl
use strict;
use warnings;
use HTML::FormatText;
use LWP::Simple;

my $dateField = 'date=2018-12-31';
my $currency  = "USD";
my $filename = 'C:\Users\Name\Desktop\doc3.txt';
my $address = "https://www.oanda.com/rates/api/v1/rates/$currency.csv?api_key=gpolonsky&decimal_places=4&$dateField&fields=averages&quote=USD&quote=AUD&quote=BRL&quote=CAD&quote=GBP&quote=CHF&quote=CNY&quote=DKK&quote=HKD&quote=INR&quote=IDR&quote=ILS&quote=JPY&quote=MXN&quote=NOK&quote=PHP&quote=PLN&quote=SGD&quote=sKK&quote=ZAR&quote=KRW&quote=SEK&quote=TWD&quote=THB&quote=EUR&quote=MYR&quote=NZD&quote=SAR&quote=TRY&quote=RUB&quote=CZK&quote=AED&quote=CLP&quote=EGP&quote=MAD&quote=NGN&quote=OMR&quote=QAR";
my $content = get($address);
my $s = 1;

defined $content or die "Cannot read '$address': $!";
$content =~  s/^[^\n]*\n//s; 
$content =~  s/^/20181231,/gm; # The m option makes ^ match at the start of each line
$content =~  s/,2018-12-3[0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\+0000*//g;
$content =~  s/([A-Z][A-Z][A-Z]),[0-9]*\.[0-9][0-9][0-9][0-9]/$1/g;

my $string = HTML::FormatText->format_string(
    $content,
    leftmargin  =>  0,
    rightmargin => 23,
);

open(my $file, '>', $filename) or die $!;
print $file $string;

my @curOrd = qw( USD AUD BRL GBP CAD CNY DKK HKD INR IDR ILS JPY MXN NOK PHP PLN SGD SKK ZAR KRW SEK CHF TWD THB EUR MYR NZD SAR TRY RUB CZK AED CLP EGP MAD NGN OMR QAR );
my %data;
my $infile = 'C:\Users\Name\Desktop\doc3.txt';
my $outfile = 'file2.txt';

open (my $in, "<", $infile ) || die "can't open $infile file"; 
while (my $line = <$in>) {
    push(@{$data{(split ',', $line)[2]}}, $line);
} 
print $infile;
close $in;

open (my $out, ">", $outfile) || die "can't open $outfile file"; 
foreach my $curr (@curOrd) {
    foreach my $line (@{$data{$curr}}) {
        print $out $line;
    }
}
close $out;

Upvotes: 1

Views: 100

Answers (2)

Dave Cross
Dave Cross

Reputation: 69224

Your problem is that you need to explicitly close() the file you're writing to before you can re-open it to read from it.

But that whole intermediate file is pointless (as I've suggested before). Just process all the data in memory before writing it to your output file.

use strict;
use warnings;
use feature 'say';

use LWP::Simple;

my $dateField = 'date=2018-12-31';
my $currency  = "USD";
my $filename = 'doc3.txt';
my $address = "https://www.oanda.com/rates/api/v1/rates/$currency.csv?"
            . "api_key=gpolonsky&decimal_places=4&$dateField&fields=averages&"
            . "quote=USD&quote=AUD&quote=BRL&quote=CAD&quote=GBP&"
            . "quote=CHF&quote=CNY&quote=DKK&quote=HKD&quote=INR&"
            . "quote=IDR&quote=ILS&quote=JPY&quote=MXN&quote=NOK&"
            . "quote=PHP&quote=PLN&quote=SGD&quote=sKK&quote=ZAR&"
            . "quote=KRW&quote=SEK&quote=TWD&quote=THB&quote=EUR&"
            . "quote=MYR&quote=NZD&quote=SAR&quote=TRY&quote=RUB&"
            . "quote=CZK&quote=AED&quote=CLP&quote=EGP&quote=MAD&"
            . "quote=NGN&quote=OMR&quote=QAR";

my $content = get($address);

# I've removed $! from the die() error below. $! is the last
# *operating system* error. And making an HTTP request is not
# an operating system operation - so the contents will have no
# connection to the results of our GET request.
defined $content or die "Cannot read '$address'";
$content =~  s/^[^\n]*\n//s;
$content =~  s/^/20181231,/gm; # The m option makes ^ match at the start of each line
$content =~  s/,2018-12-3[0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\+0000*//g;
$content =~  s/([A-Z][A-Z][A-Z]),[0-9]*\.[0-9][0-9][0-9][0-9]/$1/g;

my @curOrd = qw( USD AUD BRL GBP CAD CNY DKK HKD INR IDR ILS JPY MXN
                 NOK PHP PLN SGD SKK ZAR KRW SEK CHF TWD THB EUR MYR
                 NZD SAR TRY RUB CZK AED CLP EGP MAD NGN OMR QAR );

my $i = 1;
my %curr_lookup = map { $_ => $i++ } @curOrd;

my @data = map { [ split /,/ ] } split /\n/, $content;

my $outfile = 'file2.txt';

@data = sort { $curr_lookup{$a->[2]} <=> $curr_lookup{$b->[2]} }
        @data;

open my $out, '>', $outfile or die "Can't open $outfile for writing: $!";

say $out join ',', @$_ for @data;

Upvotes: 4

ElectricLab
ElectricLab

Reputation: 51

You need to close $file after you fetch the data from the server and are writing it to a file:

open(my $file, '>', $filename) or die $!;
print $file $string;
close($file)  # Add this line

I also had to use http:// instead of https:// in $address, but I'm on a CentOS box with an old LWP install that doesn't seem to do TLS.

Upvotes: 5

Related Questions