PDA

View Full Version : Perl script to read from one file, calculate, and write output to another file?


cjwsb
12-10-2003, 04:48 PM
Hi all,

Perl NEWBIE here. I created a file (that for now is filled with dummy data) called backs.dat. Basically, it just has some information about running backs in the NFL. Here's it contents:

Jerome Bettis PIT 323 1460
Priest Holmes KC 400 1500
Kevin Faulk NE 250 1000
Clinton Portis DEN 300 1200
Eddie George TEN 350 1300
Ahman Green GB 250 900

Each field is seperated by tabs.

I have also created a file called avgs.dat for writing. I am trying to write a script that will open the backs.dat file, reads from it, and mathematically calculates the running back averages, then sends them into the avgs.dat file. I would like any information already in the avgs.dat file to be overwritten. If either operation fails, I want the script to exit with an appropriate error message. Each line read from backs.dat should be separated so that all five fields are stored in separate variables. For each input line, a line of the following form should be output to avgs.dat:

FIRST-NAME LAST-NAME AVG-YDS-PER-CARRY

Note that the AVG-YDS-PER-CARRY is computed as $yards/$carries. For instance, a calculator shows me that the Jerome Bettis answer would be:

Jerome Bettis 4.52012383900929

After backs.dat has been processed in its entirety, both files should be closed. If a close fails, an error message should be produced and the script should exit.

I am having a helluva time figuring this out. I know it's a simple calulation, but I can't seem to even get off the ground. Anyone have any thoughts on this? Could someone show me some code examples, perhaps, that would do this? There's no rush, but it is driving me crazy!

Thanks!

Jeff Mott
12-10-2003, 06:57 PM
Sounds a lot like a homework assignment. Is there a specific spot you're having problems with or are you just expecting us to write the entire program for you?

cjwsb
12-10-2003, 09:14 PM
LOL. Nah, it's not a homework assignment. 27 years old, and college is far behind me now.

I am trying to learn perl on my own, reading "Learning Perl, third edition". Decent book.

I AM, however, using also using old notes from a friend of mine who did take a perl class years ago. This WAS a homework assignment for him. I am just using his old notes and homework so that I'll have some exercises to do to learn better.

I don't really have a specific spot I need help with. If someone has some example code, that would be nice. I would like to look it over to get some ideas (or just to simply see how it would work).

Thanks!

dswimboy
12-11-2003, 03:28 AM
check out Chapter 11 in your book. this will explain file handles pretty well.

for the extraction, i would use some pattern matching. read the section on Memory Parentheses in Chapter 8, just for some background info. then read the section 'the match variables' in chapter 9.

once you've read these, and are still having problems...come back, i'll give you the code...

cjwsb
12-11-2003, 04:02 AM
Thx, I'll brush up on chapter 11!

cjwsb
12-16-2003, 08:55 PM
This is what I have been able to come up with so far, but it's not working right.

#!/usr/bin/perl

sub probTwo() {
# open the backs.dat file for reading
# form: FIRST-NAME LAST-NAME CITY CARRIES YARDS
my $backFile = "backs.dat";
open (INFILE, "$backFile") or die "\nERROR: Cannot open the file \"$backFile\". Check to see if it exists in the current directory.\n";

# open the file to write to. Create if it does not exist
my $outputFile = "avgs.dat";
open(AVERAGES, ">$outputFile") or die "\nERROR: Cannot create/open $outputFile\n";
select AVERAGES; #redirect where to print

my @output;
my @data;
my $index = 0;

# Read each line from the file
while (<INFILE>) {
chomp;

# ignore lines I don't care about
if (length > 2) {
@data = split("\t"); # separated by tabs.

# create the lines for my output file and print them directly to the file
print AVERAGES $data[0]."\t".$data[1]."\t".($data[4]/$data[3])."\n";
}
}

#close the files
close(AVERAGES) or die "\nERROR: Cannot close $outputFile: $!\n";
close(INFILE) if (<INFILE>) or die "\nERROR: Cannot close $backFile: $!\n";
}

The backs.dat file is still the same as in my original post, but after running this script, all I get in avgs.dat is: nothing! It doesn't create the file if it doesn't exist, and if I manually create one, it doesn't write to it. What am I doing wrong? Thanks!

dswimboy
12-16-2003, 09:39 PM
you have some extra tabs in the backs.dat file.
if you change
print AVERAGES $data[0]."\t".$data[1]."\t".($data[4]/$data[3])."\n";
to
print AVERAGES $data[0]."\t".$data[1]."\t".($data[6]/$data[4])."\n";
you tab problem should be fixed. or you could make sure there is only 1 tab between each 'field' of the backs.dat file.

cjwsb
12-16-2003, 10:34 PM
There IS only one tab between all the fields. I amde the changes anyway, but it didn't help. Any other thoughts? Thanks!

cjwsb
12-17-2003, 01:35 AM
I think I got it. Took some rewriting, but it seems to work. Waddya think?

#!/usr/bin/perl

open (READ, "backs.dat") || die "Can't find backs.dat\n";

$x=0;

while ($info = <READ>) {
chomp $info;
@data = split (/\t/, $info);
push @RecEnt, [@data];
$x++;
}

close READ || die "Couldn't close backs.dat";
open (WRITE, ">avgs.dat") || die "Can't find avgs.dat\n";

$y=0;

foreach (@RecEnt){
$Avg = $RecEnt[$y][4]/$RecEnt[$y][3];
$printout .= "$RecEnt[$y][0]\t$RecEnt[$y][1]\t$Avg\n";
$y++;
}

print WRITE $printout;
close WRITE || die "Couldn't close avgs.dat";
exit (0);

dswimboy
12-17-2003, 03:16 PM
number one rule in perl: there is more than one way to do things.
which ever you like best, is correct.

cjwsb
12-17-2003, 03:44 PM
:thumbsup: