#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    2

    Programming question


    How does one, when they read a file with the open function, store specific files matched by regular expressions into a hash.

    Like say I had some value called red followed by a colon and than a number, how do I put the color into the key of the hash and the number into the value part. And say if I did have multiple numbers for the same key, how do I add them together? printing how the hashes with the keys, and completely updated values?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,947
    Rep Power
    1225
    Use a while loop to loop over the file line-by-line.

    use the split function to extract the 2 parts of the data.

    Use the 1st part for the hash key and use addition to add the value of the 2nd part.

    Give it a try and when you get stuck, post your code any/all errors it generates and a specific question on the part that's giving you trouble.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    842
    Rep Power
    496
    I think you need to go through some documentation. You can't expect us to answer such general questions and yet cover the details.

    A few primers, though, just to show how easy it is. Assuming you're reading your file line by line into a $line variable.

    Like say I had some value called red followed by a colon and than a number, how do I put the color into the key of the hash and the number into the value part.
    Assuming your data looks like this (with unique values):
    Code:
    red:125
    blue:137
    green:145
    You could do something like this:

    Perl Code:
    my %hash;
    while (my $line = <$IN_FILE>) {
         chomp $line; # removes newline characters
         my ($color, $value) = split /:/, $line;
         $hash{$color} = $value;
    }


    And say if I did have multiple numbers for the same key, how do I add them together?
    To cumulate values, just a small change:
    Perl Code:
    my %hash;
    while (my $line = <$IN_FILE>) {
         chomp $line; # removes newline characters
         my ($color, $value) = split /:/, $line;
         $hash{$color} += $value; # equivalent to: $hash{$color} = $hash{$color} + $value;
    }


    At the end, the hash will contain the cumulative values for each key.

    printing how the hashes with the keys, and completely updated values?
    Once you have read through the file and accumulated values into the hash, just print the hash (after the end of the loop), for example as follows:
    Perl Code:
    foreach my $color (keys %hash) {
         print $color, " : ", $hash{$color}, "\n";
    }

    or in numerous other ways, including this more compact (and probably more Perlish) syntax:
    Perl Code:
    print "$_ : $hash{$_}\n" for keys %hash;


    Alright, I gave you some basic solutions to your questions, but you should really work your way through some documentation. I think that I would have been able to give you all of the solutions outlined above after having read and used a good Perl tutorial 2 hours per day during three days when I first learned the language about 10 or 11 years ago (OK, perhaps less clean at the time, no use of 'my' to declare values, but the same computing ideas).
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    2
    Originally Posted by Laurent_R
    I think you need to go through some documentation. You can't expect us to answer such general questions and yet cover the details.

    A few primers, though, just to show how easy it is. Assuming you're reading your file line by line into a $line variable.



    Assuming your data looks like this (with unique values):
    Code:
    red:125
    blue:137
    green:145
    You could do something like this:

    Perl Code:
    my %hash;
    while (my $line = <$IN_FILE>) {
         chomp $line; # removes newline characters
         my ($color, $value) = split /:/, $line;
         $hash{$color} = $value;
    }




    To cumulate values, just a small change:
    Perl Code:
    my %hash;
    while (my $line = <$IN_FILE>) {
         chomp $line; # removes newline characters
         my ($color, $value) = split /:/, $line;
         $hash{$color} += $value; # equivalent to: $hash{$color} = $hash{$color} + $value;
    }


    At the end, the hash will contain the cumulative values for each key.


    Once you have read through the file and accumulated values into the hash, just print the hash (after the end of the loop), for example as follows:
    Perl Code:
    foreach my $color (keys %hash) {
         print $color, " : ", $hash{$color}, "\n";
    }

    or in numerous other ways, including this more compact (and probably more Perlish) syntax:
    Perl Code:
    print "$_ : $hash{$_}\n" for keys %hash;


    Alright, I gave you some basic solutions to your questions, but you should really work your way through some documentation. I think that I would have been able to give you all of the solutions outlined above after having read and used a good Perl tutorial 2 hours per day during three days when I first learned the language about 10 or 11 years ago (OK, perhaps less clean at the time, no use of 'my' to declare values, but the same computing ideas).
    Thanks for the help, Laurent. You are always helpful.

    I still haven't solved my issue yet, but I'm sure this stuff will be more than helpful moving forward.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    842
    Rep Power
    496
    Originally Posted by seedofwinter
    I still haven't solved my issue yet, but I'm sure this stuff will be more than helpful moving forward.
    The problem is that your question is far too general. To answer it would require tens of pages of text, which I am not willing to write because they have already been written, and usually well written, by others (under the general name of Perl documentation) and also because I am not even sure you would really read me to the end if I were going to answer with a 30-page documentation.

    You might try the following commands on you Perl environment to start with:

    Code:
    perldoc perlfunc
    perldoc perlre
    But others and I will certainly be happy to answer more specific questions, especially if you show code that you have tried and does not produce what you expect.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    2
    Originally Posted by Laurent_R
    The problem is that your question is far too general. To answer it would require tens of pages of text, which I am not willing to write because they have already been written, and usually well written, by others (under the general name of Perl documentation) and also because I am not even sure you would really read me to the end if I were going to answer with a 30-page documentation.

    You might try the following commands on you Perl environment to start with:

    Code:
    perldoc perlfunc
    perldoc perlre
    But others and I will certainly be happy to answer more specific questions, especially if you show code that you have tried and does not produce what you expect.
    I'm sorry, I don't mean to upset you. I know how frustrating I am. LOL And it doesn't help that I don't have time to read all that documentation you have been trying to lead me to. But also, for a beginner like me, that stuff is a rough chew.

    But I will try to give it a looksy for a while. Maybe It can help me get a better grip on this stuff.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    2
    Okay, you guys wanted specific code? Here it is. Why isn't this thing printing out the colors and values in my file?

    my %color_hash;
    open (FILE, "color");
    while (my $lines = <FILE>) {
    chomp $line;
    my ($colors, $score) = split /:/, $line;
    $color_hash{$color} = $value;
    }
    print "{[%color_hash]}\n"

    I define my hash on the first line. Open the text file called color on the next. Start a loop that travels through all the lines of the file on the third line. Chop the new line characters on 4th. Create the variable colors for the first half of the split and the variable keys for the second half. Put all those values into color_hash. And then try to print. Where am I making my error?
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,947
    Rep Power
    1225
    Where am I making my error?
    1) Your open call, while functional, has several problems. The main one is that it doesn't have any error handing.

    2) You read each line into the $lines var but after that, you refer to $line which is not the same var. If you had enabled strictures (i.e., have a use strict; statement near the beginning), perl would have told you about that problem.

    3) You (attempt to) split the line into the $colors, $score vars but when you assign the data to the hash, you use two different vars $color and $value which were not defined. Here again, perl would have told you about that if you had loaded the strict pragma.

    4) When you attempt to print the hash, you refer to the hash as a whole, which won't work. You need to loop over the keys to be able to output each key and value.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    842
    Rep Power
    496
    Hi, a few corrections to your code, although I do not pretend that what I am suggesting will work straight out of the box, since I have no data to test:

    Perl Code:
    use strict;
    use warnings;
    my %color_hash;
    my $file = "color";
    open my $FILE, "<", $file or die "could not open file $file $!";
    while (my $line = <$FILE>) {
         chomp $line;
         my ($color, $score) = split /:/, $line;
         $color_hash{$color} = $score;
    }
    print $_, " : ", $color_hash{$_}, "\n" foreach keys %color_hash;


    Your main coding errors:

    • $line versus $lines
      $color versus $colors
      $score versus $value
      The way to print the records of a hash


    And, even worse error, if you had used
    Perl Code:
    use strict;
    use warnings;

    the first three errors above (and possibly the fourth one) would have been picked up by the compiler and reported to you, so that it would have taken you a couple of minutes to understand and fix them.

    Comments on this post

    • dsb agrees
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    842
    Rep Power
    496
    Originally Posted by seedofwinter
    I'm sorry, I don't mean to upset you.
    Don't worry, I am not upset at all.

    I was only saying that it is difficult to help you on such a general question. Now that you have posted some code, I was able to give you (above) what I think is a much more useful answer.
  20. #11
  21. No Profile Picture
    PerlGuy
    Devshed Novice (500 - 999 posts)

    Join Date
    Jan 2001
    Posts
    720
    Rep Power
    42
    Originally Posted by FishMonger
    4) When you attempt to print the hash, you refer to the hash as a whole, which won't work. You need to loop over the keys to be able to output each key and value.
    strictly speaking, this isn't true. You can, in fact, refer to the hash variable itself in a print statement, but you can't interpolate it into a string, and it comes out as a garbled mess of key-value pairs.

    Sorry to be nit-picky, especially since, in theory, printing an entire hash is somewhat useless.
    - dsb -
    Perl Guy
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    2
    Originally Posted by Laurent_R
    Hi, a few corrections to your code, although I do not pretend that what I am suggesting will work straight out of the box, since I have no data to test:

    Perl Code:
    use strict;
    use warnings;
    my %color_hash;
    my $file = "color";
    open my $FILE, "<", $file or die "could not open file $file $!";
    while (my $line = <$FILE>) {
         chomp $line;
         my ($color, $score) = split /:/, $line;
         $color_hash{$color} = $score;
    }
    print $_, " : ", $color_hash{$_}, "\n" foreach keys %color_hash;


    Your main coding errors:

    • $line versus $lines
      $color versus $colors
      $score versus $value
      The way to print the records of a hash


    And, even worse error, if you had used
    Perl Code:
    use strict;
    use warnings;

    the first three errors above (and possibly the fourth one) would have been picked up by the compiler and reported to you, so that it would have taken you a couple of minutes to understand and fix them.
    Thanks a lot Laurent. I will make sure I head all my programs with strict and warnings. Thank you as well, fish monger. Those are some embarrassing mistakes. lol
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Location
    Paris area, France
    Posts
    842
    Rep Power
    496
    Originally Posted by seedofwinter
    Those are some embarrassing mistakes. lol
    Not at all, most of us (at least I) do such errors all the time.

    That's why getting the help of the compiler to find them at compile time is a great help.

IMN logo majestic logo threadwatch logo seochat tools logo