Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Question on loops and return values

Reply
Thread Tools

Question on loops and return values

 
 
delfuego
Guest
Posts: n/a
 
      12-03-2004
I have a script below that is supposed to read in a list of microsoft
servers, and output the disk space (current and last), dates
(beginning and ending), and compute space growth in value and
percentage; to output file. The question is this: how do I get the
correct looping going on in my for loops (one is not getting the
machines, the other is not getting the drive letters; as well as any
other problems you can point out. The files are listed below the
scriipt, although I plan to write out two additional columns, growth
value and growth rate.
ALL help is appreciated.
Thanks,

James

<script beow inline>

use lib "$ENV(HOME)/site/lib"; # occasionally perl whines about not
in a lib
no lib ".";
use warnings;
use Time::localtime; # needed for tm and using that to get dates
use Time::tm;
use Win32API::Resources; # needed for drives and disk space

our @drive = Win32API::Resources::GetDrives();
our %space = Win32API::Resources::GetDriveSpace("$let:\\");
our $file = (<SD>,"growth.cvs"); # output data file
our $file2 = (<SD>,"machines.cvs"); # input data file
our $let = ['A-Z']; # character value for drive letters
our $gvalue = 0; # difference, should be positive
our $curr = 0; # current disk space value
our $last = 0; # last disk space value
our $grate = 0; # growth rate percentage
our @line = ""; # was going to be used for file looping
our $edate = ""; # end date for run
our $sdate = ""; # start date for run

# Mind you, we still need to loop this through machines in a list, but
# this will supposedly loop through the letters in the GetDrives
returns
open (file2,"+<"); # open machines input file for read
while <file2> # loop while not eof in machines.cvs
{
foreach $machine (<file2>)
{
print "The following are valid disk drives: @drive\n";
foreach $let (@drive)
{
&space();
&growth();
}
}
}

close file2;

sub space()
# This will return the space details available from ShowKeys in three
line format
{
Win32API::Resources::ShowKeys("Drive Space:", 2, \%space);
}

sub growth()
# Reads in current value from file growth.cvs to be the value for
last, then
# the %DRVSpace becomes current's value. After this, the dates are
set and
# we start computing the growth, giving growth difference and
percentage.
# Finally, all details are written to the appended file.
{
open file or die "Cannot open data file for read\n";
while <file>
{
$sdate = (read(file,"$junk," ",$edate," ",$junk," ",$junk) =
split);
chop ($sdate);
$last = (read(file,"$junk," ",$junk," ",$junk," ",$curr) = split);
chop ($last);
}
close file;
# we have the last and sdate variables, now we need the others
my $edate = Time::tm(localtime(){$4,$5,$6});
$curr = %DRVSpace;
$last = eval { $curr / 5 }; # bogus value for testing, should be
file($curr)
# now we sart computing
$gvalue = eval { $curr - $last }; # growth rate difference
$grate = eval { ($gvalue / $last) * 100 }; # growth rate percentage
# time for a screen dump
print "Date: $edate";
print "Last: $last\tCurrent: $curr\tGrowth: $gvalue\tGrowth Rate:
$grate\n";
# now to dump everything to the file
open (file,"+>> ") or die "Cannot open data file for write\n";
while <file>
{
print (file,"\n$sdate $edate $last $curr");
}
close file;
}

<files>

machines.csv
---------------
snoopy
linus
charlie
lucy
pigpen
freida

growth.csv
-----------
11-29-2004 11-30-2004 160 125
11-30-2004 12-01-2004 125 75
12-01-2004 12-02-2004 75 50
 
Reply With Quote
 
 
 
 
Jim Keenan
Guest
Posts: n/a
 
      12-03-2004
delfuego wrote:

> I have a script below that is supposed to read in a list of microsoft
> servers, and output the disk space (current and last), dates
> (beginning and ending), and compute space growth in value and
> percentage; to output file. The question is this: how do I get the
> correct looping going on in my for loops (one is not getting the
> machines, the other is not getting the drive letters; as well as any
> other problems you can point out. The files are listed below the
> scriipt, although I plan to write out two additional columns, growth
> value and growth rate.
> ALL help is appreciated.
> Thanks,
>
> James


Am I correct in suspecting that this is a script that someone else
originally wrote and you have to fix? There's a lot of
less-than-optimal code below (e.g., use of 'our' where 'my' would almost
certainly suffice).

>
> <script beow inline>
>
> use lib "$ENV(HOME)/site/lib"; # occasionally perl whines about not
> in a lib
> no lib ".";
> use warnings;
> use Time::localtime; # needed for tm and using that to get dates
> use Time::tm;
> use Win32API::Resources; # needed for drives and disk space
>
> our @drive = Win32API::Resources::GetDrives();
> our %space = Win32API::Resources::GetDriveSpace("$let:\\");


Here a USENETtiquette problem arises. In order for us to troubleshoot
your code, we need to be on Windows, because the Win32API modules only
work on that OS. If your problem is a Windows-specific problem, then
you should probably post it on a Windows-specific list such as
http://www.velocityreviews.com/forums/(E-Mail Removed). But I'm not reading this on Windows,
so I can't test your code. My hunch is that your problem is *not*
Windows-specific, but is located in how to read directory and file
information.

Wherever you post, you should try to post the smallest possible amount
of code needed to illustrate the problem. Most of the people who read
this list don't have enough time to work through all of it --
particularly if it requires a particular OS. If you try to post the
smallest possible amount you will, in the process, probably locate your
error yourself.

> our $file = (<SD>,"growth.cvs"); # output data file
> our $file2 = (<SD>,"machines.cvs"); # input data file
> our $let = ['A-Z']; # character value for drive letters


[snip balance]

Jim Keenan
 
Reply With Quote
 
 
 
 
Tad McClellan
Guest
Posts: n/a
 
      12-04-2004
delfuego <(E-Mail Removed)> wrote:

><script beow inline>



Please show *real code*!


> use lib "$ENV(HOME)/site/lib"; # occasionally perl whines about not

^ ^
^ ^ {HOME}


> our $file = (<SD>,"growth.cvs"); # output data file
> our $file2 = (<SD>,"machines.cvs"); # input data file



Where is the SD filehandle open()ed?

Why are you using package variables instead of lexical variables?


> our $let = ['A-Z']; # character value for drive letters



You never make use of this variable, and it almost certainly
is not what you think it is.

It is a reference to an anonymous array with 1 element in it.


> our @line = ""; # was going to be used for file looping



How may elements are you expecting to be in @line right here?

Were you expecting zero elements, an empty array?

That isn't what you are getting there...


> open (file2,"+<"); # open machines input file for read



You are opening for read AND write, the comment is a trick!

Did you mean to put a filename in there somewhere?

You should use UPPER CASE for filehandles.

You should always, yes *always*, check the return value from open().


> while <file2> # loop while not eof in machines.cvs



Syntax error.

Show *real code*!


> foreach $machine (<file2>)



You are reading from the _same_ filehandle in 2 different places
in your code. Is that what you want to do?

The while loop (if it compiled) would only execute one time.

The foreach provides list context, so it will slurp to the end of file.


> chop ($last);



That is how we removed newlines 8 years ago. Where did you learn that?

Nowadays you should use chomp() to remove newlines.


> $curr = %DRVSpace;



This most certainly does not do what you think it does.

The value of a hash in scalar context is not of interest to
a Perl programmer, it is only of interest to a perl programmer.


> $last = eval { $curr / 5 }; # bogus value for testing, should be
> $gvalue = eval { $curr - $last }; # growth rate difference
> $grate = eval { ($gvalue / $last) * 100 }; # growth rate percentage



Can you tell us why you are using eval() there?


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-07-2004
Tad McClellan <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> delfuego <(E-Mail Removed)> wrote:


[...]

> > $grate = eval { ($gvalue / $last) * 100 }; # growth rate percentage

>
>
> Can you tell us why you are using eval() there?


It's probably a misguided way of saying

$grate = ($gvalue / $last) * 100 if $last;

Anno
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-08-2004
Abigail <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Anno Siegel ((E-Mail Removed)-berlin.de) wrote on MMMMCXVI
> September MCMXCIII in <URL:news:cp47no$d7l$(E-Mail Removed)-Berlin.DE>:
> __ Tad McClellan <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> __ > delfuego <(E-Mail Removed)> wrote:
> __
> __ [...]
> __
> __ > > $grate = eval { ($gvalue / $last) * 100 }; # growth rate percentage
> __ >
> __ >
> __ > Can you tell us why you are using eval() there?
> __
> __ It's probably a misguided way of saying
> __
> __ $grate = ($gvalue / $last) * 100 if $last;
>
>
> Except of course that the latter can give you an "Illegal division by zero"
> error, since numeric context ain't the same as boolean context.
>
>
> $str = "700 00";
> ($gvalue, $last) =~ $str = /(\d+)\s+(\d+)/;
> $grate = ($gvalue / $last) * 100 if $last;
> __END__
> Illegal division by zero


Yes, they're not equivalent, but "...if $last" is the far more common
idiom, and it does the job for numeric data. The original code is too
botched to make out what to expect for $last. Then again, the OP also
has

$gvalue = eval { $curr - $last };

so it looks like the author used eval for no good reason at all.

Anno
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      12-08-2004
Abigail <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Anno Siegel ((E-Mail Removed)-berlin.de) wrote on MMMMCXVI
> September MCMXCIII in <URL:news:cp47no$d7l$(E-Mail Removed)-Berlin.DE>:
> __ Tad McClellan <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> __ > delfuego <(E-Mail Removed)> wrote:
> __
> __ [...]
> __
> __ > > $grate = eval { ($gvalue / $last) * 100 }; # growth rate percentage
> __ >
> __ >
> __ > Can you tell us why you are using eval() there?
> __
> __ It's probably a misguided way of saying
> __
> __ $grate = ($gvalue / $last) * 100 if $last;
>
>
> Except of course that the latter can give you an "Illegal division by zero"
> error, since numeric context ain't the same as boolean context.
>
>
> $str = "700 00";
> ($gvalue, $last) =~ $str = /(\d+)\s+(\d+)/;
> $grate = ($gvalue / $last) * 100 if $last;
> __END__
> Illegal division by zero


Yes, they're not equivalent, but "...if $last" is the far more common
idiom, and it does the job for numeric data. The original code is too
botched to make out what to expect for $last. Then again, the OP also
has

$gvalue = eval { $curr - $last };

so it looks like the author used eval for no good reason at all.

Oh, and... good to see you back.

Anno
 
Reply With Quote
 
James
Guest
Posts: n/a
 
      12-08-2004
Hi Jim,

Sorry to you and all other posters for my general usenet "Blurting". I
guess what I was dumping the code here for was in light of lacking the
ability to express the problem in theory. What is in general the
problem is maniipulating input and output through module functions,
namely Win32::Resources(GetDrives(), GetDriveSpace(), and ShowKeys()).
This was in fact a 'hacked' script, I was trying to use code originally
useful but directed toward tailor-made for my purposes. I will respond
more in-depth tonight.

Thanks again.

James

 
Reply With Quote
 
James
Guest
Posts: n/a
 
      12-08-2004
It was .. for some reason I had the misguided idea that each math
expression had to be in an eval. I don't know why.

 
Reply With Quote
 
James
Guest
Posts: n/a
 
      12-09-2004
Hi Tad,
> Please show *real code*!
> use lib "$ENV(HOME)/site/lib"; # occasionally perl whines about not
> ^ ^
> ^ ^ {HOME}


Tad thanks .. I did not catch that at all.

>> our $file = (<SD>,"growth.cvs"); # output data file
>> our $file2 = (<SD>,"machines.cvs"); # input data file

> Where is the SD filehandle open()ed?


I have to apologize to everyone and thank them at the same time, that
was a horrible version of my non-working script that was posted. A new
one was posted today. Under a MS-blah header.
I do not believe in hindsight that it was ever opened.

> Why are you using package variables instead of lexical variables?


This I will have to re-read on, I can't recall what the difference is
between them, but if I think I know what they are, I believe I was
using package variables because they were what I thought was necessary.

>> our $let = ['A-Z']; # character value for

drive letters
> You never make use of this variable, and it almost certainly
> is not what you think it is.


I thought it was used in a foreach for a loop control variable
associated with an array, but I could be wrong on that too. I was
trying to define a range of characters in a variable (which I guess
would have to be an array anyway).

> It is a reference to an anonymous array with 1 element in it.
> our @line = ""; # was going to be used for

file looping
> How may elements are you expecting to be in @line right here?
> Were you expecting zero elements, an empty array?
> That isn't what you are getting there...


I was expecting an empty array actually, or at least null values in
it.

>> open (file2,"+<"); # open machines input file for read

> You are opening for read AND write, the comment is a trick!
> Did you mean to put a filename in there somewhere?
> You should use UPPER CASE for filehandles.
> You should always, yes *always*, check the return value from open().


I thought the + was to keep it from being clobbered..I would have to
put a filename in there I guess, I thought it was defined up top with
the filehandle. I have taken your advice and started using uppercase
for all filehandles. Why does the return value matter? Wouldn't it
just open or fail (die)?
I generally (now) use ((|| -or- or) die) after the open.

>> while <file2> # loop while not eof in machines.cvs

> Syntax error.
> Show *real code*!
>> foreach $machine (<file2>)

> You are reading from the _same_ filehandle in 2 different places
> in your code. Is that what you want to do?
> The while loop (if it compiled) would only execute one time.
> The foreach provides list context, so it will slurp to the end of

file.

Man this script was a piece. I believe what I was trying to do was
loop through the machines listed by name in the file, does foreach only
provide list context?

>> chop ($last);

> That is how we removed newlines 8 years ago. Where did you learn

that?
> Nowadays you should use chomp() to remove newlines.


I am now using chomp(); I learned chop(); in an old NT book that had a
Perl script in it to do roughly the same thing.

>> $curr = %DRVSpace;

> This most certainly does not do what you think it does.
> The value of a hash in scalar context is not of interest to
> a Perl programmer, it is only of interest to a perl programmer.


So would it be $curr = /%DRVSpace to get the value of the key, or doyou
have to explicitly go through the (sort(keys /%DRVSpace);?

>> $last = eval { $curr / 5 }; # bogus value for testing, should be
>> $gvalue = eval { $curr - $last }; # growth rate difference
>> $grate = eval { ($gvalue / $last) * 100 }; # growth rate

percentage
> Can you tell us why you are using eval() there?


I thought eval was used for numeric expressions assigned to variables,
or maybe I'm confusing it with a bash statement?
Thanks for your time.

James

 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      12-09-2004
James <(E-Mail Removed)> wrote:

>> Please show *real code*!
>> use lib "$ENV(HOME)/site/lib"; # occasionally perl whines about not
>> ^ ^
>> ^ ^ {HOME}

>
> Tad thanks .. I did not catch that at all.



You should always enable warnings when developing Perl code!

warnings would have caught that mistake *for you*.

Take all the help you can get. Start your programs with:

use warnings;
use strict;


>> Why are you using package variables instead of lexical variables?

>
> This I will have to re-read on, I can't recall what the difference is
> between them,



See:

"Coping with Scoping":

http://perl.plover.com/FAQs/Namespaces.html


> but if I think I know what they are, I believe I was
> using package variables because they were what I thought was necessary.



I don't see anything that makes them necessary...


>>> our $let = ['A-Z']; # character value for

> drive letters
>> You never make use of this variable, and it almost certainly
>> is not what you think it is.

>
> I thought it was used in a foreach for a loop control variable
> associated with an array, but I could be wrong on that too.



$let contains a _reference_ to an anonymous array.


> I was
> trying to define



The array referenced by $let has ONE element in it,
a 3-character string "A", "-", "Z".


> a range of characters in a variable (which I guess
> would have to be an array anyway).



If you want the anon array to contain 26 elements then:

my $let = ['A' .. 'Z'];

but you have no need for an anon array at all, you can just
use the 26-element list right in the foreach

foreach my $letter ( 'A' .. 'Z' ) {
...
}


>> our @line = ""; # was going to be used for

> file looping
>> How may elements are you expecting to be in @line right here?
>> Were you expecting zero elements, an empty array?
>> That isn't what you are getting there...

>
> I was expecting an empty array actually, or at least null values in
> it.



It has ONE element in it. The value of the one element is the empty string.

If you wanted zero elements, then either of these will do it:

my @line; # contains empty list by default

my @line = (); # be unnecessarily explicit about the empty list


>>> open (file2,"+<"); # open machines input file for read

>> You are opening for read AND write, the comment is a trick!
>> Did you mean to put a filename in there somewhere?
>> You should use UPPER CASE for filehandles.
>> You should always, yes *always*, check the return value from open().

>
> I thought the + was to keep it from being clobbered..



It cannot be clobbered since your program never writes to that filehandle.


> Why does the return value matter?



Because it tells you whether you actually got what you asked for or not.


> Wouldn't it
> just open or fail (die)?



No. (so you should put the "or die" stuff in there yourself)

If you read from an unopen()ed filehandle, you get an immediate EOF,
it looks like the file is empty.

If you write to an unopen()ed filehandle, your output goes in
the bit bucket, ie. is lost.

warnings will complain for either of those cases, but you should
test the return value yourself so that you can exit more gracefully.


>>> while <file2> # loop while not eof in machines.cvs

>> Syntax error.
>> Show *real code*!



> Man this script was a piece.



Errr, right.

Have you seen the Posting Guidelines that are posted here frequently?


> does foreach only
> provide list context?



Yes.

Why do you ask?

Do you think you need something other than list context?


>>> $curr = %DRVSpace;

>> This most certainly does not do what you think it does.
>> The value of a hash in scalar context is not of interest to
>> a Perl programmer, it is only of interest to a perl programmer.

>
> So would it be $curr = /%DRVSpace to get the value of the key,



What happened when you tried it?


--
Tad McClellan SGML consulting
(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Unpack less values from function's return values Chris Rebert Python 1 05-28-2009 02:47 PM
Loops with loops using html-template Me Perl Misc 2 01-12-2006 05:07 PM
object loops and what they return Eric Mahurin Ruby 3 05-11-2005 10:38 PM
what value does lack of return or empty "return;" return Greenhorn C Programming 15 03-06-2005 08:19 PM
MS Perl question -- how to use hacked script to work correctly(was Question on loops and return values or sumpin) James Perl Misc 12 12-20-2004 04:15 PM



Advertisments