Need help on AoH or array or any other think that might help!

C

cyrusgreats

Hello good people out there. I need to write a perl script that will
parse the log and generate the following output:
a flat text file in the following format: customer_name|
product_category|item_description|cost
An example log file could be:
Pedro|groceries|apple|1.42
Nitin|tobacco|cigarettes|15.00
Susie|groceries|cereal|5.50
Susie|groceries|milk|4.75
Susie|tobacco|cigarettes|15.00
Susie|fuel|gasoline|44.90
Pedro|fuel|propane|9.60

1.A report of the total revenue resulting from each customer.
2.A report for each customer showing how much of their spending went
to each category.
With the above example log file, the script should output should be
something like:
Total Revenue:
Pedro - $11.02
Nitin - $15.00
Susie - $70.15

Purchases by Pedro:
groceries - $1.42
fuel - $9.60

Purchases by Nitin:
tobacco - $15.00

Purchases by Susie:
groceries - $10.25
fuel - $44.90
tobacco - $15.00


Any help will be appreciated...million thanks in advance
 
J

J. Gleixner

Hello good people out there. I need to write a perl script that will
parse the log and generate the following output:

What have you done so far and what questions do you have?
Any help will be appreciated...million thanks in advance

Put in some sort of effort by at least reading some
documentation, or maybe a book, and posting your code.

perldoc -f split
perldoc -f open
perldoc perldsc
 
J

Jürgen Exner

Hello good people out there. I need to write a perl script that will
parse the log and generate the following output:
a flat text file in the following format: customer_name|
product_category|item_description|cost
An example log file could be:
Pedro|groceries|apple|1.42
Nitin|tobacco|cigarettes|15.00
Susie|groceries|cereal|5.50
Susie|groceries|milk|4.75
Susie|tobacco|cigarettes|15.00
Susie|fuel|gasoline|44.90
Pedro|fuel|propane|9.60

perldoc -f split:
($customer, $category, undef, $price) = split ('|');

Then add the totals in hashes:
$byCategory{$customer}{$category} += $price;
$totals{$customer} += $price;
1.A report of the total revenue resulting from each customer.
2.A report for each customer showing how much of their spending went
to each category.

Walking through the hashes and printing the accumulated data should be
trivial now.

jue
 
C

cyrusgreats

What have you done so far and what questions do you have?


Put in some sort of effort by at least reading some
documentation, or maybe a book, and posting your code.

perldoc -f split
perldoc -f open
perldoc perldsc

here portion of the code:

my %inventory;
open (FILE, $file) || die ("Could not open file. $!");
foreach my $el (<FILE)>) {
($name, $category, $item, $price) = split ("|", $el);
my %s = (
'name'=>$name,
'product'=>$category,
'item'=>$item,
'price'=>$$price,
);
push @arr, \%s;
}

foreach $el (@$arr) {
$inventory{$el)->{'name'} = {name=>$el->{'name'}};
$inventory{$el)->{'product'} = {category=>$el->{'category'}};
$inventory{$el)->{'item'} = {item=>$el->{'item'}};
$inventory{$el)->{'price'} = {price=>$el->{'price'}};
}

Am I in right track?
 
T

Tim Greer

here portion of the code:

my %inventory;
open (FILE, $file) || die ("Could not open file. $!");
foreach my $el (<FILE)>) {

^^^ You should always copy and paste your actual code you're using. The
above is broken: ( said:
($name, $category, $item, $price) = split ("|", $el);

I don't think that's going to do what you want. Did you print the
output to ensure it's going to work how you want, before you save the
values into a hash. I'd start there, fixing those issues, before you
try and move onto saving the hash keys/values and processing against
it.
 
J

John W. Krahn

Jürgen Exner said:
perldoc -f split:
($customer, $category, undef, $price) = split ('|');

The '|' character is special in a regular expresion. If you want to
match a literal '|' character you have to escape it:

my ( $customer, $category, undef, $price ) = split /\|/;

Or:

my ( $customer, $category, $price ) = ( split /\|/ )[0,1,3];



John
 
J

Jürgen Exner

John W. Krahn said:
The '|' character is special in a regular expresion. If you want to
match a literal '|' character you have to escape it:

Ooops, you are right.

jue
 
J

J. Gleixner

Tim said:
^^^ You should always copy and paste your actual code you're using. The
above is broken: (<FILE)>)

Define 'broken'. It's not good code (OP use 'while' instead
of foreach), but it will run.
 
J

Jürgen Exner

J. Gleixner said:
Tim Greer wrote:

Define 'broken'. It's not good code (OP use 'while' instead
of foreach), but it will run.

It doesn't even parse (Tim pointed it out verbatim). I guess that
qualifies as broken by any sensible definition of broken.

jue
 
T

Tim Greer

J. Gleixner said:
Define 'broken'. It's not good code (OP use 'while' instead
of foreach), but it will run.

I am aware that a for/foreach and while can work equally well. Invalid
syntax, as shown above -> (<FILE)>) is what I define as "broken".
Better?
 
J

J. Gleixner

Tim said:
I am aware that a for/foreach and while can work equally well. Invalid
syntax, as shown above -> (<FILE)>) is what I define as "broken".
Better?

Sorry.. Yep. For some reason I totally missed that it wasn't (<FILE>).
Never mind.. :)
 
H

Hans Mulder

Jürgen Exner said:
It doesn't even parse (Tim pointed it out verbatim). I guess that
qualifies as broken by any sensible definition of broken.

It does parse: it's a file name glob. It doesn't contain any globbing
metacharacters, so it would be more efficient to write it as ('FILE)').
(Assuming you really want to loop over an array containing a single
constant string.)

I think a pragma disabling this meaning of the <> operator would be a
very good idea.

Hope this helps,

-- HansM
 
T

Tim Greer

Hans said:
It does parse:

It does not (it might without warnings, but it shouldn't otherwise, and
I seriously doubt this is what the OP wanted regarding results it would
have if you did run it). Yes, it will run (if you technically call it
running) assuming you don't have warnings enabled, and it will spit out
"FILE)" and end if you were just to output it (by the looks of it, as I
have no reason to run broken code to prove what it'll do). Either way,
it certainly wouldn't have the data it expected or to split on an
actual pipe (assuming that portion of the code is fixed, too).
it's a file name glob.

No, it's not. They opened a file with open(), and then did a loop on the
filehandle (FILE) and you assume it's a file name glob? I doubt it and
I doubt that's what the OP was intending. I can only assume you didn't
see the original post this was in response to, so I'll not go further
into this.
It doesn't contain any globbing
metacharacters,

Because it's not a glob.
so it would be more efficient to write it as
('FILE)'). (Assuming you really want to loop over an array containing
a single constant string.)

I think a pragma disabling this meaning of the <> operator would be a
very good idea.

Yikes... anyway...

Okay, so to end this discussion (I'm sorry I said anything at all), here
was the full (relevant) code piece they had posted (I'm copying and
pasting it below):

open (FILE, $file) || die ("Could not open file. $!");
foreach my $el (<FILE)>) {
  ($name, $category, $item, $price) = split ("|", $el);
   my %s = (
          'name'=>$name,
          'product'=>$category,
          'item'=>$item,
          'price'=>$$price,
       );
...
 }

...

You surely see the problem with (<FILE)>) now, right? As well as
split ("|", $el), I'm sure. I'll end that here, since I believe you
understand the issue now that you've seen the code this was in response
to.
 
T

Tim Greer

Tad said:
It does:

perl -MO=Deparse -e '(<FILE)>)'

use File::Glob ();
glob('FILE)');
-e syntax OK

It does not parse, with warnings enabled, in the code the OP posted.
Yes, of course it _parses_ when you take it out of context. And yes,
when you take it out of context, it *is* a glob. Of course, I was
saying it was invalid and broken in regard to their own code they
posted. Replying and taking that out of context saying that one single
part of code does parse, is kind of a weak argument (and I don't see
the reason for an argument).
That part is probably correct though.

You think?
Yes it is.

Yeah, but not _intentionally_ and _not_ in the code the OP posted. Yes,
it _is_ an unintentional glob in their code, which (when in their code)
doesn't parse.
It was not *meant* to be a file name glob,

Exactly, and just saying it is not incorrect code and parses, all
because that's how it reads from a typo in the OP's code, is hardly
reason to call it what it _could_ be if taken out of context. If you
want to sarcastically say "but it is" for that reason, then so be it,
but I don't see the point and it absolutely doesn't apply to what I
said in direct response to their posted code.
but the typo it contains
just happens to result in a valid syntax.

Right. And, like I said, in their code it's broken and their intention
was not to have a glob. Why do you feel the need to argue about it?
There is no need to assume. We can simply ask perl, as above.

Yeah, so "ask perl" by using their originally posted code, as is. Then,
for to endless sake of making a point about a portion of code taken out
of context to prove a trivial and irrlevant point, please post and tell
me I'm wrong and that it does parse. Yeah, no kidding, when you take
it out of the broken code and apply it in a manner which you can
rightfully call it a glob and make it parse. Are you bored?
Everybody gets to be wrong once in a while, now is your turn, I guess.

Everyone has someone attack them and accuse them of being wrong on this
newsgroup without provocation once in a while, now it is my turn, I
guess.
Thank heavens!

Indeed, we can't have someone make a relevant point about the actual
reply they made, else you might not be able to find a reason to mock
someone here for no reason. It's not that I don't appreciate your
efforts, and please excuse me for trying to be a part of this newgroup
by showing respect and posting relevant replies, only to have a regular
rip into me for it, all for the sake of what, exactly? What explains
this attitude? Once again, my reply was correct and relevant to the
OPs code, I didn't say that the same code (taken out of context)
couldn't be technically something else or parse, now did I? Have I
done something to offend you?
Yes it is.

Due to a typo and that was the _point_ of asking the OP to post the
actual code used, because none of this is relevant other than egoism
and nitpicking about a matter that is nothing more than a typo. Big
deal if it turned out to be a glob because of a typo, it wouldn't have
worked in their code, and it wouldn't parse. Talk about circular
logic! There's really just no way out of this, because it's easier to
just dismiss the historical and logical path the thread here took.
Fine.
He was not commenting on the problem with (<FILE)>), so
that is not relevant.

He was commenting in response to my statement that the code was broken
(which it is), and regardless of what you want to take out of context
to argue a trivial point, I reiterated to him how it actually would
_not_ parse. I never argued that, if taken out of context, that it
couldn't be a glob (or wasn't), I said it wasn't in what the user
intended.
He was commenting on the "doesn't even parse" statement, as it
clearly *does* parse.

But, it _doesn't_ parse -- not in the code the OP posted. Twist it
anyway you want, but that's all I said (because the reply was in regard
to that and that is what my follow-up was about). If you want to take
it out of context or find a way to make it fit, fine, but for the code
the OP posted, it _does not_ parse

That's all I said (in regard to that, not him taking a portition of code
out of context to say it's not broken, when it clearly is). If someone
can't point out the obvious brokenness in the code someone posts and
ask them to please post the actual code without this sort of nonsense,
then why even pretend you have any respect for anyone else here?
 
T

Tad J McClellan

Tim Greer said:
It does not parse, with warnings enabled, in the code the OP posted.


warnings have no effect on compilation.

If it parses with warnings enabled, it will parse without warnings enabled.

If it does not parse with warnings enabled, it will not parse without
warnings enabled.

Yes, of course it _parses_ when you take it out of context.


It (the 1st foreach loop) parses even when in context.

--------------------------
temp> perl -MO=Deparse <<'ENDCODE'
my %inventory;
open (FILE, $file) || die ("Could not open file. $!");
foreach my $el (<FILE)>) {
($name, $category, $item, $price) = split ("|", $el);
my %s = (
'name'=>$name,
'product'=>$category,
'item'=>$item,
'price'=>$$price,
);
push @arr, \%s;
}
ENDCODE
my %inventory;
die "Could not open file. $!" unless open FILE, $file;
use File::Glob ();
foreach my $el (glob('FILE)')) {
($name, $category, $item, $price) = split(/|/, $el, 5);
my(%s) = ('name', $name, 'product', $category, 'item', $item, 'price', $$price);
push @arr, \%s;
}
- syntax OK
--------------------------

"syntax OK" means it did parse successfully.

[ There is a syntax error in the 2nd foreach loop that the OP posted
(an "=>" instead of an "->").
]

Yes,
it _is_ an unintentional glob in their code,


We are all in agreement then. Good.

If you
want to sarcastically say "but it is" for that reason, then so be it,


I meant no sarcasm. Honestly.

Whether it parses or not is not a matter of opinion, you submit
the tokens to the parser, if the parser accepts it, then it
has been parsed successfully.

Right. And, like I said, in their code it's broken and their intention
was not to have a glob. Why do you feel the need to argue about it?


You said:

Invalid syntax, as shown above -> (<FILE)>)

but that _is_ valid syntax.

I am not arguing about it.

I am trying to repair an incorrect statement.

Yeah, so "ask perl" by using their originally posted code, as is.


See above.

Everyone has someone attack them and accuse them of being wrong on this
newsgroup without provocation once in a while, now it is my turn, I
guess.


I am not attacking you.

I am attacking the incorrect statement that you made.

Once again, my reply was correct


The one I've quoted above was not correct.

I corrected it.
 
T

Tim Greer

Tad said:
warnings have no effect on compilation.

Right, okay, so then his code wasn't broken in your view. I don't
really know how to respond to that, but whatever means you wish to use
to make your point...
If it parses with warnings enabled, it will parse without warnings
enabled.

If it does not parse with warnings enabled, it will not parse without
warnings enabled.

Okay, poor choice of words. Yeah, it'll "parse". Still, broken is
broken.
We are all in agreement then. Good.




I meant no sarcasm. Honestly.

Whether it parses or not is not a matter of opinion, you submit
the tokens to the parser, if the parser accepts it, then it
has been parsed successfully.

I fully understand that Perl doesn't know what the user wants. All I
said was his code was broken, and you're right, it will parse.
You said:

Invalid syntax, as shown above -> (<FILE)>)

but that _is_ valid syntax.

I am not arguing about it.

I am trying to repair an incorrect statement.

Fair enough.
See above.




I am not attacking you.

I am attacking the incorrect statement that you made.

Fine. My point was that it was broken code. The word I used later to
describe in what way it was broken was not an accurate statement.
The one I've quoted above was not correct.

I corrected it.

Some people need a better sense of humor.
 

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