Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Why NO output???

by basicdez (Pilgrim)
on Nov 08, 2001 at 04:03 UTC ( [id://123958]=perlquestion: print w/replies, xml ) Need Help??

basicdez has asked for the wisdom of the Perl Monks concerning the following question:

Here is CommaSample.dat
"PER" "A1" "Denise Johnson" "red,orange,yellow,green,blue,purple" 09/25/2001 "PER" "A2" "Suzanne Summers" "blue,green,yellow,blue-green" 07/24/1995 "EMP" "A1" "X & Y Bank" "Teller" 05/17/1994 "Brian's Point" "WI" 54997 24000 +.00 "EMP" "A2" "Acme Corp" "Computer Programmer" 07/24/1997 "Maxwell" "WI" 53224 + 45000.00 "EOS"
And here is the program that I am running against it. Please tell me why this is producing NO output at all.
#!/usr/bin/perl-Tw use strict; use Text::ParseWords; open(DATA,"CommaSample.dat") || die "Cannot open datfile: $!\n"; my @data; my $i = 0; my $new_record = 0; while (<DATA>) { chomp; last if /^"EOS"$/; { @data = &quotewords('\s+', 0, $_); } if (/^PER\s*$/) { @data = &quotewords('\s+', 0, $_); my @colors=split(/,/, $data[2]); print "Entity = $data[0]\n"; print "Name = $data[1]\n"; for (@colors) { # print each color print "Color = $_ \n"; } print "Date = $data[3]\n"; @data = &quotewords ('\s+', 0, $_); } elsif (/^EMP\s*$/) { @data = &quotewords('\s+', 0, $_); print "Entity = $data[0]\n"; print "Employment = $data[1]\n"; print "Job Title = $data[2]\n"; print "Hire Date = $data[3]\n"; print "Location = $data[4], $data[5] $data[6]\n"; print "Salary = $data[7]\n"; } }
I keep going over this and over this and over this, but cannot figure it out. I am hoping it is easy, but i don't know. Please help me as I am at a high level of frustration and groveling here. peace, LOVE and ((code)) basicdez

Replies are listed 'Best First'.
Why would it?
by boo_radley (Parson) on Nov 08, 2001 at 04:15 UTC
    you're not getting output because neither of these conditions are true.
    if (/^PER\s*$/) ... elsif (/^EMP\s*$/) ...
    try adding a final else clause
    else { print "neither PER or EMP matched!\n value is $_\n" }
    briefly looking your code over, shouldn't the regexes be something like/^"PER"/? the ones you've got now seem to expect only PER and any number of spaces or EMP and any number of spaces. I'd also be wary of using DATA as a file handle, because it's special happy fun magic in perl. See documentation as to why, or look for __DATA__ in the monastery.
    All advice unproven and untested, as I'm going home now.
Re: Why NO output???
by traveler (Parson) on Nov 08, 2001 at 05:05 UTC
    You still have the problem you asked about the other day (in addition to the problems mentioned above -- $_ is never going to match /^PER\s*$/). Your PER and EMP tags are on separate lines from the other data so you need to read the data in separately. Check out the answers you got last time you posted and you will be able to fix it.

    Check out Data::Dumper if you are really stuck.

    HTH, --traveler

Re: Why NO output???
by dws (Chancellor) on Nov 08, 2001 at 04:22 UTC
      #!/usr/bin/perl-Tw Is that a typo, or is there really a space missing between "perl" and "-Tw"? Depending on which web server you're using, that missing space could explain why you aren't seeing anything (or could at least explain why you aren't running into the other problems with the script).

Re: Why NO output???
by Zaxo (Archbishop) on Nov 08, 2001 at 09:28 UTC

    The other replies are on the mark. Since the record tags are on a seperate line, you need to remember which was seen last. Here is my version:

    The preliminaries.

    #!/usr/bin/perl -Tw use strict; use Text::ParseWords; my $fname = "CommaSample.dat"; my $pretty = 1; BARE: {
    Lexicals get limited scope from the bare block. The $toggle is for remembering the previous record tag.
    my ($toggle, @data) = ('');
    Use a nonmagical file handle, weak binding 'or' to banish parens (style choice), and no newline to show off $! magic in die list. In 5.6 I'd use lexical my $fh for the file handle . That way the data file would be automagically closed when we left the block.
    open FH, "< $fname" or die "Cannot open datfile: ", $!;
    The loop logic is all done here at the top. A record tag sets the toggle and goes back to read the record on the next line. The end tag bursts out of the loop. Comma is the sequence operator, allowing modifier 'if' by making the two actions a single expression.
    while (<FH>) { $toggle = 1, next if /^"PER"\s*$/; $toggle = 0, next if /^"EMP"\s*$/; last if /^"EOS"\s*$/;
    Trap and identify malformed data.
    die "Unknown or missing record tag: Got $_ on line $., datafil +e $fname.$/" if $toggle eq '';
    We put off 'chomp' till here, it's only needed for data. The quotewords split and "Entity" output line are common to both record types, so we go ahead and do them.
    chomp; @data = &quotewords('\s+', 0, $_); print "Entity = $data[0]$/"; if ($toggle) {
    The $toggle is on for "PER" data. Do the "Color" loop as a modifier to avoid temporary variables and make it look more like the others.
    print "Name = $data[1]$/"; print "Color = $_ $/" for split /\s*,\s*/, $data[2]; print "Date = $data[3]$/"; } else {
    It's "EMP" data. Nothing special to see here besides consolidating to a single print list.
    print "Employment = $data[1]$/", "Job Title = $data[2]$/", "Hire Date = $data[3]$/", "Location = $data[4], $data[5] $data[6]$/", "Salary = $data[7]$/"; }
    Reset the bad data trap. Optionally print a blank line between records...
    $toggle = ''; print $/ if $pretty; }
    ... and always one at the end
    print $/; }
    Throughout, I've used the input record seperator $/ instead of "\n" in printing. That helps when you want to change the output format, and improves the portability of your script... though at the expense of data portability.

    Update: If there are more record tags to handle, you could expand the loop control section by $toggle = 2, next if /^"ADR"\s*$/; and so forth, with a case switch structure in place of the if ($toggle) {...} else {...} arrangement. It would be better, though, to define a hash @record_types{PER, EMP, ADR, TTY} to contain subrefs for each handler. Do you have any influance over the design of this database?

    After Compline,
    Zaxo

      I really appreciate all of the help on this one, but could anyone suggest something if there are more than two different related code files to be read in. Say PER, EMP, ADR and TTY were four different packets I was receiving in, how could I do the toggle thing? peace, LOVE and ((code)) basicdez
Re: Why NO output???
by {NULE} (Hermit) on Nov 08, 2001 at 05:22 UTC
    Hi,

    Well, for starters there is no PER or EMP in the file, they are "PER" or "EMP" so you must include the quotes in the regexp thusly, /^"EMP"\s*$/

    That will at least give you some output, there are more issues though. Like the traveler stated the regular expression will not match the line with the data in it (the data is the line after) so some other logic here is necessary.

    Good luck,
    {NULE}
    --
    http://www.nule.org

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://123958]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-03-28 17:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found