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

As you can see, my numbers in AVG are not accurately getting the average. Some of them are fine, some columns NEVER work.

Below is my output file.

qty search 1 search 2 search 3 search 4 search 5 min avg high 2 645 625 645 645 635 625 639 645 1 2,800 2,900 3,000 3,000 2,988 2,800 2.4 3,000 1 5,000 5,495 4,999 4,995 4,900 4,999 4.4 5,495 1 692 770 695 697 678 678 706. 4 770 1 1,949 1,949 3,580 2,900 2,989 1,949 1.8 3,580 1 5,000 5,000 4,950 5,000 5,000 4,950 4.8 5,000
As you can see, some averages are 2.4 and 4.4 and I have no idea why. Obviously the other numbers are correct. Below is my code.
my $avg = $se1+$se2+$se3+$se4+$se5; $avg = $avg /5;
any idea what the problem might be? $se# holds the numbers as seen in the data printout above.

Replies are listed 'Best First'.
Re: Numbers aren't averaging correctly
by pg (Canon) on Oct 06, 2005 at 02:28 UTC

    That was actually "correct", 12/5=2.4, and 22/5 = 4.4.

    Only digits before commas are converted.

    use strict; use warnings; while (my $line = <DATA>) { $line =~ s/,//g; my @n = split(/\s+/, $line); my $sum = 0; for (@n) {$sum += $_}; print $sum / ($#n + 1), "\n"; } __DATA__ 2,800 2,900 3,000 3,000 2,988 5,000 5,495 4,999 4,995 4,900

    This gives:

    2937.6 5077.8
      Instead of $line =~ s/,//g; to remove commas, I would use a more generalized regex (but on each element, not on each line):
      $elem =~ s/[^\d+-e.]//g;

      This will remove any char that is not a digit, a +, a -, an 'e' (for numbers like 2e+31), or a point (.).

      Or, even better, use Number::Format:

      use Number::Format; $elem = unformat_number($elem);

      This is especially useful if an array is used instead of the $se# notation. You'd access each one through $se[#] instead, and you could do this:

      for (@se) { $_ = $unformat_number($_) }
      <-radiant.matrix->
      A collection of thoughts and links from the minds of geeks
      The Code that can be seen is not the true Code
      "In any sufficiently large group of people, most are idiots" - Kaa's Law
Re: Numbers aren't averaging correctly
by chester (Hermit) on Oct 06, 2005 at 02:26 UTC
    Are you parsing out the commas first? Perl auto-converts strings into numbers, but it doesn't like non-alphanumeric characters and when it finds some it just makes a guess.

    perl -le 'print "2,300" + "3,500"'

    Output:

    5

      It doesn't really just make a guess. It grabs all the numeric value it can find from the front of the string, and truncates anything past that. You can see the effect in action:

      my @strings = qw( 2,300 2.54xyz123 2e32abc3 2.34,23 ); for (@strings) { print "$_ => ", 0+$_, "\n"; }

      This prints:

      2,300 => 2 2.54xyz123 => 2.54 2e32abc3 => 2e+32 2.34,23 => 2.34
Re: Numbers aren't averaging correctly
by GrandFather (Saint) on Oct 06, 2005 at 02:32 UTC

    You have shown a tiny part of your code but not, I suspect, the part likely to contain the error. How about posting a chunk of code that can be run and that shows the problem. For strong preference use <DATA> to read some sample data from a __DATA__ section. It would also help a lot if your output columns lined up with the headings!

    It is highly likely that your problem is in code that splits or otherwise extracts the data from your input stream.

    There does seem to be a correlation between input containing commas and bogus averages. Is that a hint?


    Perl is Huffman encoded by design.
Re: Numbers aren't averaging correctly
by Hue-Bond (Priest) on Oct 06, 2005 at 18:06 UTC
    1 5,000 5,495 4,999 4,995 4,900 4,999 4.4 5,495

    I won't repeat your problem with commas but, have you noticed that in this line, min is wrong?

    --
    David Serrano