www.webdeveloper.com
Results 1 to 7 of 7

Thread: Perl, Data into conditional

  1. #1
    Join Date
    Jun 2008
    Posts
    223

    Perl, Data into conditional

    Hi, I have a flatfile db that is read in and then in a conditional check against a field in order to process the rest of the data.

    Code:
    if ($fd[5] eq "Fr" || $fd[5] eq "Sp" || $fd[5] eq "It")
    It works, but.....

    I have to add to this manually, when I decide to add another reference.

    So, say I add Ge to it, then I need to make it read like this:

    Code:
    if ($fd[5] eq "Fr" || $fd[5] eq "Sp" || $fd[5] eq "It" || $fd[5] eq "Ge")
    (Note: the quotes are around the refs, because "use strict" told me to do that)
    Sooner or later this is going to break as I could end up with a dozen or so references. If I had these references in another flatfile db, can I create the conditional from that? Is that possible?

    So a file with
    --------------
    Fr|France
    Sp|Spain
    It|Italy
    Ge|Germany
    --------------
    would be read and the first field of each record grabbed to check against the field in the main database, then print the Country name as part of the read out (I've done that bit, so that's not a problem).

    Does that make sense? There's probably a simple answer to this, but it's beyond my skills.

    Hope someone can help, Thanks.
    Last edited by edatz; 02-12-2012 at 12:09 PM.

  2. #2
    Join Date
    Oct 2007
    Location
    Vienna, Austria
    Posts
    389
    Hey, yes, it is definitely possible and IMO it's even a good idea.
    Code:
    # load the countries
    my @countries = load_the_countries_database();
    # now I assume @countries array contains records like "Fr|France"
    
    # now create a hash out of the array,
    # indexed with the country codes for easy access
    my %country_by_code;
    for my $country_line (@countries) {
        my ($code,$name) = split /\|/, $country_line;
        $country_by_code{$code} = $name;
    }
    
    # then later when you check the conditional...
    if ( exists $country_by_code{ $fd[5] } ) { ... }

  3. #3
    Join Date
    Jun 2008
    Posts
    223
    Hi Sixtease, that is quite interesting.

    it is definitely possible and IMO it's even a good idea
    A very good idea.
    I can see all kinds of possibilies from it. Thanks very much.

    This is the whole thing.

    Files:
    main.txt
    Code:
    4||Tanger|Cheap grass, cheap food, rotten jail.||No|
    3||London|Don't waste your hard earned money going to the 2012 Olympic Games.||Lt|
    2||Madrid|Madrid is cold during winter because it's over a mile high.||Sp|
    1||Taranto|One of the main ports in the Med, but do they have good pizza?||It|
    specs.txt
    Code:
    Lt|The UK|
    Sp|Spain|
    It|The Pizza Journeys|
    The script
    Code:
    YOURPATHTOPERL
    use strict;
    use warnings;
    use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
    print "Content-type: text/html\n\n";
    
    my $fl = "main.txt";
    my $fs = "specs.txt";
    
    open(SDB, "$fs") || die("Cannot open $fs");
    my @countries=<SDB>; close (SDB); ## Opens the specs file, read only
    
    open(MDB, "$fl") || die("Cannot open $fl"); # Opens the main file, read only
     while (<MDB>) {
     chomp;
     my @fd = $_;
     my @fd=split /\|/, "@fd";
     my &#37;country_by_code; # Sixtease's hash
      for my $country_line (@countries) {
      my ($code,$name) = split /\|/, $country_line;
      $country_by_code{$code} = $name;}
       if ( exists $country_by_code{ $fd[5] } ) {
       print qq ~<div style="margin-bottom:24px;"><b>$fd[2]</b><br>$fd[3]<br>......<br>~;
       foreach my $line (@countries) {
       chomp($line); my @sp=split /\|/, "$line";
        if ($sp[0] eq $fd[5]) {
        print qq ~&#91;$sp[1]&#93;~;
        print qq ~</div>~;
        }
       }
     }
      else {print qq ~<div style="margin-bottom:24px;"><b>$fd[2]</b><br>$fd[3]</div>~;}
    }
    close (MDB);
    exit;
    The sp1 read could be anything, all I've put here is a short thing for this post.

    Thanks again.
    Last edited by edatz; 02-13-2012 at 03:51 AM.

  4. #4
    Join Date
    Oct 2007
    Location
    Vienna, Austria
    Posts
    389
    Two little details:

    * You're reading the countries file over and over with every loop iteration. Create the &#37;country_by_code hash outside of the loop instead.

    * I'd suggest to chomp the @countries before creating the hash, so you don't have "Fr|France\n" in there.
    Code:
    chomp for @countries

  5. #5
    Join Date
    Jun 2008
    Posts
    223
    You mean like this?
    I didn't know you could have a chomp outside of a loop.
    Code:
    open(SDB, "$fs") || die("Cannot open $fs");
    my @countries=<SDB>; close (SDB); ## Opens the specs file, read only  
    
    chomp(@countries);
    
    my &#37;country_by_code; # Sixtease's hash
      for my $country_line (@countries) {
      my ($code,$name) = split /\|/, $country_line;
      $country_by_code{$code} = $name;}
    
    open(MDB, "$fl") || die("Cannot open $fl"); # Opens the main file, read only
     while (<MDB>) {
     chomp;
     my @fd = $_;
     my @fd=split /\|/, "@fd";
       if ( exists $country_by_code{ $fd[5] } ) {
       print qq ~<b>$fd[2]</b><br>$fd[3]<br>~;
    
       foreach my $line (@countries) {
       chomp($line); my @sp=split /\|/, "$line";
        if ($sp[0] eq $fd[5]) {
        print qq ~($sp[1])~;
        print qq ~<br><br>~;
        }
       }
     }
      else {print qq ~<b>$fd[2]</b><br>$fd[3]<br><br>~;}
    }
    close (MDB);
    exit;
    I see that the file is opened, hashed and then because it has been opened and held in the array @countries, the second read works to show the country, yes?

    right I see about the chomp. The array is being chomped. Got it (takes me a while :-))

    Note: I trimmed the HTML down as I was getting confused.
    Last edited by edatz; 02-13-2012 at 08:29 AM.

  6. #6
    Join Date
    Oct 2007
    Location
    Vienna, Austria
    Posts
    389
    I actually meant
    Code:
    chomp for @countries;
    which is exactly the same as
    Code:
    foreach my $line (@countries) {
      chomp($line);
    }
    but your version
    Code:
    chomp(@countries)
    is actually even better. Neither I knew it was possible but perldoc -f chomp shows that it is.

    You don't need the second loop. You can just use the hashed value. No need to parse the file all over again.
    Code:
    if ( exists $country_by_code{ $fd[5] } ) {
        print qq ~<b>$fd[2]</b><br>$fd[3]<br>$country_by_code{ $fd[5] }<br><br>~;
    }

  7. #7
    Join Date
    Jun 2008
    Posts
    223
    Hi Sixtease,
    The chomp stands to reason. The array is already in place. Hmmm.

    You don't need the second loop. You can just use the hashed value. No need to parse the file all over again.
    I'm not used to hashes, I guess they hold differently than standard arrays. Anything that makes less code and still do the job is always welcome.

    It all works fine. Thanks for that, it wouldn't have ever dawned on me.

    I've been to Perldoc and find it appears to be for seriously experienced programmers (which makes me wonder why it's there in the first place - if someone knows all about Perl, they probably don't need Perldoc). Most of what is presented is very obscure and leaves tons to be desired explanation wise.

    I've only got a few more things to do (yes I may be back ) and then I am getting off the merry-go-round to go out visiting places I have not been before (may end up your neck of the woods, only drove thru the corner of Austria to Hungary 20 years ago on an Aid Run).

    You coming to the Olympics this summer?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles