in reply to New to Perl

First off welcome to perl, I hope you enjoy your stay.

As others have said your output requirements are rather vague so what I have done is parsed your input into a perl data structure. This I have just dumped out so you can see that we have all the data. You can really pick and choose what you want and how you want to format the output.

I have made the assumption that the format you gave is fairly complete, e.g. what they say will always contain says or doesn't speak. I have allowed names to contain whitespace and funny characters. if there are certain to be simple then they can be better matched with (\w+). You mention each round having a question but I do not really see this in your data. I have captured the bit after the round number as a guess of where I find this (round 2 has a value here, round 1 not)

click the read more links to open up the code underneath

#!/usr/bin/perl use warnings; use strict; use Data::Dumper; my @cases; my %current_case; my $current_round; while (<DATA>) { next if /^\s*$/; # ignore blank lines if (/#Case Number: (\d+)/) { %current_case && push @cases, \%current_case; %current_case=(); $current_case{case_number}=$1; $current_case{seat}=[]; $current_case{round}=[]; } elsif (/People at table = (\d+)/) { $current_case{people_at_table}=$1 } elsif (/Seat (\d+): (.*)/) { # perl starts counting from zero so we decrement seat number my $seat = $1 - 1; $current_case{seat}[$seat]=$2; $current_case{$2}=[]; } elsif (/(.*) speaks first/) { $current_case{speaks_first}=$1; } elsif (/Round (\d+):(.*)/) { $current_round=$1-1; # perl likes to start counting at zero $current_case{round}[$current_round]=$2 ? $2 : ""; } elsif (/(.*) ((says|doesn\'t talk).*)/) { $current_case{$1}[$current_round]=[] unless defined $current_c +ase{$1}[$current_round]; push @{$current_case{$1}[$current_round]}, $2; } } push @cases, \%current_case; print Dumper(\@cases); __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 # That is the script, this is the output $ ./case $VAR1 = [ { 'people_at_table' => '5', 'round' => [ '', ' Next question' ], 'seat' => [ 'Joe', 'Steve', 'Mary', 'Jill', 'Bob' ], 'case_number' => '12345', 'Joe' => [ [ 'says bad' ], [ 'says bad' ] ], 'Bob' => [ [ 'doesn\'t talk' ], [ 'doesn\'t talk', 'says that\'s enough' ] ], 'Jill' => [ [ 'says good', 'says that\'s enough' ], [ 'says bad' ] ], 'Mary' => [ [ 'doesn\'t talk' ], [ 'doesn\'t talk' ] ], 'speaks_first' => 'Jill', 'Steve' => [ [ 'says good', 'says that\'s enough' ], [ 'says bad' ] ] } ]; $

Cheers,
R.

Pereant, qui ante nos nostra dixerunt!

Replies are listed 'Best First'.
Re^2: New to Perl
by chromatic (Archbishop) on Jan 20, 2005 at 23:58 UTC
    %current_case && push @cases, \%current_case; %current_case=();

    Try it with a data set with more than one case.

      Hi Chromatic

      Thanks for reading and thinking about my code, its a fair cop, I just reset the hash rather than grabing a new one, DOH ! Sadly its 00:58 here, this evening I have enjoyed good company, a delicious Rioja and I got a 9am meeting, so no more coding till the morning.

      G'night,
      R.

      Pereant, qui ante nos nostra dixerunt!

      OK I found a couple of fixes, either make %current_case a package global with our then push a new ref to an empty hash into its typglob *current_case={}; or make current case a $scalar, store a ref to an anon hash in it $current_case={}; and replace all instances of %current_case{whatever} with $current_case->{whatever}. I guess the latter is the prefered solution

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!
Re^2: New to Perl
by Anonymous Monk on Jan 20, 2005 at 18:31 UTC

    While I appreciate the time you've taken to help, I must say, I don't appreciate the way you've done it. You have given a nearly complete solution to someone asking for pointers on how to start. I'm sure you've heard the old proverb about teaching someone to fish rather than giving them a fish...

    Now, you may go on about how your code was intended to be a useful example to learn by, but I can't entirely agree. It's not commented, quite dense, and, frankly, doesn't exactly use what I would call good style. It works, and there's something to be said for that, but I'm dubious about using such examples for pedagogical purposes.

      You are probably right. I started playing with this and it took longer than I thought so I did not get time to comment the code, I thought as I had written it I may as well post it. It answered at least one of the OPs questions, can perl do this ;)

      The data structure is not exactly beginers stuff but as we did not have any spec for output I thought that was the easiest way to show that it can be done. Now we have an output spec I would (shall if I get time this evening) re-write it so it prints the data as it finds it removing the need for a Hash of Arrays of God knows what.

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!
      I respectfully disagree with you. It is not that he has given you a fish as much as he has built the pole for you. If it doesn't meet your standards, then that particular pole serves at least as a reference point for building your own.

      I don't mind the style that much, though I would never say my $scalar="bleh"; before I said my($scalar) = "bleh";. But that's just me. I'm probably one of the few people left who puts parens around a single my arg. Of course, that's an OCD thing more than anything else. Anyway, I've never thought that getting nit-picky about another person's perl style was polite. If TIMTOWTDI and the interpreter doesn't ultimately care what method is chosen, I don't think it's up to you or anyone else to chastise another programmer for his style. It just seems un-perl to me.

      I don't know if your intention was to be "politely rude" so to speak, but it comes off that way. What was wrong with simply saying "thanks for taking time out of your day to assist me" and disregarding the rest of what you felt you HAD to post. I could be interpreting that wrong, so I'm telling you how I heard it and giving you the opportunity to correct me.

      I think this is the first node I've read where working code was frowned upon.

      /renz.

      UPDATE: Ugh. tall_man: bad example on my part. You're right. Humorously enough I finally gave up my desire to put parens before everything, some time after posting this, and for the very reason you have given. I just neglected to modify this post (mainly because I forgot about it). As of late I have labored greatly to conform to perldoc perlstyle as much as possible, though I have never preferred a 4-column indent to a 2-column indent, and I find it difficult not to cuddle my elses.
        I agree with what you say; providing some code in answer to a question is entirely appropriate most of the time.

        The nit I have is that you say there is no difference other than style between my $scalar="bleh"; and my($scalar) = "bleh";. There is a difference. The former uses scalar context and the latter uses list context. That can make a difference to the evaluation of an expression. For example:

        use strict; my $time1 = localtime(); my($time2) = localtime(); print "time1 is $time1\n"; print "time2 is $time2\n";

        The time2 line prints only the seconds value of the current time.