PREVIOUS  TABLE OF CONTENTS  NEXT 

Predicting Sports Championships

Jon Orwant and Chris Nandor

Packages Used

LWP::Simple:        CPAN

People don't eat at dilapidated restaurants, and they don't like to fly on old-looking planes. If the restauranteur or airline doesn't keep up external appearances, there's a good chance that quality control suffers in the kitchen and cockpit too. The same is true for web sites: a broken web server indicates that something's wrong back at the fort.

Two years ago, the crack TPJ research team correctly predicted the winner of the Superbowl: the Denver Broncos. Our sole criterion was the web server chosen by the participating teams. The Broncos used Apache with mod_perl (http://perl.apache.org), demonstrating swiftness, integrity, thrift, intelligence, and foresight. It also showed that they weren't afraid of steroids, by which I mean the extraordinary medicinal boost provided by mod_perl event handlers.

Chris Nandor generalized the idea this year, providing a short program that polls American football, baseball, and hockey teams. Chris' program, perlpoll.plx, retrieves the list of sports team home pages from his web site at http://pudge.net/pudge/teams.html, and then retrieves the web page, performing an HTTP HEAD request to identify the web server. Then the program ranks their web servers using some heuristics of his own design (note his bias toward Mac servers). Here's the program:

#!/usr/bin/perl -s
# perlpoll.plx, pudge@pobox.com
use strict;
use vars '$DEBUG';
use LWP::Simple;
my($sport, $url, @page, %teams, $count, @order, @top);
$sport = uc(shift || 'nfl');

print "Polling web servers, please wait …\n"; 
@page = split /\015?\012/, get 'http://pudge.net/pudge/teams.html'; 
$_ = shift @page until m/<H2>$sport</;

while (shift(@page) =~ m|^<LI>(?:<A HREF="(.+?)">)?(.+?)<|) {
    my($team, $turl, $score) = ($2, $1, 0);
    my $server = (head $turl)[-1];
    for ($server) {
        /^Apache/ and $score += 10;
        /^NCSA/ and $score += 7;
        /^Netscape/ and $score += 5;
        /^Microsoft/ and $score -= 5;
        /(php|unix|mysql|ssl)/i and $score += 2;
        /\bmac(?:| ?os|perl|intosh)\b/i and $score += 10;
        $score += 50 while /perl/ig;
        $score += 2 while /mod_/ig;
    }
    $teams{$team} = [$server, $score, $turl];
    print "\u$team ($turl) = $server ($score)\n" if $DEBUG; }

@order = map  { $_->[0] } sort { $b->[2] <=> $a->[2] || $a->[1] cmp $b->[1] }
                              map  { [ $_, @{$teams{$_}} ] } keys %teams; 
@top = grep { $teams{$_}->[1] == $teams{$order[0]}->[1] } @order;

if (@top > 1) 
}
    @order[0..$#top] = tiebreak(@top);
} else {
    @top = grep { $teams{$_}->[1] == $teams{$order[1]}->[1] } @order;
    @order[1..@top] = tiebreak(@top) if @top > 1; }

sub tiebreak {
    my %tie;
    print "Executing tiebreaker <...>\n";
    for my $team (@_) {
        $tie{$team} = 100;
        local $_ = get $teams{$team}->[2];
        $tie{$team}--     while /<\s*(IMG|SCRIPT|EMBED)\b/gi;
        $tie{$team} -= 10 while /<\s*APPLET\b/gi;
        $tie{$team} -= 3  while /<\s*FRAME/gi;
        $tie{$team} -= 50 if /<\s*FRAME/i && ! /<\s*NOFRAME/i;
        $tie{$team} -= 50 if /require[\w ]+frame|frame[\w ]+require/i;
        print "  $team: $tie{$team}\n" if $DEBUG;
    }
    return sort { $tie{$b} <=> $tie{$a} } keys %tie; }

printf <<EOT, map ucfirst, @order[0, 1], $sport;

THE PERL SPORTS POLL

====================
Unless some team upgrades, the %s will defeat the 
%s in the next %s championship.

EOT

for (@order) {
    printf "%2.2d. %s ($teams{$_}->[1])\n", ++$count, ucfirst $_; 
}

perlpoll.plx takes one argument: the sport. Chris has team lists for football (nfl), baseball (mlb), and hockey (nhl). Here are his Superbowl predictions:

% perlpoll.plx nfl
Polling web servers, please wait ...

THE PERL SPORTS POLL

====================
Unless some team upgrades, the Denver Broncos will defeat the 
Green Bay Packers in the next NFL championship.

01. Denver Broncos (66) 
02. Green Bay Packers (64) 
03. Buffalo Bills (14) 
04. Atlanta Falcons (12) 
05. New Orleans Saints (12) 
06. Philadelphia Eagles (12) 
07. Dallas Cowboys (12) 
08. Detroit Lions (12) 
09. Oakland Raiders (12) 
10. New York Jets (7) 
11. San Francisco 49ers (5) 
12. Jacksonville Jaguars (5) 
13. San Diego Chargers (5) 
14. Chicago Bears (5) 
15. St. Louis Rams (0) 
16. Tampa Bay Buccaneers (0) 
17. Arizona Cardinals (0) 
18. New York Giants (0) 
19. Cincinnati Bengals (0) 
20. Tennessee Titans (-5) 
21. Kansas City Chiefs (-5) 
22. Baltimore Ravens (-5) 
23. Carolina Panthers (-5) 
24. Indianapolis Colts (-5) 
25. Miami Dolphins (-5) 
26. Washington Redskins (-5) 
27. New England Patriots (-5) 
28. Cleveland Browns (-5) 
29. Seattle Seahawks (-5) 
30. Minnesota Vikings (-5) 
31. Pittsburgh Steelers (-5)

The World Series will be played by two American League teams this year:

% perlpoll.plx mlb
Polling web servers, please wait
...Executing tiebreaker ...

THE PERL SPORTS POLL

====================
Unless some team upgrades, the Baltimore Orioles will 
defeat the Chicago White Sox in the next MLB championship.

01. Baltimore Orioles (64) 
02. Chicago White Sox (64) 
03. Tampa Bay Devil Rays (64) 
04. Cincinnati Reds (12) 
05. Anaheim Angels (12) 
06. Boston Red Sox (12) 
07. San Francisco Giants (12) 
08. Kansas City Royals (12) 
09. San Diego Padres (12) 
10. St. Louis Cardinals (12) 
11. New York Yankees (12) 
12. Arizona Diamondbacks (12) 
13. Texas Rangers (12) 
14. Toronto Blue Jays (10) 
15. Milwaukee Brewers (10) 
16. Montreal Expos (10) 
17. Pittsburgh Pirates (5) 
18. Minnesota Twins (5) 
19. Atlanta Braves (5) 
20. Florida Marlins (5) 
21. Philadelphia Phillies (5) 
22. Oakland Athletics (5) 
23. Los Angeles Dodgers (5) 
24. Cleveland Indians (0) 
25. Chicgo Cubs (0) 
26. Colorado Rockies (-5) 
27. New York Mets (-5) 
28. Detroit Tigers (-5) 
29. Houston Astros (-5) 
30. Seattle Mariners (-5) 

And finally, the Stanley Cup:

% perlpoll.plx nhl
Polling web servers, please wait 
... Executing tiebreaker ...

THE PERL SPORTS POLL

====================
Unless some team upgrades, the Buffalo Sabres will defeat 
the Carolina Hurricanes in the next NHL championship.

01. Buffalo Sabres (14) 
02. Carolina Hurricanes (14) 
03. San Jose Sharks (12) 
04. New York Rangers (12) 
05. Nashville Predators (12) 
06. Mighty Ducks of Anaheim (12) 
07. Ottawa Senators (12) 
08. Phoenix Coyotes (12) 
09. Boston Bruins (10) 
10. Atlanta Thrashers (10) 
11. Toronto Maple Leafs (10) 
12. Pittsburgh Penguins (10) 
13. Washington Capitals (10) 
14. Tampa Bay Lightning (10) 
15. New York Islanders (10) 
16. Florida Panthers (10) 
17. New Jersey Devils (10) 
18. Detroit Red Wings (5) 
19. Edmonton Oilers (5) 
20. Dallas Stars (5) 
21. Los Angeles Kings (5) 
22. Calgary Flames (5) 
23. Chicago Blackhawks (0) 
24. Vancouver Canucks (0) 
25. Montreal Canadiens (-5) 
26. Philadelphia Flyers (-5) 
27. St. Louis Blues (-5) 
28. Colorado Avalanche (-5)

__END__


PREVIOUS  TABLE OF CONTENTS  NEXT