On 2/6/10, Chris Coggins <cacogg...@cox.net> wrote:
> Rob Dixon wrote:
>> Chris Coggins wrote:
>>> I posted a question to this list yesterday from the google groups
>>> interface, asking for help with the following. I have since tried to
>>> post additional details in replies to that message using the google
>>> groups site and none of my posts have shown up on the list so let's
>>> try this again the right way.
>>>
>>> I have a datafile with 1 line of data, 30 numbers delimited by
>>> tildes. (Sample code below only uses 4 numbers to save time)
>>>
>>> I need to open this file, grab this line of data, split it into
>>> individual numbers, perform some simple math (addition) on each
>>> number, and then put the new values back into the datafile, replacing
>>> the original data that was there.
>>>
>>> I neglected to mention in my original post that I need to access
>>> these new values elsewhere in the script to perform additional math
>>> functions with them.
>>>
>>> I've tried several variations of the code below, including using
>>> arrays, and none of them got through without the script failing. The
>>> new datafile gets written, but it merely contains a ~. The errors I
>>> get are "use of uninitialized values in such and such line" and
>>> "variables needs explicit package name". When the script does run,
>>> the variables lose their values as soon as I close the file after
>>> inhaling it, making all the rest of the actions in the subroutine
>>> futile.
>>>
>>> the datafile used below initially contains 30 values that were
>>> written previously, and this has been verified over and over.
>>>
>>> sub newValues {
>>> my($file)   =  shift;
>>>
>>> open(FILE, "<$file") or die("Unable to open data file.");
>>> while (<FILE>) {
>>> my($a,$b,$c,$d) = split(/~/, $_);
>>> $a = $a+$previousarray[4]; # I've tried to perform this math action
>>> after close(FILE) and get the same result -> failure.
>>> $b = $b+$previousarray[7];
>>> $c = $c+$previousarray[0];
>>> }
>>> close(FILE);
>>> open(FILE, ">$file") || die ("unable to open file");
>>> print FILE ("$a~$b~$c \n");
>>> close(FILE);
>>> }
>>> #end sub
>>>
>>> Now my datafile just contains a single tilde and no values. I've also
>>> tried to bring the original data from the datafile into my(@array)
>>> and get the same errors.
>>>
>>> Keep in mind I need other subroutines to be able use these new
>>> values, but these local variables lose their values once the file is
>>> closed. I've also tried to declare them as global variables but I'm
>>> not doing something right because the script won't execute.
>>>
>>> I really need some help figuring this out if somebody would be kind
>>> enough to help a novice.
>>
>> Hello Chris
>>
>> Your lexical variables $a, $b, $c are local to the 'while' block, and
>> do not exist outside it. Error "Global symbol xx requires explicit
>> package name" is because the variable is not declared. Error "Use of
>> uninitialized value..." is because Perl uses a value of 'undef' where
>> variables are missing.
>>
>> As an aside it is bad form to use meaningless variable names, and $a
>> and $b are special names that are used by core Perl so should be
>> avoided. Also it is prefereable to use lexical file handles and the
>> three-argument form of 'open', and incorporating the standard variable
>> $! into the die string will give valuable information about why the
>> operation failed.
>>
>> Declaring your variables outside the 'while' loop would fix your
>> problem, but as you are interested only in the first line of the file
>> it is as well to remove the loop altogether. Take a look at the code
>> below and see if it meets your requirements.
>>
>> HTH,
>>
>> Rob
>>
>>
>> sub newValues {
>>
>>   my $file = shift;
>>
>>   open my $data, '<', $file or die "Unable to open data file: $!";
>>   my $line = <$data>;
>>   close $data;
>>
>>   my @data = split /~/, $line;
>>   die "Invalid data format" if @data < 3;
>>   $data[0] += $previousarray[4];
>>   $data[1] += $previousarray[7];
>>   $data[2] += $previousarray[0];
>>
>>   open my $out, '>', $file or die "Unable to open output file: $!";
>>   print $out join('~', @data[0,1,2]), "\n";
>>   close $out or die "Failed to close output file: $!";
>> }
>>
> Rob, thank you very much. This worked perfectly, unless my datafile is
> empty at the start. Easiest fix was inserting 30 zero-tildes into the file.
>
> I have a couple other snags if yall are willing to tolerate the questions.
>
> 1. another script uses data passed into it from an html form. Some of
> the fields are empty, and my "print report file" subroutine prints the
> empty variables because I don't know how to filter them out, and they
> need to be removed from the report. Can someone give me the perfectly
> formed "if" statement that lets me skip over the one or two empty
> variables during the print action? The data being printed to the file is
> stored in an array. See code below.
>
> print FILE ("Report summary: $taskarray[0] \n"); #this value is good
> print FILE ("Data for task 3: $taskarray[3] \n"); #this value is good
> print FILE ("Data for task 7: $taskarray[7] \n"); #this value is empty,
> don't print this data
> print FILE ("Data for task 2: $taskarray[2] \n"); #this value is empty,
> don't print this data
> print FILE ("Data for task 11: $taskarray[11] \n"); #this value is good
> but needs to be modified, see #2 below
>
> 2. Some of the data being printed above needs to be stripped of some of
> its characters in the string. For example, one of the values is a part
> number with 27 characters. I only need the last 10 characters of the
> string for this report because somebody else is going to fill in the
> front 17 characters with a new part code that I have nothing to do
> with.  The string currently looks like this:
> TNA-140ZQ00-170011234567.890. I need it to print to FILE like this:
> ___-_______-______1234567.890, and I need to do this in the same block
> of code above.
>
> Chris


1)  You would have to be more specific as to what an 'empty variable'
is.  Zero?  A blank string? undef?


2)

use strict;
use warnings;
use 5.010;

my $string = 'TNA-140ZQ00-170011234567.890';
my $prefix = '___-_______-______';

my $last_eleven = substr $string, -11;
say "$prefix$last_eleven";

--output:--
___-_______-______1234567.890


By the way, you should know that a period is a character.  You are
pretty sloppy in describing your problems.  Consider providing *no*
verbal explanation of your problems.  Rather try posting, "I have xxxx
and I am trying to get yyyy".  Here is an example program
demonstrating what I am trying to do.   My *expected* output (or
error) is this.  My *actual* output is this."

Also, when you have a problem in your actual program, to try and solve
it you should create another practice program.  Try to mimic the
problem with a 10 line example program, and then post your example
program--not your real program.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to