Stuart White wrote:
>
> > Conceptually, what you have is a tree. There are
> > three
> > branches from the root, one for each foul type, and
> > each of these is split into a further three
> > branches,
> > one for each player.
> >
>
> Like this:
>
>                  -->Rodriguez{numFouls}
>      -->offensive-->Chan{numFouls}
>                  -->Smith{numFouls}
>
>                 -->Rodriguez{numFouls}
> fouls-->personal-->Chan{numFouls}
>                 -->Smith{numFouls}
>
>                 -->Rodriguez{numFouls}
>      -->shooting-->Chan{numFouls}
>                 -->Smith{numFouls}
>
> That's what I conceptually see, and what I think it
> should be.

That's about it. Your notation isn't consistent
but I shouldn't worry about that.

> > Internally what you have is a hash, %fouls, which
> > relates
> > foul types (as the hash keys) to hash references (as
> > the
> > values). Each of these references refer to a hash
> > which
> > relates player names (as the keys) to foul count (as
> > the values).
> >
>
> internally, that looks like this, right?
> $fouls{offensive}{Chan}
>
> then substitute the foultype and the player name for
> the 8 other options.

Well, that's just the syntax for extracting a single
count from the structure. You need to understand that

    $fouls{offensive}

is a hash reference. That's why I suggested Dumper.

>
> > It may be helpful to do this
> >
> >   use Data::Dumper;
> >   print Dumper \%fouls;
> >
>
> the call to print is after I've written the hash,
> right?  and the use Data::Dumper;  is just like typing
> use strict; right?  I don't have to do anything else
> with that I suppose?

Yes. Put 'use Data::Dumper' anywhere before you first
use it, and 'print Dumper \%fouls' after you've populated
the hash.

>
> I actually did something like this when I had 1-d
> hashes, but six of them, one for every different
> foul(for simplicity's sake, I've just written names of
> 3 diff kinds of fouls), but then I thought I'd have to
> write a bunch of lines like you wrote for the 2-d
> hash, which I thought would be cumbersome, since there
> are plenty of different names.

I wrote it that way so that it produced exactly the output
that you proposed. The list of foul types is just
the list of keys for the %fouls hash,so you could write

  foreach (keys %fouls) {
    :
  }

> I had something like:
> if ($3 eq 'Offensive')
> {
>  $offensive{$1}++;
> }
>
> That's when he suggested that I didn't have to match
> $3 or $1 to anything, and so sent me on a chase to
> figure out how.  That's how I came up with the thought
> that I'm not matching the name in the example above
> ($1) so perhaps I could write a line like so:
> $fouls{$3}{$1}++;
> and that would do the same thing if wrote:
>
> if ($1 eq 'Chan' and $3 eq 'offensive')
> {
>  $fouls{$3}{$1}++;
> }
> or something like that.
> So this is what I'd like to do, count fouls without
> using string comparison operators.

You're getting confused between variables and data here.
$1, $3, $player, $type etc are all just scalar variables
(except that you can't set $1 .. $9 yourself. Perl
hash to set them from a regex.)

What you're trying to write above is

  if ($1 eq 'Chan' and $3 eq 'offensive') {
    $fouls{offensive}{Chan}++;
  }

but then you have to replicate this for every combination
of player and foul type, which also means that you have to
know what valid values to expect. This may be the case here,
when you know what foul types are possible, but you don't
want to have to change the program when the team members
change.

I hope you can see that this is the same as

  $fouls{$3}{$1}++;
or
  $fouls{$player}{$type}++;

without having to test the contents of the variables at
all.


> > > I'm getting confused by the variable
> > > names and what each represent since the $1 or the $3
> > > isn't in there.
> >
> > Scalar $type holds the foul type. The same as $3 on
> > input.
> > Scalar $player holds the player name. The same as $1
> > on input.
> >
>
> Yes, but was supposed to assume that further up in the
> code I would have assigned $1 to $player, and $3 to
> $type?  That's where a lot of my confusion came from.

No. Forget about $1 and $3 once you've read your data
into the hash. If you want particular values out of the
data you can hard-code them like this:

  foreach my $type ( qw/Offensive Personal Shooting/ ) {
    my $rank = $fouls{lc $type};
    :
  }

or, if you just want all the data in the hash, in no
particular order


  foreach my $type ( keys %fouls ) {
    my $rank = $fouls{lc $type};
    :
  }

> Then, what does $rank refer to?  Wait, it looks like
> it is assigned to $fouls{$type}

Yes.

> so then $rank would have a key of foultype, and a
> value of player name which is also a key and would
> have a value of the number of fouls?  Is that it?


Careful now! $rank is a scalar variable,and happens
to be a hash reference. Going back to the diagram,
you've plucked one of the three first level branches
off the tree and put it into $rank. The hash it
references has the three player names as keys and
their foul counts as values.

> and I'm not familiar with this syntax:
> %$rank

If $rank is a hash reference, then %$rank is the
hash it refers to.

> > > Also, can I do it without the reference?
> >
> > You can do it without the hash reference but it
> > looks more
> > confusing that way. You can't get around the fact
> > that the
> > level 2 hashes are anonymous ones so you need to
> > understand
> > references.
> >
>
> I asked because I'm still moving in baby steps here.
> :)  References are next.

You can't have multi-dimensional hashes without using
references. You can hide the fact that they're
references to some extent, but to do anything useful
you have to know how to handle references to manipulate
the second level and below.

> Before this would work, I'd have to assign $3 to
> $type and $1 to $player, right?

No. This is back to the distinction between data and
variables, and between building and using the hash.

The regex puts the player name into scalar $1 when you're
populating the hash. The 'foreach' loop puts sets $player
to the keys (player names) that are in the hash for which you
want to access the values.

> >   foreach my $type ( qw/Offensive Personal Shooting/
> > ) {
> >     printf "%s fouls\n", $type;
> >     foreach my $player ( keys %{$fouls{$type}} ) {
> >       printf "%s: %d\n", $player,
> > $fouls{$type}{$player};
> >     }
> >   }
> >

Time to go and play with hashes for a while! Start with
the simplest imaginable hash

    my %hash;
    $hash{A} = 1;

and dump it. Then add additional data, then additional
levels, and get a feel for what the operations are doing.

Cheers,

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to