in reply to Tutoring for beginner?

Replies are listed 'Best First'.
Re^2: Tutoring for beginner?
by poj (Abbot) on Mar 07, 2015 at 16:41 UTC
    Try
    @data{@speciesList} = split(/\t/, $_, scalar @speciesList); # ^ ^ remove "
    poj
      Brilliant, that worked - thanks a lot! I can't wrap my head around how that made a difference, though.

        It makes a difference because with the added quotes, you're splitting on a literal string rather than a regular expression.

        If you want to split along tab characters, then the following are equivalent:

        @data{@speciesList} = split /\t/, $_, scalar @speciesList; @data{@speciesList} = split "\t", $_, scalar @speciesList;

        But the following is not:

        @data{@speciesList} = split "/\t/", $_, scalar @speciesList;

        as that splits on a slash followed by a tab followed by another slash, rather than just a slash. Here's a quick demonstration that may be instructive:

        #!/usr/bin/perl use strict; use warnings; use feature qw/say/; use English; $LIST_SEPARATOR = ","; while(<DATA>) { chomp; my @a = split /\t/; my @b = split "\t"; my @c = split "/\t/"; say "@a"; say "@b"; say "@c"; } __DATA__ foo bar foo/ /bar

        This outputs:

        $ perl 1119187.pl foo,bar foo,bar foo bar foo/,/bar foo/,/bar foo,bar $

        EDIT: posting the above script converted tab characters to spaces in the __DATA__ section, so you'll have to change those back before running the script to get the correct output.

        As you are very new I suggest you to read good Perl: i very suggest you a copy of Perl Cookbook. Is somehow old and sometimes outdated, but is perfectly valid Perl and you'll have a good panorama view of many Perl's possibilities.

        PS I was very newbie too and with no scientific background too: now I approach my problem with Perl with easy with the help of PerlMonks.

        welcome!
        L*
        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re^2: Tutoring for beginner?
by eyepopslikeamosquito (Archbishop) on Mar 08, 2015 at 00:01 UTC

    Programs often start out small and evolve into more complex beasts. Not unlike species.

    First, to make it easier for others to run, here is my test file, Mammal.txt, with each field separated by a single TAB character:

    Thylacine 42 147 Quagga 34 18 Baiji 40 116

    Running my program below on this input file produces the following output:

    Name : Thylacine Latitude : 42 Longitude : 147 Name : Quagga Latitude : 34 Longitude : 18 Name : Baiji Latitude : 40 Longitude : 116
    which has essentially the same data as yours but with minor (cosmetic) differences in formatting.

    I show below how I would have written your program. I hope that you find it useful and that it may serve as motivation for you for further study to improve your Perl skills.

    # Always start your scripts with strict and warnings. use strict; use warnings; # With "use strict" you must declare all variables before use # (this catches errors when you misspell a variable name, for example) +. # So we put a "my" in front of @speciesList and others below to declar +e # them as lexical variables, which have a scope from the point of # declaration to end of scope (i.e. end of block or end of file). my @speciesList = qw(Name Latitude Longitude); # Put "Mammal.txt" into a variable to avoid having to repeat it. my $infile = "Mammal.txt"; # BTW, instead of hard-wiring $infile to "Mammal.txt" above # you could now accept it as a command line argument like so: # my $infile = shift or die "usage: $0 filename\n"; # Use three-argument open and a lexical file handle. # Also check if the open fails and die with a useful message if so. open my $MAMMALS, "<", $infile or die "error: open '$infile': $!"; # Use explicit lexical variables rather than $_ while (my $line = <$MAMMALS>) { my %data; @data{@speciesList} = split /\t/, $line, scalar @speciesList; foreach my $species (@speciesList) { printf "%-10.10s : %s\n", $species, $data{$species}; } } close $MAMMALS;

    That is a first cut only.

    You might like to think further about your input file format. For example, if you add more species properties (in addition to Latitude and Longitude) how easy would it be to adjust your program? Is the input file format convenient? I would at least think about a different input file format with named properties (so you can easily add new ones without affecting existing properties), and with fields separated by any white space rather than a TAB char (for convenience and to allow vertical whitespace alignment when editing), and with a comment character to allow you to comment out lines. For example:

    # This is a species file Thylacine Lat=42 Long=147 Quagga Lat=34 Long=18 Baiji Lat=40 Long=116
    Of course, if you did that, your code would need to change in step ... which might be a useful training exercise. It would be good training for you to write the code to read the species properties file as a subroutine, taking a file name as input and returning an appropriate data structure of species properties as output.