Monks,

I recently read the article Good Perl code is the best form of evangelism from perlbuzz.com:

    http://perlbuzz.com/2008/03/good-perl-code-is-the-best-form-of-evangelism.html

The article regards the second event in the Microsoft Scriptnet 2008 Winter Games, namely:

"to read in a text file of comma-separated values of ice skating scores, drop the highest and lowest scores from each skater, and show the top three skaters by the average of their remaining scores"

For example, the first two lines from the actual file is:

    Janko Cajhen,84,80,61,81,71,62,76
    Ryan Calafato,59,93,93,80,67,73,95

Their average scores would be:

    Janko Cajhen => 74
    Ryan Calafato => 81.2

The article provides one solution, and also references Jan Dubois' (ActiveState) solution as exemplary perl. I agree that both solutions are cleaner than Microsoft's.

I would be grateful for the communities feedback on the following solution. Is it good Perl? Why or why not?
use strict; sub sum {my $x; $x += $_ for @_; $x } sub avg {sum(@_)/@_} undef $/; open(my $F, 'skaters.txt'); my @x = map{[split/,/]}grep{/\S/}split/\n+/,<$F>; for(@x){ @$_ = ($_->[0],avg(@{[sort{$a<=>$b}@{$_}[1..$#$_]]}[1..$#$_-2])) } @x = sort{$b->[1] <=> $a->[1]}@x; printf "%-5s %-20s %-20s\n",$_+1,@{$x[$_]} for(0..2);
I have posted skaters.txt to the web:

    skaters.txt

Note that the text file does not require any fancy escapes for its comma separated values as it might if the ice skaters names were given in the last name, first name format. Or in something even more interesting using double quoted escapes like:

"Wojciech, ""the man"" Czupta",89,53,96,81,63,65,85

which would require some fancier unrolling like:
our $csvs = qr/(?:"(?:[^"]|"")*"|[^",])+/; sub csv_file_to_AoA { map{[csv($_)]}grep{/\S/}split/\n/,file_contents($_[0]) } sub csv { my @x = $_[0] =~ /(${csvs})(?:,|$)/g; for(@x){ /^"(.*?)"$/s ? $_ = $1 : undef; $_ =~ s/""/"/g; } @x } sub file_contents { local $/ = undef; open(my$F,$_[0])||die"cant open : $_[0]\n$!\n"; my $x = <$F> }
Do you think Microsoft did that on purpose so as not to expose just how bad their solution would be if the data were in this format? Or perhaps how much better Perl would be than VB Script or Powershell at parsing such data? Ultimately, what would be the most minimalistic and or elegant way to solve the problem given such data? That of the Cookbook?

Dave

In reply to winter games, perl, ice and bling by mobiusinversion

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.