Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Sports::Baseball::Teams

by ChemBoy (Priest)
on Sep 25, 2001 at 06:03 UTC ( #114460=sourcecode: print w/ replies, xml ) Need Help??

Category: Fun Stuff
Author/Contact Info ChemBoy
chemboy@perlmonk.org
Description: A module to provide a simple object-oriented interface to basic information about Major League Baseball teams, with a little overloading sugar for fun. See included POD for detailed information.
Update: added a missing method and the documentation for it, and addressed the symptoms (if not the cause) of one problem pointed out below. 10/02/2001
package Sports::Baseball::Teams;
use vars qw($VERSION);
use Carp;
use strict;
use overload '""'         => \&stringify,
             '=='         => \&compare,
             'eq'        => \&compare,
              'fallback' => "SOL";

$VERSION = 0.33;

###Initialization code

my $stringsare = "place";

my %MLTeams  =  (
            sea =>      {
                        fullname     => "Seattle Mariners",
                        place         => "Seattle",
                        teamname     => "Mariners",
                        league         => "American",
                        division    => "West",
                        abbrevs         => [ "Sea" ],
                        nick         => "M's",
                      },
            tex =>       {
                        fullname     => "Texas Rangers",
                        place         => "Texas",
                        city        => "Arlington",
                        teamname    => "Rangers",
                        division    => "West",
                        league        => "American",
                        abbrevs        => ["Tex"],
                      },
            ana =>       {
                        fullname    => "Anaheim Angels",
                        place        => "Anaheim",
                        teamname    => "Angels",
                        league        => "American",
                        division    => "West",
                        abbrevs        => ["Ana"],
                      },
            oak =>       {
                        fullname    => "Oakland Athletics",
                        place        => "Oakland",
                        teamname    => "Athletics",
                        league        => "American",
                        division    => "West",
                        abbrevs        => ["Oak"],
                        nick        => "A's",
                      },
            cle =>       {
                        fullname    => "Cleveland Indians",
                        place        => "Cleveland",
                        teamname    => "Indians",
                        league        => "American",
                        division     => "Central",
                        abbrevs        => ["Cle"],
                      },
            kan =>       {
                        fullname    => "Kansas City Royals",
                        place        => "Kansas City",
                        teamname    => "Royals",
                        league        => "American",
                        division     => "Central",
                        abbrevs        => ["KC"],
                      },
            min =>       {
                        fullname     => "Minnesota Twins",
                        place        => "Minnesota",
                        city        => "Minneapolis",
                        teamname    => "Twins",
                        league        => "American",
                        division     => "Central",
                        abbrevs        => ["Min"],
                      },
            det =>       {
                        fullname    => "Detroit Tigers",
                        place        => "Detroit",
                        teamname    => "Tigers",
                        league        => "American",
                        division     => "Central",
                        abbrevs        => ["Det"],
                      },
            chw =>       {
                        fullname     => "Chicago White Sox",
                        place        => "Chicago",
                        teamname    => "White Sox",
                        league        => "American",
                        division     => "Central",
                        abbrevs        => ["CWS", "CHA"],
                      },
            tor =>       {
                        fullname     => "Toronto Blue Jays",
                        place        => "Toronto",
                        teamname    => "Blue Jays",
                        league        => "American",
                        division     => "East",
                        abbrevs        => ["Tor"],
                      },
            tam =>       {
                        fullname     => "Tampa Bay Devil Rays",
                        place        => "Tampa Bay",
                        city        => "St. Petersburg",
                        teamname    => "Devil Rays",
                        league        => "American",
                        division     => "East",
                        abbrevs        => ["TB"],
                      },
            bos =>       {
                        fullname    => "Boston Red Sox",
                        place        => "Boston",
                        teamname    => "Red Sox",
                        league        => "American",
                        division     => "East",
                        abbrevs        => ["Bos"],
                      },
            nyy =>       {
                        fullname    => "New York Yankees",
                        place        => "New York",
                        teamname    => "Yankees",
                        league        => "American",
                        division     => "East",
                        abbrevs        => ["NYY", "NYA"],
                      },              
            bal =>       {
                        fullname    => "Baltimore Orioles",
                        place        => "Baltimore",
                        teamname    => "Orioles",
                        league        => "American",
                        division     => "East",
                        abbrevs        => ["Bal"],
                      },
            los =>       {
                        fullname    => "Los Angeles Dodgers",
                        place        => "Los Angeles",
                        teamname    => "Dodgers",
                        league        => "National",
                        division    => "West",
                        abbrevs        => ["LA"],
                      },
            sfo =>       {
                        fullname    => "San Francisco Giants",
                        place        => "San Francisco",
                        teamname    => "Giants",
                        league        => "National",
                        division    => "West",
                        abbrevs        => ["SF"],
                      },
            sdg =>       {
                        fullname    => "San Diego Padres",
                        place        => "San Diego",
                        teamname    => "Padres",
                        league        => "National",
                        division    => "West",
                        abbrevs        => ["SD"],
                      },
            ari =>       {
                        fullname    => "Arizona Diamondbacks",
                        place        => "Arizona",
                        city        => "Phoenix",
                        teamname    => "Diamondbacks",
                        league        => "National",
                        division    => "West",
                        abbrevs        => ["Ari"],
                      },
            col =>       {
                        fullname    => "Colorado Rockies",
                        place        => "Colorado",
                        city        => "Denver",
                        teamname    => "Rockies",
                        league        => "National",
                        division    => "West",
                        abbrevs        => ["Col"],
                      },
            stl =>       {
                        fullname    => "St. Louis Cardinals",
                        place        => "St. Louis",
                        teamname    => "Cardinals",
                        league        => "National",
                        division    => "Central",
                        abbrevs        => ["StL"],
                      },
            chc =>       {
                        fullname    => "Chicago Cubs",
                        place        => "Chicago",
                        teamname    => "Cubs",
                        league        => "National",
                        division    => "Central",
                        abbrevs        => ["ChC", "CHN"],
                          nick        => "Cubbies",
                      },
            cin =>       {
                        fullname    => "Cincinnati Reds",
                        place        => "Cincinnati",
                        teamname    => "Reds",
                        league        => "National",
                        division    => "Central",
                        abbrevs        => ["Cin"],
                      },
            mil =>       {
                        fullname    => "Milwaukee Brewers",
                        place        => "Milwaukee",
                        teamname    => "Brewers",
                        league        => "National",
                        division    => "Central",
                        abbrevs        => ["Mil"],
                          nick        => "The Brew Crew",
                      },
            hou =>       {
                        fullname    => "Houston Astros",
                        place        => "Houston",
                        teamname    => "Astros",
                        league        => "National",
                        division    => "Central",
                        abbrevs        => ["Hou"],
                          nick        => "'Stros",
                      },
            pit =>       {
                        fullname    => "Pittsburgh Pirates",
                        place        => "Pittsburgh",
                        teamname    => "Pirates",
                        league        => "National",
                        division    => "Central",
                        abbrevs        => ["Pit"],
                          nick        => "Bucs",
                      },
            atl =>       {
                        fullname    => "Atlanta Braves",
                        place        => "Atlanta",
                        teamname    => "Braves",
                        league        => "National",
                        division    => "East",
                        abbrevs        => ["Atl"],
                      },
            nym =>       {
                        fullname    => "New York Mets",
                        place        => "New York",
                        teamname    => "Mets",
                        league        => "National",
                        division    => "East",
                        abbrevs        => ["NYM", "NYN"],
                      },
            phi =>       {
                        fullname    => "Philadelphia Phillies",
                        place        => "Philadelphia",
                        teamname    => "Phillies",
                        league        => "National",
                        division    => "East",
                        abbrevs        => ["Phi"],
                      },
            fla =>       {
                        fullname    => "Florida Marlins",
                        city        => "Miami",
                        place        => "Florida",
                        teamname    => "Marlins",
                        league        => "National",
                        division    => "East",
                        abbrevs        => ["Fla"],
                          nick        => "Fish",
                      },
            mon =>       {
                        fullname    => "Montreal Expos",
                        place        => "Montreal",
                        teamname    => "Expos",
                        league        => "National",
                        division    => "East",
                        abbrevs        => ["Mon"],
                      },
             );
              

my %abbrs;

while (my ($key, $val) = each %MLTeams) {
    $abbrs{$key} = $key;
    foreach (@{$val->{abbrevs}}) { $abbrs{lc $_} = $key; }
}              

###Constructors

sub new {
    my $probe = lc $_[1];
    if (not exists $abbrs{$probe} ) {
        $@ = "No team matches probe $_[1]";
        return;
    }
    return bless \$probe, $_[0];    
}

sub new_fromscore {
    my $probe = lc $_[1];
    my ($ans);
    reset %MLTeams;
    while ( my ($key, $hash) = each %MLTeams) {
        if (   lc $hash->{place} eq $probe ) {
            $ans = $key;
        }
    }

    # special cases
    if    ($probe =~ /WS/i)      { $ans = "chw" }
    elsif ($probe =~ /Cubs/i)    { $ans = "chc" }
    elsif ($probe =~ /Mets/i)    { $ans = "nym" }
    elsif ($probe =~ /Yankees/i) { $ans = "nyy" }
    
    if ($ans) {return bless \$ans, $_[0] }
    else      {$@= "No team matches probe \"$_[1]\""; return}
}

###Accessor methods

sub getfullname {
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return $self->{fullname};
}

sub getplacename {
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return $self->{place};
}

sub getlocation {
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return exists $self->{city} ?  $self->{city} : $self->{place};
}

sub getteamname {
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return $self->{teamname};
}

sub getleague {
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return $self->{league};
}

sub getdivision {
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return $self->{division};
}

sub getnick {  # we do not guarantee that this is defined
    my $self = $MLTeams{$abbrs{${$_[0]}}};
    return $self->{nick}; 
}

sub getkey { #this is indicative of a design flaw, but an easy patch
    $abbrs{${$_[0]}}
}

###Class functions

sub stringify {
    if ($stringsare eq "place")   { $_[0]->getplacename() } 
    elsif ($stringsare eq "team") { $_[0]->getteamname()  }
    elsif ($stringsare eq "full") { $_[0]->getfullname()  }
}

sub compare { $_[0]->getkey() eq $_[1]->getkey() }

sub import {
    return unless $_[1];
    if    ($_[1] eq "-teamname") { $stringsare = "team"; }
    elsif ($_[1] eq "-fullname") { $stringsare = "full"; }
    else { warn "Sports::Baseball::Teams : unrecognized tag '$_[1]'\n"
+}
}

"Just another Perl hacker";

=pod

=head1 Synopsis

    use Sports::Baseball::Teams '-fullname';
    
    my $hometeam = Sports::Baseball::Teams->new("sea")
    my $villians = Sports::Baseball::Teams->new_fromscore("NY Yankees"
+);
    
    print "The $hometeam and $villians play in the ",
           $hometeam->getleague, " league.";

=head1 Constructors

=over 4

=item C<new>

Takes a string containing a two or three letter abbreviation 
for a major league team. The abbreviations must be reasonably 
standard, but some allowance is made for teams with multiple valid 
abbreviations (e.g. KC and Kan).  If no matching team is found, $@ is
set and undef returned.

=item C<new_fromscore>

Takes a string containing the team name found in the Boxscores on 
ESPN.com (e.g. "Boston", "Seattle", "NY Mets", "Chicago WS").  If no
matching team  is found, $@ is set and undef returned.

=back

=head1 Methods

=over 4

=item C<getfullname> 

Returns the full name of the team (e.g. "Seattle Mariners", "Tampa
Bay Devil Rays").

=item C<getplacename> 

Returns the place name of the team (e.g. "Seattle", "Tampa Bay").

=item C<getlocation> 

Returns the home city of the team (e.g. "Seattle", "St. Petersburg").

=item C<getteamname> 

Returns the team name (e.g. "Mariners", "Devil Rays").

=item C<getleague> 

Returns the league (National or American) of the team.

=item C<getdivision>

Returns the division (East, West or Central) of the team.

=item C<getnick>

Returns the nickname of the team if available (e.g. "M's", "Cubbies"),
if one is defined (otherwise undef).

=item C<getkey>

Returns the hash key for this team (principally for constructing 
URLs on ESPN.com).  This could legitimately be considered a nasty 
little hack.

=back

=head1 Overloaded operations

By default, objects in this class stringify to their place name 
(e.g. "Seattle", "Chicago").  This behavior can be changed to use 
either the full name or the team name by supplying an additional
argument of '-teamname' or '-fullname' to the C<use> statement, as in

    use Sports::Baseball::Teams '-teamname';

The equality operators (== and eq) are overloaded to operate as one
would expect (using the C<getkey> method above). 


=cut

Comment on Sports::Baseball::Teams
Download Code
Re: Sports::Baseball::Teams
by merlyn (Sage) on Sep 25, 2001 at 06:14 UTC
    I don't quite get this. From an object design standpoint, you have constant objects with no internal state, and an object class that is not particularly reusable because there's no real allowances for subclassable items. This means it's not really an object you want, but a package of subroutines instead. About the only thing you're using of the object-ness is the overloading.

    Worse yet, the following code fails (I think):

    ## first put all my favorite teams in a list: my @favorites = map { Sports::Baseball::Teams->new($_) } qw(Sea Tex An +a); ## now, let's notice a particular team playing tonight my $tonight = Sports::Baseball::Teams->new("Sea"); # seattle tonight ## let's see if this team playing tonight is one of my favorites: if (grep $_ == $tonight, @favorites) { ## THIS WON'T BE TRUE, BUT IT SHOULD BE }
    The reason is that a unique instance is not returned for a given team. Each new call asking for Seattle will return a distinct Seattle object. That's bad. Real bad.

    There's your initial review. To get more details, you'll have to pay me. {grin}

    If you wanna learn objects well, get Squeak and play with it a bit. Smalltalk rocks.

    -- Randal L. Schwartz, Perl hacker

Re: Sports::Baseball::Teams
by Zaxo (Archbishop) on Sep 25, 2001 at 09:25 UTC

    This is a credible effort and I enjoyed looking at it. I'd like to make a few comments about your design.

    Objects aside, it is good to separate data from code. Here, the ability to read a list of team data from a file, and to use as default the MLB data from a __DATA__ section, would be one approach to generalizing the module. The separation would support introducing Team as an object and feeding the data to a constructor.

    You have a well-defined level of abstraction for OO. All the information needed for identifying teams in a box score are here. All the teams that can conceivably play an official game with each other are listed. You omit complications like roster, management, ownership, and farm system.

    OO design models some abstraction which is always informed by the size of the problem space. By definition, a module designer does not have the luxury of a well-defined problem space. With modules, the measure of success is the number of unanticipated ways the module can be used. Could a fantasy league use the module? Could a high school conference? Could ESPN's box score server? In that last case, you have the problem that the server may run for months or years. On the fly, can it handle league expansion and movement of teams?

    There are many distinct Teams, but each is unique to itself. The constructor should produce a single instance, and all methods should deal in references to that instance. This is a restatement of merlyn's principal objection.

    Thanks for posting this interesting module. I found it thought-provoking.

    After Compline,
    Zaxo

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://114460]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2014-07-26 07:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (175 votes), past polls