Sum the middle column for a given unique volser.

N

Noatec

If I have a data set like the one below.
1st column = tape volser.
2nd column = the number of reads in the last hour.
3rd column = the last write date.
I need to sum the 2nd column for each unique volser and spit out
volser,sum,last write date.
Would anyone be interested in helping me incorporate the hash?

Sample Data:
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,2,2003-08-22
300000,2,2003-08-22
300000,2,2003-08-22
300000,2,2003-08-22
300000,3,2003-08-22
300000,3,2003-08-22
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
So on an so forth for 1500 volsers.

This is all I have so far.
#!/usr/bin/perl
use warnings;
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);


printf "$volser $reads $lwd"
}

# close the file
close(MLIST);
 
P

Paul Lalli

Noatec wrote:

[[ snip the same problem description as posted in
http://groups.google.com/group/perl...5f7d9ea1837?lnk=st&q=&rnum=1#5fed15f7d9ea1837
]]

This is all I have so far.

No, that's what someone else was gracious enough to GIVE you.
#!/usr/bin/perl
use warnings;
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);


printf "$volser $reads $lwd"
}

# close the file
close(MLIST);

If you didn't understand the code you were given, why didn't you ask
the person who gave it to you for a clarification? Why are you now
posting in a completely different group, pretending that you came up
with this on your own?

Paul Lalli
 
P

Paul Lalli

Paul said:
Noatec wrote:

[[ snip the same problem description as posted in
http://groups.google.com/group/perl...5f7d9ea1837?lnk=st&q=&rnum=1#5fed15f7d9ea1837
]]

This is all I have so far.

No, that's what someone else was gracious enough to GIVE you.
#!/usr/bin/perl
use warnings;
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);


printf "$volser $reads $lwd"
}

# close the file
close(MLIST);

If you didn't understand the code you were given, why didn't you ask
the person who gave it to you for a clarification? Why are you now
posting in a completely different group, pretending that you came up
with this on your own?

Bah. I completely misread the thread I referenced above. The code
posted is what the OP posted there as well. My apologies. However, my
question still stands as to why you are suddenly jumping groups and
asking for a fresh start rather than following up to that thread.
Someone there did help you out with putting your data into a hash. If
you don't understand that code, ask about it there.

Paul Lalli
 
N

Noatec

Paul said:
Paul said:
Noatec wrote:

[[ snip the same problem description as posted in
http://groups.google.com/group/perl...5f7d9ea1837?lnk=st&q=&rnum=1#5fed15f7d9ea1837
]]

This is all I have so far.

No, that's what someone else was gracious enough to GIVE you.
#!/usr/bin/perl
use warnings;
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);


printf "$volser $reads $lwd"
}

# close the file
close(MLIST);

If you didn't understand the code you were given, why didn't you ask
the person who gave it to you for a clarification? Why are you now
posting in a completely different group, pretending that you came up
with this on your own?

Bah. I completely misread the thread I referenced above. The code
posted is what the OP posted there as well. My apologies. However, my
question still stands as to why you are suddenly jumping groups and
asking for a fresh start rather than following up to that thread.
Someone there did help you out with putting your data into a hash. If
you don't understand that code, ask about it there.

Paul Lalli

Paul,
Thanks for taking another look at the post.
I was unable to get the provided code to work right.

my %volsers=();
for my $line (split(/\n/, $data)){
my ($volser, $reads, $date) = split(/\,/,$line);
$volsers{$volser}{reads}+=$reads;
$volsers{$volser}{date}=$date;

Just was just looking for another perspective on the problem.
 
P

Paul Lalli

Noatec said:
Thanks for taking another look at the post.
I was unable to get the provided code to work right.

That is a horrible error description. How is it not "working right"
for you? What errors are you seeing? Syntax errors? Runtime errors?
Incorrect output? No output? Infinite loop? Crash? Computer bursts
into flames?
my %volsers=();
for my $line (split(/\n/, $data)){
my ($volser, $reads, $date) = split(/\,/,$line);
$volsers{$volser}{reads}+=$reads;
$volsers{$volser}{date}=$date;


Other than the missing } that I assume you missed when copying, there's
nothing wrong with that code. Therefore, there's something wrong with
your usage of it. Please post a SHORT but COMPLETE script that
demonstrates the problem you're seeing.
Just was just looking for another perspective on the problem.

How can anyone have a different perspective when you haven't told
anyone what's wrong with this perspective?

Paul Lalli
 
J

J. Gleixner

Noatec said:
Paul said:
Paul said:
Noatec wrote:

[[ snip the same problem description as posted in
http://groups.google.com/group/perl...5f7d9ea1837?lnk=st&q=&rnum=1#5fed15f7d9ea1837
]]


This is all I have so far.
No, that's what someone else was gracious enough to GIVE you.

#!/usr/bin/perl
use warnings;
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);


printf "$volser $reads $lwd"
}

# close the file
close(MLIST);
If you didn't understand the code you were given, why didn't you ask
the person who gave it to you for a clarification? Why are you now
posting in a completely different group, pretending that you came up
with this on your own?
Bah. I completely misread the thread I referenced above. The code
posted is what the OP posted there as well. My apologies. However, my
question still stands as to why you are suddenly jumping groups and
asking for a fresh start rather than following up to that thread.
Someone there did help you out with putting your data into a hash. If
you don't understand that code, ask about it there.

Paul Lalli

Paul,
Thanks for taking another look at the post.
I was unable to get the provided code to work right.

my %volsers=();
for my $line (split(/\n/, $data)){
What's $data??
my ($volser, $reads, $date) = split(/\,/,$line);
Why escape the comma??
$volsers{$volser}{reads}+=$reads;
$volsers{$volser}{date}=$date;

maybe replace those with:

$volsers{$volser}{$date}{'read'} += $reads;
}
Just was just looking for another perspective on the problem.

That doesn't look like the code you originally posted. Please post your
actual code; something that others can run, as is, to help pinpoint the
problem.
 
N

Noatec

Paul said:
That is a horrible error description. How is it not "working right"
for you? What errors are you seeing? Syntax errors? Runtime errors?
Incorrect output? No output? Infinite loop? Crash? Computer bursts
into flames?



Other than the missing } that I assume you missed when copying, there's
nothing wrong with that code. Therefore, there's something wrong with
your usage of it. Please post a SHORT but COMPLETE script that
demonstrates the problem you're seeing.


How can anyone have a different perspective when you haven't told
anyone what's wrong with this perspective?

Paul Lalli

Paul,
Are you always this critical of people who are trying to learn?
I wouldn't think a teacher of technology would want to turn people off
of learning a new language.
Your posts are very condescending and borderline rude.

I'm truly not looking for someone to solve this for me.
I really want to learn it.

I'm trying to incorporate the hash into this working code that will
simply list every row.
I don't know what $data should be.
#!/usr/bin/perl
use warnings;
#my $line = $ARGV[0];
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);
printf "$volser,$reads,$lwd"
}

# close the file
close(MLIST);
 
P

Paul Lalli

Are you always this critical of people who are trying to learn?

You do not appear to be trying to learn. You appear to be wanting
someone to do your work for you.
I wouldn't think a teacher of technology would want to turn people off
of learning a new language.

You are not trying to learn. And as for "teacher of technology",
you're not one of my students. You're a guy posting to Usenet looking
for a freebie.
Your posts are very condescending and borderline rude.

No, I've passed beyond borderline now, and I'm definately being
flat-out rude. That's because your method of posting and asking
questions has been at least equally rude. You post a question to one
list, and got an answer. Rather than following up with that question,
you posted to another group, made no mention of the answer you already
got, and posted no further attempt to solve the problem based on the
answer you already got. Then when someone confronts you on it, you
simply say "it didn't work", with no attempt to explain in what way it
didn't work, or show the attempt you made that lead to it "not
work"ing. That is an astonishing amount of time of other people which
you have wasted. That is extremely rude.
I'm truly not looking for someone to solve this for me.
I really want to learn it.

Then why haven't you posted your best attempt? How can anyone correct
it for you? Why haven't you posted any specific questions beyond "How
do I do this?"?
I'm trying to incorporate the hash into this working code that will
simply list every row.
I don't know what $data should be.

So why didn't you ask that in the first place? Why have you wasted all
this time making people guess as to your level of understanding? If
you didn't understand what the code you were given is doing, why didn't
you ask about that code?
#!/usr/bin/perl

You forgot:
use strict;
use warnings;
#my $line = $ARGV[0];
my $line = mlist;

What the hell is this? Is this a function? Is it a bareword string?
Where did it come from, and what does it represent?
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

perldoc -q quoting

So $line is supposed to be the name of the file you want to open?
Doesn't that seem to be a REALLY bad variable name to you?

Change those two lines to:
my $filename = 'mlist';
open my $MLIST, '<', $filename or die "Unable to open $filename: $!\n";
# read it in one record at a time
while ($line = <MLIST>) {

Now you're using $line for something completely different. Granted,
here $line makes sense.

while (my $line = said:
my ($volser,$reads,$lwd) = split(/,/,$line);

So now you have your three variables. So now put them into the hash
the way it was explained to you already. The only difference is that
while you called the line from the file $line, the poster who gave you
that code called it $data.
printf "$volser,$reads,$lwd"
}

# close the file
close(MLIST);

Now loop through the keys of the hash and print out the values.

Once you've actually made an ATTEMPT to do this, if it doesn't work,
post a SHORT but COMPLETE script that demonstrates your error.

Paul Lalli
 
M

Mumia W.

If I have a data set like the one below.
1st column = tape volser.
2nd column = the number of reads in the last hour.
3rd column = the last write date.
I need to sum the 2nd column for each unique volser and spit out
volser,sum,last write date.
Would anyone be interested in helping me incorporate the hash?

Sample Data:
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,1,2003-08-22
300000,2,2003-08-22
300000,2,2003-08-22
300000,2,2003-08-22
300000,2,2003-08-22
300000,3,2003-08-22
300000,3,2003-08-22
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
300001,1,2003-04-21
So on an so forth for 1500 volsers.

This is all I have so far.
#!/usr/bin/perl
use warnings;
my $line = mlist;
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

# read it in one record at a time
while ($line = <MLIST>) {
my ($volser,$reads,$lwd) = split(/,/,$line);


printf "$volser $reads $lwd"
}

# close the file
close(MLIST);

First, make sure you know how hashes and hashes of arrays
work. Read and understand "perldoc perldsc"

Put each volser in a hash. Each volser has two bits of
information you need the program to remember about it: the
count of accesses and the last access date.

The only way to store multiple pieces of data in a hash value
is to use an anonymous array, so you would need to put the
count of accesses and the last access date in an anonymous
array when you assign to the hash.

On each iteration of the while loop, the count of accesses
would be added to, and the last access date would be set to
the latest seen so far.

I've already written most of the program, so I know it works.

BTW, if a poster is consistently rude to you, there is no need
to read that person's posts.
 
N

Noatec

Paul said:
Are you always this critical of people who are trying to learn?

You do not appear to be trying to learn. You appear to be wanting
someone to do your work for you.
I wouldn't think a teacher of technology would want to turn people off
of learning a new language.

You are not trying to learn. And as for "teacher of technology",
you're not one of my students. You're a guy posting to Usenet looking
for a freebie.
Your posts are very condescending and borderline rude.

No, I've passed beyond borderline now, and I'm definately being
flat-out rude. That's because your method of posting and asking
questions has been at least equally rude. You post a question to one
list, and got an answer. Rather than following up with that question,
you posted to another group, made no mention of the answer you already
got, and posted no further attempt to solve the problem based on the
answer you already got. Then when someone confronts you on it, you
simply say "it didn't work", with no attempt to explain in what way it
didn't work, or show the attempt you made that lead to it "not
work"ing. That is an astonishing amount of time of other people which
you have wasted. That is extremely rude.
I'm truly not looking for someone to solve this for me.
I really want to learn it.

Then why haven't you posted your best attempt? How can anyone correct
it for you? Why haven't you posted any specific questions beyond "How
do I do this?"?
I'm trying to incorporate the hash into this working code that will
simply list every row.
I don't know what $data should be.

So why didn't you ask that in the first place? Why have you wasted all
this time making people guess as to your level of understanding? If
you didn't understand what the code you were given is doing, why didn't
you ask about that code?
#!/usr/bin/perl

You forgot:
use strict;
use warnings;
#my $line = $ARGV[0];
my $line = mlist;

What the hell is this? Is this a function? Is it a bareword string?
Where did it come from, and what does it represent?
my $sum = 0;

# open the file
open(MLIST,"$line") or die "Unable to open mlist:$!\n";

perldoc -q quoting

So $line is supposed to be the name of the file you want to open?
Doesn't that seem to be a REALLY bad variable name to you?

Change those two lines to:
my $filename = 'mlist';
open my $MLIST, '<', $filename or die "Unable to open $filename: $!\n";
# read it in one record at a time
while ($line = <MLIST>) {

Now you're using $line for something completely different. Granted,
here $line makes sense.

while (my $line = said:
my ($volser,$reads,$lwd) = split(/,/,$line);

So now you have your three variables. So now put them into the hash
the way it was explained to you already. The only difference is that
while you called the line from the file $line, the poster who gave you
that code called it $data.
printf "$volser,$reads,$lwd"
}

# close the file
close(MLIST);

Now loop through the keys of the hash and print out the values.

Once you've actually made an ATTEMPT to do this, if it doesn't work,
post a SHORT but COMPLETE script that demonstrates your error.

Paul Lalli

HOLY CRACKERS !!!!!!!
You really made me angry !!!!
I thought about what you said; took some time to cool off and I'm fine
now.
Honestly, I'll bet you're probably not the prick you come off to be in
this medium.

At any rate, to prove that I am trying to learn, I'll stick with the
abrasive critique and post my findings tomorrow.
I kinda like the tough love thing.

Good Evening.
 
T

Tad McClellan

[ snip 150 quoted lines. Please learn how to compose a proper followup. ]

HOLY CRACKERS !!!!!!!
You really made me angry !!!!
I thought about what you said; took some time to cool off and I'm fine
now.


You really should see the Posting Guidelines that are posted
here frequently.

Honestly, I'll bet you're probably not the prick you come off to be in
this medium.


Do you want people to help you or to ignore all of your future posts?

Act accordingly.

I kinda like the tough love thing.


Then you will learn a whole lot about Perl programming here.
 
N

Noatec

Tad said:
[ snip 150 quoted lines. Please learn how to compose a proper followup. ]

HOLY CRACKERS !!!!!!!
You really made me angry !!!!
I thought about what you said; took some time to cool off and I'm fine
now.


You really should see the Posting Guidelines that are posted
here frequently.

Honestly, I'll bet you're probably not the prick you come off to be in
this medium.


Do you want people to help you or to ignore all of your future posts?

Act accordingly.

I kinda like the tough love thing.


Then you will learn a whole lot about Perl programming here.

Hello everyone,
First of all thanks for all your help and patients.
I applogize for the rough start.
I took some extra time to review the perldocs and my reference book on
hashes in detail. ( I can hear the cheers from here.)

This is what I came up with.
#!/usr/bin/perl
use strict;
use warnings;

my $thresh = $ARGV[0];
my $filename = 'mlist';
my $sum = 0;
my $line='';
my $reads='';
my $volser='';
my $tmp_vol = '';

# open the file
open my $MLIST, '<', $filename or die "Unable to open $filename: $!\n";

# load the hash
my %hash=();
while (my $line = <$MLIST>) {
my ($volser, $reads, $date) = split(/,/,$line);
if ($tmp_vol eq ''){
$tmp_vol=$volser;
}
$hash{$volser}{reads}+=$reads;
$hash{$volser}{date}=$date;
if ($tmp_vol != $volser) {
if ($hash{$tmp_vol}{reads} <= $thresh) {
print "$tmp_vol $hash{$tmp_vol}{reads} $date";
}
$tmp_vol=$volser;
}
}

#close the file
close($MLIST);

I added the threshold since I only care about tapes with less than x
reads.
The next step is to add some date logic to calculate whether three
years has past since the last write date.
I'm very interested in your critique of this.
Is there a way to do it better, faster or shorter?
 
T

Tad McClellan

Noatec said:
Tad McClellan wrote:


Pleeaaase learn the proper way to compose a followup.

Do not quote an entire article.

Do not quote .sigs.

Interleave your comments following the quoted text that
you are commenting on.

Thank you.

First of all thanks for all your help and patients.


Some of us are patients, but we don't generally admit it in public.

Many of us have patience.

:)

if ($tmp_vol eq ''){
$tmp_vol=$volser;


Whitespace is not a scarce resource, feel free to use as much of it
as you like in order to make your code easier to read and understand.

One good place to put spaces is around operators.

You can replace that if() and its block with:

$tmp_vol = $volser unless length $tmp_vol;

if ($tmp_vol != $volser) {
if ($hash{$tmp_vol}{reads} <= $thresh) {
print "$tmp_vol $hash{$tmp_vol}{reads} $date";
}
$tmp_vol=$volser;
}
}


Something horrid has happened to your code formatting.

Surely it isn't really formatted like this, is it?

If so, then learn and adopt a sensible coding style. It will help
both you and everybody else who has to look at your code. See:

perldoc perlstyle
 
P

Paul Lalli

Noatec said:
First of all thanks for all your help and patients.
I applogize for the rough start.
I took some extra time to review the perldocs and my reference book on
hashes in detail. ( I can hear the cheers from here.)

This is what I came up with.
#!/usr/bin/perl
use strict;
use warnings;

GOOD!!


my $thresh = $ARGV[0];
my $filename = 'mlist';
my $sum = 0;
my $line='';
my $reads='';
my $volser='';
my $tmp_vol = '';

Do not do this.
For one, do not declare your variables until they are needed. That
will create them in the smallest scope possible, helping use strict; to
tell you when you've done things wrong, and also preventing the need to
scan your entire source file to find all the times the variable might
have changed.
For two, do not pre-initialize variables to defined values. Perl has a
default value. It's called 'undef'. And when you use a variable
before you meant to, 9 times out of 10, Perl will be able to warn you
about it. By initializing those variables before you have any reason
to, Perl assumes you know what you're doing and doesn't warn you.
# open the file
open my $MLIST, '<', $filename or die "Unable to open $filename: $!\n";
Good!!


# load the hash
my %hash=();

Again, no need for the initialization. `my %hash;` will do fine.
Also, consider finding better names for your variables. The % already
tells you that it's a hash. Name it something tells you what the
variable contains.
while (my $line = <$MLIST>) {

Are you sure you want a newline on the end of that line? I don't know,
maybe you do. But if not,
chomp $line;
my ($volser, $reads, $date) = split(/,/,$line);
if ($tmp_vol eq ''){
$tmp_vol=$volser;

$tmp_vol = $volser unless defined $tmp_vol;

Please fix your indentation. I've cleaned it up below, because I can't
parse it otherwise.
$hash{$volser}{reads}+=$reads;
$hash{$volser}{date}=$date;
if ($tmp_vol != $volser) {
if ($hash{$tmp_vol}{reads} <= $thresh) {
print "$tmp_vol $hash{$tmp_vol}{reads} $date";
}
$tmp_vol=$volser;
}
}

#close the file
close($MLIST);

I added the threshold since I only care about tapes with less than x
reads.
The next step is to add some date logic to calculate whether three
years has past since the last write date.
I'm very interested in your critique of this.
Is there a way to do it better, faster or shorter?

Other than the comments I've already made, looks decent to me. What
are $volser and $tmp_vol. As in, are they strings or integers or
other? Depending on the data, it might be possible to use arrays
(which are sorted by nature) and eliminate the whole "checking to see
if $x is not the same as the last $x" bit.

Paul Lalli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top