Re: some suggestions

2012-03-23 Thread Chris Stinemetz
Thank you everyone. I'm still digesting this, but I do have a better
understanding.

Chris

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




some suggestions

2012-03-22 Thread Chris Stinemetz
I would like to use the number on the left as a key in a hash and use
the number on the right as the value pair to the key. Then print the
values for each hour that have the same key. Maybe this is a good
example for an array of hashes, but I not real sure how to begin. Any
help is greatly appreciated.

Below is the input data:

Hr 12
0001 2
0002 3
0003 1
Hr 13
0001 2
0002 3
0003 1
Hr 14
0001 2
0002 3
0003 1

Desired output below:

  12 13 14
00012   2  2
00023   3  3
00031   1  1

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




Re: some suggestions

2012-03-22 Thread Jim Gibson
On 3/22/12 Thu  Mar 22, 2012  2:23 PM, Chris Stinemetz
chrisstinem...@gmail.com scribbled:

 I would like to use the number on the left as a key in a hash and use
 the number on the right as the value pair to the key. Then print the
 values for each hour that have the same key. Maybe this is a good
 example for an array of hashes, but I not real sure how to begin. Any
 help is greatly appreciated.
 
 Below is the input data:
 
 Hr 12
 0001 2
 0002 3
 0003 1
 Hr 13
 0001 2
 0002 3
 0003 1
 Hr 14
 0001 2
 0002 3
 0003 1
 
 Desired output below:
 
   12 13 14
 00012   2  2
 00023   3  3
 00031   1  1

I would suggest using a hash-of-hashes. You have a two-level key: the first
(primary) key is the hour value: 12, 13, 14. The second (-ary) key is the
number from the left-hand column. The value is the number from the
right-hand column.

So read the file, save the hour keys in a variable (e.g. $hour), extract the
two numbers (e.g. $left, $right), and store the values in a two-level hash:

$hash{$hour}{$left} = $right;

Then, when you have read the entire file, print the data in your desired
format. 

The printing will be a little tricky as you are inverting your data with
respect to the keys, so you can't do a simple two-level traversal over the
nested hashes and print as you go.

If all you want is to print as shown, then you can invert the importance of
the keys and use this instead:

$inverted_hash{$left}{$hour} = $right;

Then you can traverse the left numbers and print the hour values for
each one.

Sometimes the trick for effective programming is defining the right data
structure.



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




Re: some suggestions

2012-03-22 Thread Shawn H Corey

On 12-03-22 05:23 PM, Chris Stinemetz wrote:

but I not real sure how to begin. Any
help is greatly appreciated.

Below is the input data:

Hr 12
0001 2
0002 3
0003 1
Hr 13
0001 2
0002 3
0003 1
Hr 14
0001 2
0002 3
0003 1

Desired output below:

   12 13 14
00012   2  2
00023   3  3
00031   1  1


The first question you should ask yourself when you need to write a 
script that manipulates data is: Is preserving the input order of the 
data important? If so, the using an array is the easiest way to do this. 
In this case, however, the objective is to rearrange the data, so we are 
free to use any data structure to hold the data.


The second question is: What is the best data structure for this task? 
The possibilities fall into three categories: one similar to the input 
structure, one similar to the output, and some intermediate one. The 
advance of the first is that it will take little processing of the input 
to achieve it but more processing of the output. The second choice is 
the same as the first but with input and output switched around. The 
third is the most complex and should only be used as a last resort. But 
of the first two, which is better?


Well, take a look at the structures of the data. The input is linear; it 
has one datum after another. The output is a table, two dimensional. If 
we store the data in a linear structure, like its input, we would still 
have to transform it to a two-dimensional one before we can output it. 
But if we can transform the input into a two-dimension structure, it can 
be easily outputted and we save ourselves a step. So, since preserving 
input order is not important, a hash of hashes seems the best structure.


When printing out a table, it's nice to have the column index or key as 
the inner one and the row index or key as the outer one. The column key 
is the Hr value, and the row key is from the lines with two numbers. So, 
the pseudo-code looks like this:


Create a variable to hold the Hr key;
For each line of input:
If the line starts with Hr:
Save the number in the Hr variable;
Else
Extract the key and value from the line;
Store it in a HoH with this key, the Hr key and the value
$HoH{$key}{$Hr_key} = $value;

Now output the table (exercise left to the reader) :).


--
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

[edited for today's programmers]
Show me your code and conceal your interfaces, and I shall continue
to be mystified. Show me your interfaces, and I won't usually need
your code; it'll be obvious.
-- Fred Brooks

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




Re: some suggestions

2012-03-22 Thread John W. Krahn

Chris Stinemetz wrote:

I would like to use the number on the left as a key in a hash and use
the number on the right as the value pair to the key. Then print the
values for each hour that have the same key. Maybe this is a good
example for an array of hashes, but I not real sure how to begin. Any
help is greatly appreciated.

Below is the input data:

Hr 12
0001 2
0002 3
0003 1
Hr 13
0001 2
0002 3
0003 1
Hr 14
0001 2
0002 3
0003 1

Desired output below:

   12 13 14
00012   2  2
00023   3  3
00031   1  1



$ echo Hr 12
0001 2
0002 3
0003 1
Hr 13
0001 2
0002 3
0003 1
Hr 14
0001 2
0002 3
0003 1 | perl -e'

my ( @hours, %data );
while (  ) {
push @hours, $1 if /^hr\s*(\d+)/i;
$data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
}

print join( \t, , @hours ), \n;
for my $row ( sort { $a = $b } keys %data ) {
print $row;
for my $col ( sort { $a = $b } keys %{ $data{ $row } } ) {
print \t$data{$row}{$col};
}
print \n;
}
'
12  13  14
00012   2   2
00023   3   3
00031   1   1




John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.   -- Albert Einstein

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




Re: some suggestions

2012-03-22 Thread John W. Krahn

John W. Krahn wrote:


$ echo Hr 12
0001 2
0002 3
0003 1
Hr 13
0001 2
0002 3
0003 1
Hr 14
0001 2
0002 3
0003 1 | perl -e'

my ( @hours, %data );
while (  ) {
push @hours, $1 if /^hr\s*(\d+)/i;
$data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
}

print join( \t, , @hours ), \n;
for my $row ( sort { $a = $b } keys %data ) {
print $row;
for my $col ( sort { $a = $b } keys %{ $data{ $row } } ) {
print \t$data{$row}{$col};
}
print \n;
}
'
12 13 14
0001 2 2 2
0002 3 3 3
0003 1 1 1


Probably better:

$ echo Hr 12
0001 2
0002 3
0003 1
Hr 13
0001 2
0002 3
0003 1
Hr 14
0001 2
0002 3
0003 1 | perl -e'

my ( @hours, %data );
while (  ) {
push @hours, $1 if /^hr\s*(\d+)/i;
$data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
}
print join( \t, , @hours ), \n;
for my $row ( sort { $a = $b } keys %data ) {
print $row;
for my $col ( @hours ) {
print \t$data{$row}{$col};
}
print \n;
}
'
12  13  14
00012   2   2
00023   3   3
00031   1   1




John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.   -- Albert Einstein

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




Re: some suggestions

2012-03-22 Thread lina
On Fri, Mar 23, 2012 at 10:20 AM, John W. Krahn jwkr...@shaw.ca wrote:
 John W. Krahn wrote:


 $ echo Hr 12
 0001 2
 0002 3
 0003 1
 Hr 13
 0001 2
 0002 3
 0003 1
 Hr 14
 0001 2
 0002 3
 0003 1 | perl -e'

 my ( @hours, %data );
 while (  ) {
    push @hours, $1 if /^hr\s*(\d+)/i;
    $data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
    }

 print join( \t, , @hours ), \n;
 for my $row ( sort { $a = $b } keys %data ) {
    print $row;
    for my $col ( sort { $a = $b } keys %{ $data{ $row } } ) {
        print \t$data{$row}{$col};
        }
    print \n;
    }
 '
 12 13 14
 0001 2 2 2
 0002 3 3 3
 0003 1 1 1


 Probably better:


 $ echo Hr 12
 0001 2
 0002 3
 0003 1
 Hr 13
 0001 2
 0002 3
 0003 1
 Hr 14
 0001 2
 0002 3
 0003 1 | perl -e'

 my ( @hours, %data );
 while (  ) {
    push @hours, $1 if /^hr\s*(\d+)/i;
    $data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
    }
 print join( \t, , @hours ), \n;
 for my $row ( sort { $a = $b } keys %data ) {
    print $row;
    for my $col ( @hours ) {

        print \t$data{$row}{$col};
        }
    print \n;
    }
 '
        12      13      14
 0001    2       2       2
 0002    3       3       3
 0003    1       1       1



Here I use:


push  @hours, $1 if(/Hr\b(.*)\b/) ;

$data{$1}{$hours[-1]} = $2 if(/\b(.+)\b(.*)\b/);

it reported, how can I fix it:


$ perl calen.pl
 12  13  14
Argument 0003 1 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument 0002 3 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument 0001 2 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument Hr 12 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument Hr 13 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument Hr 14 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Hr 12   Hr 13   Hr 14   0001 2  0002 3  0003 1l


Thanks,



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




Re: some suggestions

2012-03-22 Thread Jim Gibson

At 10:41 AM +0800 3/23/12, lina wrote:

On Fri, Mar 23, 2012 at 10:20 AM, John W. Krahn jwkr...@shaw.ca wrote:

 John W. Krahn wrote:



 $ echo Hr 12
 0001 2
 0002 3
 0003 1
 Hr 13
 0001 2
 0002 3
 0003 1
 Hr 14
 0001 2
 0002 3
 0003 1 | perl -e'

 my ( @hours, %data );
 while (  ) {
push @hours, $1 if /^hr\s*(\d+)/i;
$data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
}

 print join( \t, , @hours ), \n;
 for my $row ( sort { $a = $b } keys %data ) {
print $row;
for my $col ( sort { $a = $b } keys %{ $data{ $row } } ) {
print \t$data{$row}{$col};
}
print \n;
}
 '
 12 13 14
 0001 2 2 2
 0002 3 3 3
 0003 1 1 1



 Probably better:


 $ echo Hr 12
 0001 2
 0002 3
 0003 1
 Hr 13
 0001 2
 0002 3
 0003 1
 Hr 14
 0001 2
 0002 3
 0003 1 | perl -e'

 my ( @hours, %data );
 while (  ) {
push @hours, $1 if /^hr\s*(\d+)/i;
$data{ $1 }{ $hours[ -1 ] } = $2 if /^(\d+)\s+(\d+)/;
}
 print join( \t, , @hours ), \n;
 for my $row ( sort { $a = $b } keys %data ) {
print $row;
for my $col ( @hours ) {

print \t$data{$row}{$col};
}
print \n;
}
 '
12  13  14
 00012   2   2
 00023   3   3
 00031   1   1




Here I use:


push  @hours, $1 if(/Hr\b(.*)\b/) ;

$data{$1}{$hours[-1]} = $2 if(/\b(.+)\b(.*)\b/);

it reported, how can I fix it:



By using the correct regex. You need to use \d or [0-9] in your 
regular expression rather than the dot character, which matches any 
character. You are matching and capturing the entire line with (.+), 
leaving nothing for the second capture group.





$ perl calen.pl
12   13  14
Argument 0003 1 isn't numeric in sort at calen.pl line 23, 
$_[...] line 12.
Argument 0002 3 isn't numeric in sort at calen.pl line 23, 
$_[...] line 12.
Argument 0001 2 isn't numeric in sort at calen.pl line 23, 
$_[...] line 12.

Argument Hr 12 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument Hr 13 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Argument Hr 14 isn't numeric in sort at calen.pl line 23, $_[...] line 12.
Hr 12   Hr 13   Hr 14   0001 2  0002 3  0003 1l




Thanks,





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



--
Jim Gibson
j...@gibson.org

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