Here is a more readable version with comment. I now include speaker order and made the output a little more readable. The problem pointed out by Chromatic is also fixed in this version
#!/usr/bin/perl # the folllowing check your code for you # enforce some good behaviour (like declaring variables) # and catch a lot of finger pilotage errors use warnings; use strict; # here I declare some variables I am going to use # $ is a scalar (string, number, or a reference to another variable) # @ is an array of scalars # % is an associative array or hash, values looked up by a unique key my ( $case_number, $head_count, @player, $spoke_first, %player_said, $round );
# if you put a __DATA__ block at the end of your code you can # read from it like this. for your purposes you will want # to open another file and read from that but the while loop # will end up mauch the same while (<DATA>) { next if /^\s*$/; # ignore blank lines # now we do a series of pattern matches. Perl # captures any match in brackets into a numbered # variable $1 for the first match, $2 for the.... # \d is a decimal digit, \d+ one or more, read up # on regex to find much more goodness if (/#Case Number: (\d+)/) { # here we call a subroutine defined later # putting a \ infront of a variable passes # a reference to it to the subroutine. &print_case($case_number, $head_count, \@player, $spoke_first, \%player_said ); $case_number=$1; @player=(); %player_said=(); } elsif (/People at table = (\d+)/) { $head_count=$1 } elsif (/Seat (\d+): (.*)/) { # perl starts counting from zero so we decrement seat number my $seat = ($1 - 1); $player[$seat]=$2; $player_said{$2}=[]; } elsif (/(.*) speaks first/) { $spoke_first=$1; } elsif (/Round (\d+):(.*)/) { $round=$1-1; # perl likes to start counting at zero $player_said{$_}[$round]=[] foreach (@player); } elsif (/(.*) (says|doesn\'t talk)\s*(.*)/) { push @{$player_said{$1}[$round]}, ($3 ? $3 : 0); } } # we need to pass the data when we fall of the end too or we would # always loose the last case &print_case($case_number, $head_count, \@player, $spoke_first, \%player_said ); # OK now lets print out what we got # sub uses a prototype to check you are passing it # the correct sort of values (two scalars, a ref to an array # another scalar and a ref to a hash sub print_case($$\@$\%) { my $case_number=shift; my $head_count=shift; # as we passed a reference we will dereference it here # to make things a little less ugly my @player=@{+shift}; my $spoke_first=shift; # more dereferencing this time a hash my %player_said=%{+shift}; # work out the speaking order based assuming they speak # in seating order (and obviosly starting with who first my %speaking_order; my $turn=1; foreach my $player (@player, @player) { next unless ($player eq $spoke_first) ... ($player eq $spoke_f +irst); last if defined $speaking_order{$player}; $speaking_order{$player}=$turn++; } # now we build our data to print for each player my $seat_number=1; foreach my $player (@player) { my @output; push @output, $player; push @output, $case_number; push @output, "seat:".$seat_number++; push @output, "spoke:".$speaking_order{$player}; my @rounds_array=@{$player_said{$player}}; my $i = 1; foreach my $ar_speach (@rounds_array) { push @output, "question:".$i++; for my $j (0..4) { my $speach = defined $$ar_speach[$j] ? $$ar_speach[$j] + : 0; push @output, $speach; } } # this is the actual print of each player print join ",",@output; print "\n"; } } __DATA__ #Case Number: 12345 People at table = 5 Seat 1: Joe Seat 2: Steve Seat 3: Mary Seat 4: Jill Seat 5: Bob Jill speaks first Round 1: Jill says good Bob doesn't talk Joe says bad Steve says good Mary doesn't talk Jill says that's enough Steve says that's enough Round 2: Next question Jill says bad Bob doesn't talk Joe says bad Steve says bad Mary doesn't talk Bob says that's enough #Case Number: 76543 People at table = 3 Seat 1: Fred Seat 2: Nynke Seat 3: Jan Round 1: Nynke speaks first Nynke says LaLaDiLa Jan doesn't talk Fred says that's enough Nynkes says oh no its not Jan says he's behind you Round 2: Nynke says ik hou van patat Jan doesn't talk Fred says its all over when the fat lady sings Nynke doesn't talk Jan says that's enough Fred says foo Nynke says I'm back Jan says dag lieferds # output looks like this Joe,12345,seat:1,spoke:3,question:1,bad,0,0,0,0,question:2,bad,0,0,0,0 Steve,12345,seat:2,spoke:4,question:1,good,that's enough,0,0,0,questio +n:2,bad,0,0,0,0 Mary,12345,seat:3,spoke:5,question:1,0,0,0,0,0,question:2,0,0,0,0,0 Jill,12345,seat:4,spoke:1,question:1,good,that's enough,0,0,0,question +:2,bad,0,0,0,0 Bob,12345,seat:5,spoke:2,question:1,0,0,0,0,0,question:2,0,that's enou +gh,0,0,0 Fred,76543,seat:1,spoke:3,question:1,that's enough,0,0,0,0,question:2, +its all over when the fat lady sings,foo,0,0,0 Nynke,76543,seat:2,spoke:1,question:1,LaLaDiLa,0,0,0,0,question:2,ik h +ou van patat,0,I'm back,0,0 Jan,76543,seat:3,spoke:2,question:1,0,he's behind you,0,0,0,question:2 +,0,that's enough,dag lieferds,0,0
Cheers,
R.
In reply to Re^2: New to Perl
by Random_Walk
in thread New to Perl
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |