Getting Insight from Data: Baseball

Big Data is cited by many prognosticators as a major growth area in computer science over the next decade. While definitions of Big Data abound, the basic idea is that data is being collected as such a rate and with such volume now that traditional ways of saving and analyzing it no longer suffice.

(Neal Ford once told me about a bioengineering project that collects roughly 5 exabytes of data every few days, and as scientists they never want to throw anything away. Their simplest solution for storing it all may be to build a dedicated hard drive factory next door.)

The real issue, though, is not how much data you have. It’s what you do with it. How do you understand your situation when the data is voluminous, but may contain errors, omissions, and other problems?

This is not a new problem, and fortunately we have a great field of examples to use as a model. If you want to understand how to get insight from large amounts of data, look at baseball.

Even a brief summary of the history of sabermetrics (a term coined by Bill James himself, based on SABR — the Society for American Baseball Research) would go well beyond the scope of a simple blog post. If you’ve seen the Moneyball movie or read the book, you’ve got the general idea. Suffice it to say that sabermetrics is an attempt to understand how to win baseball games by focusing on the data, rather than on conventional wisdom.

Some of the interesting observations made by the stats community include ideas that seem blindingly obvious but were ignored for years:

1. Outs are everything, so don’t give them away unnecessarily. Baseball doesn’t have a time limit, and you can’t stall or play a prevent defense. You keep playing until 27 outs are recorded.

2. That means if you steal at less than about a 70% success rate, don’t run. It doesn’t matter how many bases you steal if you’re giving up too many by getting caught.

3. Similarly, bunting is done way, way too often. Moving a runner over from first to second (or sometimes from second to third) isn’t worth giving away an out. Or, as the stat guys say, if you play for one run, that’s likely all you’ll get, and most of the time not even that.

4. Pitcher wins are highly dependent on elements outside the pitcher’s control, like runs scored by his offense or errors made by the defense. Wins are a lousy measure of pitcher skill. Frankly, ERA (earned run average) isn’t that much better, because there are many subjective judgements in there, too (try looking at the difference between earned and unearned runs sometime and the arbitrariness of it all will make your head spin).

5. RBIs are so dependent on where you are in the batting order that they’re a lousy measure of hitting skill. If you are a major leaguer and you bat fourth, fifth, or sixth, you’re going to get a lot of RBIs no matter what you do. That’s why OBP (on base percentage, which measures how often you avoid giving up an out) is far better correlated with wins.

Incidentally, that was one of themes of the Moneyball movie. The idea was to get the players to get on base as much as possible, placing a higher than normal value on walks. Since OBP was much more important to wins than RBIs, the Oakland A’s could replace stars that left by filling in their on-base contributions rather than worrying about runs batted in.

As it turned out, they placed too little emphasis on defense. In the movie they moved Scott Hatteberg to first base where he had no defensive skills at all just to keep his bat in the lineup. Nowadays they would care more about the defense they gave up.

Actually, the real theme of Moneyball was to identify players that were undervalued based on traditional metrics and use them to build a successful team cheaply. At the time, OBP was a market inefficiency.

Rather than go on, I want to mention that there’s a reason I’m writing this post today. Tonight is the first game of the World Series between the Detroit Tigers and the San Francisco Giants, and from a sabermetric point of view it has all the elements of a potential classic.

I want to mention a couple baseball writers and what they’ve said about the upcoming series. First, Jonah Keri (author of The Extra 2%) wrote a great preview article today at Grantland discussing the Giants. Rany Jazayerli (a medical doctor cursed by following the Kansas City Royals) wrote a similar article on the Tigers. Both are well worth reading.

My favorite writer of all, however, is Joe Sheehan. He’s brilliant, and controversial, and fascinating to follow on Twitter. He writes a newsletter that I’m very happy to subscribe to, and his World Series preview came out today. I hope he won’t mind if I quote from it a bit, just to demonstrate the difference between mindlessly quoting statistics and drawing true insight from them.

The Tigers beat you by striking you out and not letting you exploit their poor defense.

He builds up to this by showing how the strike-out rate of the Detroit pitching staff is second in the league, and that they exceeded the league record in total strikeouts (coming in second to the Rays, actually). He also points out that their defense is so bad (they are the worst defense ever to reach the World Series) that the high strike out numbers are partly padded by having to face more batters than they should have had to, given the bad defense.

The Giants beat you by putting the ball in play and making you chase it.

The Giants were last in MLB in home runs. There were second in batting average and fourth on OBP. They have a park that suppresses homers and they play accordingly. On the other hand, they have a very low strike out rate. By the stat called equivalent average, they were the third best offense in baseball despite never hitting home runs.

As it turned out, the Tigers — after winning a weak division — caught two postseason opponents ill-equipped to take advantage of their poor defense.

The A’s struck out a lot and the Yankees were almost entirely driven by homers. The Giants will be completely opposite.

There’s plenty more, but this is the flavor of the observations. Note that none of the articles I mentioned are full of statistics. There are few choice stats presented with the goal of making a clear argument. That’s insight.

By the way, most organizations in baseball know this. The conflict between the scouts and the stats guys demonstrated in Moneyball is largely over (with the great exception being the Kansas City Royals, who not coincidentally keep coming in last). There’s one major group who still doesn’t “get it”, though, and that’s the media.

I cannot fathom why the networks continually put “analysts” in the broadcast booth who are completely unaware of the last twenty years of baseball research. In fact, they often disdain anything learned from studying the game as tricks with statistics. The greatest irony (as mentioned by Joe Sheehan many times) is that no stats guy is anywhere near as wedded to a particular metric as the so-called “traditionalists” care about RBIs or pitcher wins. If you watch the game broadcasts, you’ll see meaningless statistic after meaningless statistic based on small sample size (batter A is 2 for 7 against pitcher B) paraded out as though it meant anything, completely ignoring what’s now viewed as truly important.

For example, you’re guaranteed tonight to hear tons about the Giants’ “momentum” (which demonstrably doesn’t exist) or the effects of the Tigers’ long layoff since winning the ALCS, neither of which matter at all. Instead, the real story is whether the Giants can put enough balls in play to take advantage of the Tigers’ poor defense, or whether the Tigers’ great strike-out pitchers can keep them from doing it. It’s also whether the Tigers’ line up, which is dominated by a few stars, will be able to beat the Giants’ pitching, which has relatively weak starters but lots of bullpen depth, and the excellent San Francisco defense.

I have no vested interest in either team. Frankly, if it wasn’t for what I learn by reading those writers and others like them, I probably wouldn’t care at all. Now I’m excited to watch the interplay of two diametrically contrasting styles. Even better, I’m looking forward to the snarky comments by the great writers I follow on Twitter during the games (nobody does snark like a good baseball writer).

Do I have a prediction? Please. I’m just happy the Yankees got swept. That almost, but not quite, made up for the disaster that was the Red Sox season. Still, one of the Red Sox owners claims part of the team’s problem was that they didn’t listen to Bill James enough, so that gives me hope for next year.

Also, I’m really looking forward to the articles written after each game, which will be beautiful demonstrations of how to make decisions based on insight rather than just quoting statistics as though they were significant in themselves. I’ll just have the mute button ready whenever Tim McCarver starts talking.

—-

Joe Sheehan’s Newsletter is sent via email. An annual subscription is available at http://joesheehanbaseball.blogspot.com.

Twitter handles:
Joe Sheehan (@joe_sheehan)
Rany Jazayerli (@jazayerli)
Johan Keri (@jonahkeri)
Keith Law (@keithlaw)
Joe Posnanski (@JPosnanski)

Writing json output from a groovlet

Read more of this post

Groovy StubFor magic

I finished revising the testing chapter in Making Java Groovy (the MEAP should be updated this week), but before I leave it entirely, I want to mention a Groovy capability that is both cool and easy to use. Cool isn’t the right word, actually. I have to say that even after years of working with Groovy, what I’m about to describe still feels like magic.

Here’s the issue: I have a class that uses one of Google’s web services, and I want to test my class even when I’m not online. That means I need to mock the dependency, which isn’t all that hard. The problem is that there’s no explicit way to get my mock object into my own service. Yet, with Groovy’s MockFor and StubFor classes, I can mock a dependency, even when it’s instantiated as a local variable inside my class.

Let me show you the code. I’ll start with a simple POGO called Stadium:

class Stadium {
    String street
    String city
    String state
    double latitude
    double longitude
    
    String toString() {
        "($street,$city,$state,$latitude,$longitude)"
    }
}

I use this in my Groovy Baseball application, which accesses MLB box scores online and displays the daily results on a Google Map. The Stadium class holds location data for an individual baseball stadium. When I use it, I set the street, city, and state and have the service compute latitude and longitude for me.

My Geocoder class is based on Google’s restful geocoding service.

class Geocoder {
    String base = 'http://maps.google.com/maps/api/geocode/xml?'
   
    void fillInLatLng(Stadium stadium) {
        String urlEncodedAddress =
                [stadium.street, stadium.city, stadium.state].collect {
                    URLEncoder.encode(it,'UTF-8')
                }.join(',+')
        String url = base + [sensor:false, address:urlEncodedAddress].collect { it }.join('&')
        def response = new XmlSlurper().parse(url)
        String latitude = response.result.geometry.location.lat[0] ?: "0.0"
        String longitude = response.result.geometry.location.lng[0] ?: "0.0"
        stadium.latitude = latitude.toDouble()
        stadium.longitude = longitude.toDouble()
    }
}

First I take the stadium’s street, city, and state and add them to a list. Then the collect method is used to apply a closure to each element of the list, returning the transformed list. The closure runs each value through Java’s URLEncoder. In looking at the Google geocoder example, I see that they separate the encoded street from the city and the city from the state using “,+“, so I do the same using the join method.

The Google geocoding service requires a parameter called sensor, which is true if the request is coming from a GPS-enabled device and false otherwise. In the Groovy map, I set its value to false, and set the value of the address parameter to the string from the previous line. The collect method on the map converts each entry to “key=value“, so joining with an ampersand and appending to the base value gives me the complete URL for the stadium.

Most restful web services try to provide their data in a format requested by the user. The content negotiation is usually done through an “Accept” header in the HTTP request, but in this case Google does something different. They support only XML and JSON output data, and let the user select which one they want through separate URLs. The base URL in the service above ends in xml. Google lists the JSON version as preferred, but that’s no doubt because they expect the requests to come through their own JavaScript API. I’m making the request using Groovy, and the XmlSlurper class makes parsing the result trivial.

(Since Groovy 1.8, the JsonSlurper class also makes parsing JSON trivial, and I have a version that does that, too, but the difference really isn’t significant here.)

The resulting block of XML that is returned by the service is fairly elaborate, but as you can see from my code, the data is nested through the elements GeocodeResponse/result/geometry/location/lat and GeocodeResponse/result/geometry/location/lng. After invoking the parse method (which returns the root element, GeocodeResponse), I just walk the tree to get the values I want.

I do have to protect myself somewhat. The Google service isn’t nearly as deterministic as I would have expected. Sometimes I get multiple locations when I search, so I added the zero index to make sure I always get the first one. Also, some time during the last year Google decided to start throttling their service. I have a script that uses the Geocoder for all 30 MLB stadiums, and unfortunately it runs too fast (!) for the Google limits. I know this because I start getting back null results if I don’t artificially introduce a delay. That’s why I put in the Elvis operator with the value 0.0 if I don’t get a good answer.

So much for the service; now I need a test. If I know I’m going to be online, I can write a simple integration test as follows:

import static org.junit.Assert.*;
import org.junit.Test;

class GeocoderIntegrationTest {
    Geocoder geocoder = new Geocoder()
    
    @Test
    public void testFillInLatLng() {
        Stadium google = new Stadium(street:'1600 Ampitheatre Parkway',
            city:'Mountain View',state:'CA')
        geocoder.fillInLatLng(google)
        assertEquals(37.422, google.latitude, 0.01)
        assertEquals(-122.083, google.longitude, 0.01)
    }
}

I’m using Google headquarters, because that’s the example in the documentation. I invoke my Geocoder’s fillInLatLng method and check the results within a hundredth of a degree.

(The fact that the Google geocoder returns answers to seven decimal places is evidence that their developers have a sense of humor.)

Now, finally, after all that introduction, I reach the subject of this post. What happens if I’m not online? More to the point, how do I test the business logic in the fillInLatLng method without requiring access to Google?

What I need is a mock object, or, more precisely, a stub.

(A stub stands in for the external dependency, called a collaborator. A mock does the same, but also validates that the caller accesses the collaborator’s methods the right number of times in the right order. A stub helps test the caller, and a mock tests the interaction of the caller with the collaborator, sometimes called the protocol. Insert obligatory link to Martin Fowler’s “Mocks Aren’t Stubs” post here.)

In my Geocoder class, the Google service is accessed through the parse method of the XmlSlurper. Even worse (from a testing point of view), the slurper is instantiated as a local variable inside my fillInLatLng method. There’s no way to isolate the dependency and set it from outside, either as an argument to the method, a setter in the class, a constructor argument, or whatever.

That’s where Groovy’s StubFor (or MockFor) class comes in. Let me show it in action. First, I’ll set up the answer I want.

String xml = '''
    <root><result><geometry>
        <location>
            <lat>37.422</lat>
            <lng>-122.083</lng>
        </location>
    </geometry></result></root>'''
    
def correctRoot = new XmlSlurper().parseText(xml)

The xml variable has the right answer in it, nested appropriately. I use the XmlSlurper to parse the text and return the root of the tree I want.

Now I need a Stadium to update. I deliberately put in the wrong street, city, and state to make sure that I only get the right latitude and longitude if I insert the stub correctly.

Stadium wrongStadium = new Stadium(
    street:'1313 Mockingbird Lane',
    city:'Mockingbird Heights',state:'CA')

(Yes, that’s a pretty obscure reference. For details, see here. And yes, I’m old. If you’re in the right age group, though, you now have the show’s theme song going through your head. Sorry.)

The next step is to create the stub and set the expectations.

def stub = new StubFor(XmlSlurper)
stub.demand.parse { correctRoot }

The StubFor constructor takes a class as an argument and builds a stub around it. Then I use the demand property to say that when the parse method is called, my previously computed root is returned rather than actually going over the web and parsing anything.

To put the stub into play, invoke its use method, which takes a closure:

stub.use {
    geocoder.fillInLatLng(wrongStadium)
}

That’s all there is to it. By the magic of Groovy metaprogramming, when I invoke the parse method of the XmlSlurpereven when it’s instantiated as a local variable — inside the use block the stub steps in and returns the expected value.

For completeness, here’s the complete test class:

import static org.junit.Assert.*
import groovy.mock.interceptor.StubFor
import org.junit.Test

class GeocoderUnitTest {
    Geocoder geocoder = new Geocoder()
    
    @Test
    public void testFillInLatLng() {
        Stadium wrongStadium = new Stadium(
            street:'1313 Mockingbird Lane',
            city:'Mockingbird Heights',state:'CA')
        
        String xml = '''
        <root><result><geometry>
            <location>
                <lat>37.422</lat>
                <lng>-122.083</lng>
            </location>
        </geometry></result></root>'''
        
        def correctRoot = new XmlSlurper().parseText(xml)
        
        def stub = new StubFor(XmlSlurper)
        stub.demand.parse { correctRoot }
        
        stub.use {
            geocoder.fillInLatLng(wrongStadium)
        }
        assertEquals(37.422, wrongStadium.latitude, 0.01)
        assertEquals(-122.083, wrongStadium.longitude, 0.01)
    }
}

Since I’m only calling one method and only calling that method once, a stub is perfectly fine in this case. I could invoke the verify method if I wanted to (MockFor invokes verify automatically but StubFor doesn’t), but it doesn’t really add anything here.

There is one limitation to this technique, which only comes up when you’re doing the sort of Groovy/Java integration that is the subject of my book. You can only use StubFor or MockFor on a class written in Groovy.

All this code is available in the book’s Github repository at http://github.com/kousen/Making-Java-Groovy. This particular example is part of Chapter 5: Testing Java and Groovy.

As a final note, I should say that I dug into all of this, worked out all the details, and tried it in several examples. Then I finally did what I should have done all along, which was look it up in Groovy In Action. Of course, there it was laid out in detail over about five pages. Someday that will stop happening to me. ūüôā

Live blogging World Series Game 4: Yankees/Phillies

11:48 pm: It’s over. ¬†The Yankees win 7-4, as the Phillies hit three balls to Mark Teixeira, the best fielder the Yankees have.

Cliff Lee now has to save the Phillies season. ¬†Even if he does, though, it’s hard to imagine the Phillies beating the Yankees three straight times. ¬†That just doesn’t happen in the playoffs.

Except in 2004, of course. ūüôā

Johnny Damon made himself a ton of money tonight. ¬†His arm is dead, his range is lousy and getting worse, and his hitting is fading badly. ¬†But he turned a single into essentially a triple at a critical time in the World Series, so somebody will give him a big contract this off season. ¬†I only pray it’s not the Sox.

As I’ve said before, I root for several ex-Sox: Nomar, Pedro, even Manny. ¬†But I will never, ever forgive Johnny Damon.

11:44 pm: The irony is that assuming Rivera can hold a 3-run lead (and we’ll have major news if not), then the win actually goes to Joba, who gave up the tying run. ¬†Yeah, that’s fair.

11:41 pm: Posada singles home two runs and is tagged out trying to stretch it into a double. ¬†But now it’s 7-4 Yankees. ¬†The game, and very probably the series, is over.

11:38 pm: A-Rod doubles, as he has all this post-season. ¬†It’s now 5-4 Yankees.

11:37 pm: And he hits Teixeira!  Now we have runners on the corners with two outs.  We now have A-Rod up.

The funny part is, if A-Rod fails here, he’s a choker, but they’ll conveniently forget that Jeter just struck out himself.

11:35 pm: Damon stole 2nd, then saw that nobody was covering 3rd (because of the defensive shift for Tex) and just about walked there.  Now a wild pitch is a disaster.  Lidge has to be careful with his breaking ball.

11:33 pm: Lidge goes full count against Damon, too.  Damon fouls off 2 pitches and then singles.  Here comes Teixeira, which is not good.

11:29 pm: The guys at Baseball Prospectus are incensed that Girardi let his team blow a 1-run lead without getting either Hughes or Rivera into the game.  They hate the way so many teams manage to the save statistic.

Meanwhile, Lidge throws the same low strike that’s worked all game, but doesn’t get it against Jeter. ¬†Instead the count goes full. ¬†(And some people say baseball is boring. ¬†As Joe Posnanski says, it is boring, and then it’s not. ¬†That’s what makes it great.)

Lidge gets the K on Jeter.  Wow.

11:25 pm: Joe Buck is doing his best to reverse jinx Lidge by reciting all the bad statistics from this year (11 blown saves, etc). ¬†We’ll see if it works.

It works on Matsui anyway, who pops to short.

11:23 pm: Here comes Brad Lidge.  As a Sox fan, I was very nervous this year every time Papelbon came in, and the playoffs showed I was right.  That is nothing, NOTHING, compared to what the Phillies fans are feeling right now.

11:21 pm: End of the 8th.  Talk about your true outcomes.  Joba goes K, K, HR, K.

(For those who don’t know, the “three true outcomes” are K, HR, and BB. ¬†For each of them, the fielders might as well not have bothered to come out of the dugout.)

11:19 pm: Werth K’s on a high, inside pitch. ¬†All fastballs from Joba. ¬†Then Ibanez K’s too.

And just when it looked like Joba was going to strike out the side, Pedro Feliz takes a 3-2 fastball out of the park. ¬†It’s tied again, 4-4.

11:13 pm: It’s Joba time! ¬†Now anything can happen, from three straight K’s to three straight HR’s.

11:10 pm: Middle of the 8th. Ryan Madson takes over for the Phillies, against A-Rod, Posada, and Cano.

He K’s A-Rod without ever pitching him inside (where he’s supposed to be vulnerable). ¬†He walks Posada, and then Cano drops a total bloop down the LF line between three fielders. ¬†Bad, bad luck.

Swisher K’s on a very nice pitch that curved into the strike zone, and got Gardner to pop up to end the inning.

It’s Werth plus the bottom of the order in the 8th, hoping to score before Rivera comes in.

10:57 pm: Ryan Howard takes a strike on a off-speed ball, then a strike on a fastball strike. ¬†Howard finally pops up yet another outside slider, and it’s inning over. ¬†At the end of 7 innings, it’s 4-3 Yankees.

Now we get to see what the middle of the Yankees line up can do against the Phillies relievers.

10:54 pm: Utley crushes a ball into the stands and it’s a one-run game. ¬†Yankees 4-3. ¬†I was going to say that Girardi will probably let CC face Howard, since he still hasn’t done anything with the slider, but no, he’s gone. ¬†That last pitch was a hanger, though, so that may have had something to do with it.

Now let’s see what Howard (and maybe Werth) can do with Damaso Marte.

10:50 pm: This has GOT to be the inning for the Phillies.  CC is almost done and the top of the lineup is up.

Two hard hit balls right at fielders (one to 3B, one to RF) and it’s two outs. ¬†It’s time for Utley/Howard/Werth to win it. ¬†Or not.

10:43 pm: Look, I read all the Sherlock Holmes stories as a kid, and again in grad school when I was trying to avoid my thesis.  I never remember him diving out of a window into the Thames.

10:41 pm: 7th inning stretch time. ¬†CC bats to start the top of the 7th, so he’s definitely staying in, even after 95 pitches. ¬†I guess Girardi really doesn’t trust his set-up men. ¬†Makes you wonder, though, how easy it will be for CC to come back for a game 7.

Chan Ho Park comes in for the Phillies.

Jonah Keri points out that though Blanton looked good, he still gave up 4 runs in 6 innings.  He definitely thinks Lee should have pitched instead.

10:33 pm: End of the 6th. ¬†Feliz moves to 2nd on Ruiz’s ground out, bringing in our first pitch hitter, Ben Francisco. ¬†He flies out quietly to CF on the first pitch. ¬†CC had now given up only 2 runs in 6 innings, and Rivera will pitch the 9th. ¬†CC will no doubt start the 7th, too. ¬†The window of opportunity is closing, especially if the Phillies left-handed batters can’t figure out how to lay off that low, outside slider.

10:30 pm: Gardner replaces Cabrera in CF when Cabrera pulls up lame running to 1B. ¬†Better defense, but lousy hitter. ¬†If the Phils don’t start hitting, though, it’s not going to matter.

Feliz gets on with one out, ensuring that the pitcher’s spot will indeed come up this inning.

10:25 pm: Middle of the 6th. ¬†This time Howard really did catch the ball in the air (I think), but he flipped to Blanton anyway for the out. ¬†McCarver is sure it short-hopped, but I thought it looked the other way. ¬†Turns out it didn’t matter.

Swisher swung hard at ball 4, but Blanton walks him anyway.  Blanton gets Cabrera, though, to end the inning.

He’s up to 93 pitches, and the pitcher’s spot is due up 4th in the bottom of the 6th. ¬†If the spot comes up, he should be done. ¬†If not, well, they sent Pedro out for the 7th when they shouldn’t have…

At last, the Cialis commercials have started.  Bummer.

10:13 pm: End of the 5th, still 4-2 Yankees. ¬†I’d never heard of a “quick pitch” before this series, but now it’s happening a lot. ¬†Sabathia got Utley on one, apparently, pitching before he was ready. ¬†Now it’s Howard’s turn to do something spectacular, but he pops up instead. ¬†Sigh.

McCarver said that Jeter came out to Sabathia to make sure he wasn’t changing signs without letting Jeter know, but that’s not at all what it looked like he was saying.

Werth just missed crushing a pitch for another HR.  He strikes out instead.

Sabathia’s pitch count is now well into the 80’s. ¬†He isn’t showing any signs of fatigue that I can see. ¬†He’ll definitely go one more inning. ¬†If it’s quick, maybe two.

10:04 pm: Maybe the problem is that I think of the strike zone as an absolute, when in reality it’s a probability distribution. ¬†The two inches off the right side of the plate are a strike about 75% of the time.

(Keeping in mind that 80% of all statistics are made up on the spot, of course.)

10:03 pm: In case you’re wondering, the game moves a LOT faster when you’re live blogging it.

After 76 pitches, it’s now two on and nobody out for Sabathia. ¬†This is a big opportunity for the Phils. ¬†(I know — duh. ¬†I plead too much exposure to Buck/McCarver.)

9:55 pm: Middle of 5th. ¬†A-Rod hits a soft fly to end the inning. ¬†An inside pitch very nearly hit him, though he didn’t try very hard to get out of the way. ¬†At least we’re spared that controversy.

The Avatar movie is being hyped relentlessly.  I remember hearing that the initial trailer was very badly received.

Here’s the thing, though. ¬†The greatest trailer I ever saw, and it was truly a work of art, was for Star Wars I: The Phantom Menace. ¬†That just about sums it up.

9:54 pm: Blanton gets Tex to fly out, leading to A-Rod with two men on and two out. ¬†If Blanton doesn’t get him, it probably doesn’t matter what the pitch count is.

9:51 pm: McCarver: “Lead-off walks always score.” ¬†I never would have guessed.

That’s it — the Phillies outfielders are definitely playing too deep. ¬†Damon bloops a single to make it 4-2 Yankees.

9:49 pm: Utley tries to make a spectacular flip to 2nd on a grounder by Cabrera but can’t do it. ¬†Now Yankees have 1st and 2nd with nobody out, but Sabathia up. ¬†Sabathia can’t get the bunt down, fouling the bunt with two strikes and bringing up Jeter.

Tweeps are understandably upset that Jeter won the Hank Aaron award ahead of Joe Mauer, but he singles here to make it 3-2 Yankees.

9:44 pm: Ugh. Swisher walks on 4 pitches, though two of them were arguable strikes. ¬†The zone is definitely low, but I can’t tell if it’s outside or not any more.

9:42 pm: I don’t understand why the Yankees didn’t tag Howard anyway, if they thought he missed the plate. ¬†Sure, Posada threw to 2nd to try to stop the advance, but they could have thrown back, right? ¬†After Posada threw would have been a good time for Howard to go back and touch the plate, too.

9:40 pm: End of the 4th, tied 2-2. McCarver mentions that Feliz is slumping against left-handed pitching, so naturally he lines the next pitch for a single. ¬†Howard challenges Damon’s arm (of course) and beats the throw, assuming he ever touched the plate, which he probably didn’t. ¬†Feliz takes 2nd on the throw.

Then an intentional walk, but it’s to get to the pitcher so maybe that’s okay. ¬†Blanton obliges by striking out on 3 pitches.

Howard finally gets a hit. ¬†Sabathia tried yet another slider, but this one got a lot of the plate. ¬†Then he actually stole 2nd when Posada, clearly surprised, couldn’t get the ball out of his glove. ¬†So the lead-off hitter is on 2nd with nobody out.

In the manager interview, Girardi says C.C. could go 100 to 120 pitches. ¬†But the real question is whether he’ll be able to control them as he tires. ¬†We’re up to 66 pitches after 4 innings.

9:26 pm: Middle of 4th.  Blanton looks great and has only thrown 44 pitches.

McCarver says Posada couldn’t argue his strike three call because he has to get behind the plate and hope for consistency, but maybe he didn’t argue because it was a strike.

A-Rod flies out, to a big cheer from the crowd.  Apparently he annoys Phillies fans as much as Sox fans.

So we have a commercial based on Wayne’s World (at least 20 years old) and one based on Lassie (double that or more). ¬†Either the advertising people are old, or they think the target audience is old. ¬†I guess that figures, since the kids can’t make it to the end of the game. At least the Cialis commercials haven’t started yet.

9:18 pm: End of 3rd. ¬†Joe Buck reminds us that lead-off hitters are important. ¬†It’s that kind of insight and analysis that makes a World Series announcer.

Teixeira makes another good defensive play at 1B. ¬†After watching the travesty the Yankees got from their first basemen last year, it’s been remarkable watching Tex this year. ¬†Unfortunately.

This inning the high pitches were strikes.  Maybe the ump has a dinner date tonight.

1-2-3 inning for Sabathia, who has thrown 46 pitches after 3.

9:10 pm: End of 2 1/2. ¬†Great play by Feliz on the Jeter grounder to 3rd. I love the fact that they said yesterday that Pedro Feliz has the most accurate arm of any 3B in the league. ¬†That’s a great asset to have.

Another ball call on a strike, followed by a strike call on a ball.  Make up call or just incompetence?  You decide.  Actually, it looks like this ump has a very low strike zone that extends about 2 inches outside, too.

9:00 pm: End of 2nd. Jonah Keri points out that C.C. is getting 15 mph separation between his fastball and his slider. ¬†That’s a lot. ¬†We’ll see if he can maintain it as the innings add up. ¬†The Phillies really need to be patient to let the pitch count climb.

The game is moving right along. ¬†I expect it to really drag later, especially when the Yankees’ manager (Girardi) starts shuffling relievers. ¬†The key for the Phillies is to get C.C. out of there early enough that they can crush the bullpen before Rivera comes in. ¬†The opposite is true, too, except that the Yankees are probably salivating at the prospect of seeing Brad Lidge in a close game.

8:55 pm: Middle of the 2nd. Blanton gets the outs despite the fact the Yankees are making solid contact. ¬†The hard hits are going to right, and easy flies are going to left. ¬†Again, small sample size, but we’ll see if it holds.

You also knew the FOX dweebs would find a way to promote Brett Favre again.  I expect to hear about him at least a dozen more times before the night is out.

8:47 pm: That outside slider is still getting Phillies out.  2-1 Yankees at the end of 1.

The pitch count is adding up for Sabathia.  Of course, Pettitte had over 50 pitches after two innings yesterday, and we know how that worked out.

The idiot in the new Windows 7 commercial makes me want to buy a Mac. ¬†That’s not good.

8:45 pm: Ouch. ¬†Another K for Howard. ¬†That was a really, really good pitch, though. ¬†The ump’s strike zone is low and outside, and so was that pitch. ¬†No way he could take it.

If they actually intentionally walk Werth, Joe Posnanski’s head will explode. ¬†McCarver thinks they only reason they don’t do it is because it’s still the first inning. ¬†The real reason not to do it is that it’s stupid. ¬†Intentional walks are almost always a bad idea, and this would be no exception.

8:42 pm: Utley doubles home Victorino, and it’s 2-1 Yankees, bringing up Ryan Howard. ¬†TV lives on small sample sizes (tiny in this case), so they keep bringing up the possibility of another K.

Posada is jumping around to catch Sabathia, implying C.C. is having trouble finding his targets. ¬†We’ll see if he settles down. ¬†Maybe both managers were wrong — Lee should be in there, and C.C. shouldn’t. ūüôā

8:31 pm: End of the top of the first, 2-0 Yankees.  I liked the way the throw from left field hit Damon in the head.

Baseball is such a game of inches.  Utley made a great grab of that lead-off hit by Jeter, but slipped when he tried to get up to throw him out.  If he makes that out, it might have been a different inning.

8:30 pm: “The opening pitch was brought to you by ….” ¬†The stupid promotions begin.

A-Rod plunked again. ¬†McCarver thinks it was an accident, but it’s the third time in two days. ¬†The umps warned both sides, so no obvious pay back. ¬†We’ll see what the Yankees do anyway. ¬†They certainly can’t afford to have Sabathia thrown out. ¬†Advantage Phillies, other than the fact A-Rod is now on base.

8:20 pm: Tim McCarver thinks the Phillies should have pitched Cliff Lee on short rest, so not doing so must be the right move.

Okay, just because he says it doesn’t mean it’s automatically wrong. ¬†But it’s awfully likely to be wrong.

The people I follow are split on the decision. ¬†Lee has never gone on short rest before and this is a big stage to do it on, but the Phil’s really can’t afford to lose this game. ¬†Sabathia will be going on three day’s rest. ¬†We’ll see how that works out, too. ¬†If the Phillies don’t hit, it won’t matter much.

(By the way, don’t expect me to keep updating this frequently. ¬†I’ll settle into more of a rhythm as time goes on.)

Also, if you want to contact me, I’m available at ken.kousen@kousenit.com .

8:15 pm: In case you’re interested, I’m in downtown Parkersburg, WV this week, teaching an Intro Java class. ¬†I haven’t taught Intro Java in years, but the class was available when I was still in my, “there’s a recession going on so say yes to everything” mode. ¬†It should be an interesting experience, though. ¬†I plan to get a fair amount of work done on my book (“Making Java Groovy,” coming soon from O’Reilly) this week as well.

8:05 pm: Isn’t waving a white towel supposed to mean you surrender? ¬†That bothers me. ¬†Maybe I’m just being a curmudgeon.

Another horrible thing about FOX’s coverage of baseball is the way they desperately try to find sponsors for everything. ¬†This whole “introduce the game and hype Avatar at the same time” thing is truly annoying, and they’re just getting started.

8:00 pm: Jonah Keri’s live blog of game 4 can be found at¬†http://blogs.wsj.com/dailyfix/2009/11/01/world-series-diary-yankees-at-phillies-2/ .

7:50 pm: In general, MLB announcers are the best announcers in any sport. ¬†They’re clever, know the game, and are used to telling stories when they have time to fill. ¬†I’ve been very fortunate that the local Red Sox announcers are particularly good.

NBA announcers are usually good as well. ¬†I don’t watch as much basketball, at least not until the playoffs, because I get very frustrated by my inability to tell what a foul is anymore. ¬†Still, Hubie Brown is great, and he’s not alone.

College basketball announcers tend to be solid, once you get past the rah-rah ones (and mute Dick Vitale).

The NFL has a handful of good announcers, like Troy Aikman and Chris Collinsworth, and a lot of really bad ones.   The transition from baseball season to football season is always such a drop in announcer quality, but so be it.

College football announcers should never be allowed near a microphone, with the possible exception of Bob Griese.  They are simply horrible, living off one cliche after another, most of which are just wrong.

And yet, with all the great baseball announcers out there, once we hit the World Series we’re saddled with the travesty that is Joe Buck and Tim McCarver. ¬†I just can’t understand how either got the job, and I really can’t imagine how they keep it. ¬†Blech.

Most of this night I’ll watch with the sound muted, but I’ll be forced to unmute occasionally. ¬†That’ll no doubt generate more posts here.

7:30 pm: Two factors have increased my enjoyment of the World Series this year. ¬†First, two of my favorite baseball writers, Jonah Keri and Joe Posnanski, are “live blogging” each game, though I really only follow Jonah Keri’s. ¬†Second, Twitter has really broken through to the mainstream.

That deserves it’s own paragraph. ¬†I joined Twitter (@kenkousen) a long time ago, but didn’t do anything with it for the longest time. ¬†Then, to my surprise, I discovered that almost the entire Groovy and Grails core teams were there, and that they tweeted all the cool things they were doing on a regular basis. ¬†I suddenly had a community to follow, and that made all the difference.

As Twitter grew and grew, I slowly added people I enjoyed following. ¬†By now there are several baseball people I like there, like both the above mentioned guys and lots of others (@JPosnanski, @robneyer, @keithlaw, @joe_sheehan, and @jonahkeri). ¬†They’re so much better than listening to the inanities of Joe Buck and Tim McCarver on FOX, who should never, ever be allowed to broadcast a baseball game. ¬†They’re a complete travesty. ¬†Thank goodness I now have an alternative!

A note on how I’m going to handle the “live” aspect of this blog. ¬†I’m going to continually edit this post, but I’ll actually go through the motion of posting it, in the wildly unlikely event that anybody wants to follow me on it. ¬†We’ll see how that works out.

Dragons roar, cough, and sputter in Dayton

Tim Kurkjian says you should never miss the chance to go to a ballgame, because you might see something you’ve never seen before. ¬†On Tuesday I got the chance to go to see the Dayton Dragons play in their charming stadium, Fifth Third Field (seriously, that’s the name) in downtown Dayton, Ohio.

(I’m here this week teaching a class that combines Java Server Faces, Spring Web Flow, and Spring Faces — an adventure to say the least, but a story for another post.)

Accompanying me was my friend Stephen Williams, who I hadn’t seen in about eight months. He lives reasonably close to Dayton, but had never seen the Dragons play.

The Dragons are the A-ball affliate of the Cincinnati Reds. ¬†They draw extremely well in Dayton, despite the fact that they’re really, really bad this year.

(This is in contrast to my own Connecticut Defenders, who are limping their way out of town this season and playing to an almost empty stadium.  That, too, though, is a post for another day.)

The Dragons were 8 Р23 when the game started.  Their opponent tonight was the West Michigan Whitecaps, the Class A affliate of the Detroit Tigers and leaders of their division with a record of 21 Р9.  The weather was beautiful, roughly 70 degrees and sunny, with a very mild breeze, and the stands were nearly filled.  They were treated to what only can be described as a very odd game.

The fun started in the bottom of the second inning. ¬†There’s no score when Taylor Sloval led off with a walk. ¬†Then Stephen Chapman was called out on strikes, leaving a man on first with one out.

The official boxscore then says, “Kevin Coddington reaches on a fielders choice, fielded by third baseman Bryan Pounds. ¬†Tyler Stoval to 2nd.”

Hmm.  How did that happen?  How can a third baseman field a cleanly hit ball and manage not to get either runner out?

The key is that it looked to everyone in the place, including poor Bryan Pounds, like Coddington hit a soft fly right to him which he then caught. ¬†Pounds looked around, expecting the umpire to signal an out, but nothing happened. ¬†The runner, seeing this, kept going for 2nd, and by the time Pounds threw the ball there, he was called safe. ¬†Even that wasn’t clear, though, because it looked like the throw beat the runner.

So, either Coddington is out and Stoval is safe at 2nd on a stolen base, because he wasn’t tagged, or Coddington is safe at 1st because the ball bounced, but Stoval is out at 2nd on a force out. ¬†Which is it?

The umpires got together and talked it over. ¬†Eventually they settled on the unlikeliest of outcomes, which was that both runners were safe, but Coddington didn’t get a base hit on the play, nor was anybody charged with an error. ¬† Instead, it looked like Pounds was an idiot for holding onto the ball too long.

In my scorecard, I just put in a giant question mark. ¬†Welcome to A ball, where the umpires, too, are not necessarily ready for the big leagues. We’ll come back to that later.

Of course, what followed was a double and a single, resulting in a 2 Р0 lead for Dayton.  Yay home team.

Skip forward to the top of the 7th, where the fun really started. ¬†The Dragons are holding onto a 2 – 1 lead when Billy Nowlin for the Whitecaps singled and stole 2nd. ¬†Joseph Bowen struck out swinging, then Luis Salas walked, and Gustavo Nunez popped out to the catcher in foul territory. ¬†So now we have men on 1st and 2nd, but with two outs. ¬†The tying run is on 2nd, but both teams have hit horribly with men in scoring position all night. ¬† Then the next batter, Brett Wyatt, hits a soft grounder to the pitcher. ¬†It looks like Andrew Bowman, the Dragon’s pitcher who came in at the top of the 6th, is going to escape with no damage.

Or not.  His throw to 1st winds up somewhere near Cincinnati.  Nowlin scores, Salas makes it to 3rd, and Wyatt is safe at 1st.  Now the game is tied, with men on 1st and 3rd, still with two outs.

Surprise, surprise, the next batter, Ben Guez, gets hit by a pitch, loading the bases.   This despite the fact that Guez was 0 for 2 at the time, with a strike out and a foul out to 3rd, and had already been hit by a pitch way back in the 1st inning.

The catcher trots out to have a word with Bowman.  Steve and I imagine the conversation going something like:

Catcher: Dude, stop thinking about your throwing error, or the fact that you just blew the win so that the best you can hope for now is a no-decision.  Just throw strikes.

Pitcher: Yeah, whatever.

Next up comes Brandon Douglas. ¬†Whack! ¬†Yet another hit by pitch, bringing home Salas. Now it’s 3 – 2 Whitecaps and the bases are still loaded. ¬†The night is now officially over for Andrew Bowman. ¬†He’s replaced by Aguido Gonzales.

Gonzales faces Bryan Pounds (remember him from the 2nd inning?). ¬†Pounds works the count full and is rewarded with a walk, bringing home another run. ¬†Ron Bourquin then singles, scoring yet another. ¬†Finally, Billy Nowlin (batting again this inning — yup, the Whitecaps batted around) pops out to 1st to end the inning. ¬†The score is now 6 – 2 Whitecaps and the game is effectively over.

By the way, the second-to-last batter was given a single by a generous home scorer when the 2nd baseman (Cody Pucket, who went 4 for 4 and probably won’t be playing here long) should have been given an error. ¬†If it had been ruled an error, then the Whitecaps would have scored 5 runs on one hit, two walks, two errors, and two hit-by-pitches. ¬†I don’t expect to ever see that again.

The fun wasn’t over yet. ¬†Advance to the bottom of the 8th, with the score still 6 to 2. ¬†After two fly-outs and two singles, it’s now men on 1st and 2nd with two outs, and up comes Byron Wiley for the home team. ¬†The count goes full, and to Byron Wiley, the next pitch looks very much like a ball. ¬†He actually tosses his bat three feet away and starts heading for 1st when the umpire yells strike!

Oops.  Umpires really hate it when you show them up like that.  Wiley retrieves his bat, and again Steve and I imagine the conversation going on at the moment.

Umpire: Make me look bad like that? ¬†You better swing at the next pitch, dude, because it’s a strike. ¬†I can tell you that right now. ¬†I don’t care if it’s over your head, in the dugout, or three rows into the stands, it’s a strike. ¬†So don’t forget to swing.

Wiley: <grumble>

Sure enough, the next pitch is high and outside.  Sure enough, Wiley swings and misses.  Sure enough, the umpire calls it a strike before the swing even starts.  Inning over.

Wiley throws both his helmet and his bat this time, and the umpire throws Wiley.  Out of the game, actually, which comes as a surprise to nobody.

You’d think that would be it, but no, the top of the 9th was great, too. ¬†There were six total at-bats in the top of the 9th. ¬†They went: home run, strike out, strike out, home run, home run, strike out.

Yes, that’s three homers and three Ks. ¬†The fielders might as well have stayed in the dugout. How cool is that? ūüôā

The bottom of the 9th featured yet another homer, meaning that there were four total home runs in the 9th.  The final score was 9 Р4 in favor of the Whitecaps.

Even then my evening wasn’t finished. ¬†I convinced Steve to come with me to the Dragons Team Store, so I could buy a massively overpriced T-shirt or a massively overpriced cap. While I was browsing the massively overpriced merchandise ($35 for a shirt, and even $33 for a cap, but at least I wasn’t even tempted by the massively overpriced $125 jersey), a worker in the store pointed us to the line for autographs. ¬†It turned out one of the Dragon players was coming down to sign for the fans.

Who was the player?  Yup, you guessed it, poor unfortunate pitcher Andrew Bowman, whose pitching line for the night read 1.2 innings, 1 hit, 5 runs, none earned (wow), two walks, two strike outs, a very bad throwing error and a 6.48 ERA.  He got both a blown save and took the loss.  Not his best day.

He was warm and friendly, though.  He was kind enough to put an unintelligible scribble in my program and I got a quick picture with him on my phone.

Me and poor Andrew Bowman, of the Dayton Dragons

I did feel I had to say something, though.

Me: How’s your arm?

Bowman (smiling): It’s sore.

Me: Ah.  Well, good luck.

Bowman: Thanks.

I think anything else would have been cruel. ¬†I paid for my massively overpriced shirt and left with a cool story to tell. ¬†Yup, never miss the chance to go to a ballgame. ūüôā

Never miss a ballgame

As Tim Kurkjian famously said, “Never miss the opportunity to go to a baseball game.¬† You might see something you’ve never seen before.”

This week I’m in Asheville, NC.¬† I’m very busy with my Securing Java Web Applications class while other issues keep coming up, but the bottom line is that the Asheville Tourists (the class A affiliate of the Colorado Rockies) are nearby and are in town.¬† I was debating whether to go or not when I spoke to my wife on the phone.¬† As usual, she encouraged me to go.¬† She’s claims I’m always in a better mood after I’ve attended a ball game, so who can blame her?

Even better, minor league baseball team names in North Carolina are great.¬† I really liked the Lehigh Valley Iron Pigs when I was in Allentown a couple weeks ago, but NC has great names in abundance.¬† You’ve got the Greensboro Grasshoppers, the Winston-Salem Warthogs, the Kannapolis Intimidators, the Carolina Mudcats, and even tonight’s opponent, the Hickory Crawdads.¬† That doesn’t even mention the classic Durham Bulls.¬† But honestly, how can you not go to a game between the Tourists (who have had that name since 1914!) and the Crawdads?¬† It’s just not possible.

So I did my usual practice, which is to show up at the box office about a half hour before game time, told them I needed only one ticket and asked for the best available seat in the house.¬† In Asheville, that turned out to be a special “Home Deck Suite” right behind the on-deck circle (probability of a foul ball: zero), which cost a fortune ($45, an insane amount for a minor league game) but included all you can eat on the menu, delivered for seven innings by a helpful staff person.

That’s right — all you can eat.¬† The guy kept coming back asking if I wanted more, and I kept doing massive rationalizations justifying horrible overeating in order to consume enough to make the ticket worthwhile.¬† Let’s say that I think I managed to do so (er, hot dogs, popcorn, cheese nachos, a giant pretzel, and an endless supply of sodas, but I showed some restraint — no crackerjacks, though I was tempted), which I’m already regretting and surely will regret more tomorrow.¬† I even got lucky and sat next to a charming couple who were in town on business and had tons of minor league baseball stories to tell.¬† The guy next to me also reminded me that the manager of the Tourists is good old Joe Mikulik, the immortal star of this classic YouTube video featuring a managerial meltdown that is topped only by this one by Phil Wellman, and I saw Earl Weaver in his prime.

As for the game, the Crawdads won 7 – 1, but I definitely saw some things I’d never seen before:

  • Hickory’s Bobby Spain went 4 for 5 with a home run, but he was outdone by his teammate Andrew Walker, who went 4 for 5 with two home runs.¬† They even went back-to-back in the top of the 2nd inning.¬† Is it too obscure a reference to think their slogan should be Walker and Spain and Pray for Rain?
  • Hickory’s Harrison Bishop and Tom Boleska combined to strike out six batters in a row from the bottom of the sixth to the bottom of the eighth.¬† I was surprised when they took out Bishop after striking out four in a row, but then Boleska came in and struck out two more before the next guy grounded out weakly to second.
  • The two teams combined for a total of seven (!) errors (Hickory made 4 and still won), which is more than I’ve seen in some Little League games.
  • The catcher’s name on the Crawdads is Lars Davis.¬† Yes, he’s the catcher.¬† Don’t they therefore, by law, HAVE to call him Crash?
  • The guy who sang the National Anthem was an excellent operatic singer.¬† Every anthem singer in Connecticut thinks they have to sing with a country twang or like they have vocal diarrhea (see Aguilera, Christina, or lament the sad, pathetic American Idolization of singing), but here I am in North Carolina and I get a trained voice with a fine instrument.¬† Go figure.

The weather was great, the crowd was small (2872) but enthusiastic.  Asheville is the champion of the first half of the season of the Northern Division of the South Atlantic league (an odd but interesting achievement), so on the way out they were giving away general admission tickets to any future game.

That means I have a free ticket to the game tomorrow, even if it’s not for a very good seat and I still have work to do.¬† Still, you should never miss going to a ballgame…

Minor league baseball rocks

I’ve been traveling a lot lately.¬† Fortunately, this is baseball season, so sometimes I get a chance to visit a park I’ve never been to before.

Last week I was in Allentown, PA.¬† Actually, that’s not quite true — I was actually in Schnecksville, PA, a small suburb of Allentown.¬† It turns out that this year Allentown has a new baseball team.¬† The Lehigh Valley Iron Pigs are playing their inaugural season as the AAA affiliate of the Philadelphia Phillies.

(Two years ago, as part of an extended weekend road trip, my son Xander and I did the Phillies circuit.¬† We got tickets to see the Phillies at Citizens Bank park (a huge improvement over the old Veteran’s Stadium, but, then again, almost anything would be), then we saw the Reading Phillies (their AA affiliate), and finally swung around to see the Scranton/Wilkes-Barre Red Barons, who at the time were the Phillies AAA team.¬† Now that Scranton is the AAA team for the Yankees, we won’t be going back any time soon (I’d link to their web site, but hey, if you’re a Yankee fan, go find it yourself).¬† As a final aside, we were hoping to do a similar circuit for the Red Sox (Red Sox at Fenway, Portland Sea Dogs, Lowell Spinners), but couldn’t get tickets to any of them.¬† That’s right — the Single A Lowell Spinners were sold out, too.¬† Baseball is king in New England.)

I was teaching a private class last week, and the client was a major sponsor of the Iron Pigs.  That meant I was able to join a group of people in a good balcony section of Coca-Cola Park (an awful name, but there it is).  The whole pig theme was obvious, from the kids hanging out on the freshly mowed lawn in left-center, which was called Pigs on a Blanket, to the Pig Pen in right-center field.  Their program was even called Pork Illustrated.

We had a lot of fun, even though the Iron Pigs lost 5-4.¬† Still, the park was charming, we had excellent weather, and the people were friendly.¬† (Mostly — I did have an extended baseball discussion with a long suffering Cleveland Indians fan who hates all things Boston, which is probably understandable under the circumstances. ;))

This week I’m in Austin, TX.¬† Last night I drove out to Round Rock and got to see the Round Rock Express, the AA affiliate of the Houston Astros.¬† Yesterday the temperature peaked at 102, but there was a warm breeze and it cooled off a bit as the sun went down.¬† The stadium wasn’t terribly full, but the people who were there were quite enthusiastic.¬† The Express even won 3-0 and hit two home runs.¬† Other than taking forever to find my rental car in the parking lot (a sign of traveling too much is that you forget what your rental car looks like), I had a great time.

I’ve now added baseball caps from the Iron Pigs and the Express to my collection.¬† I used to get T-shirts everywhere for my son Xander, but he told me he doesn’t want them any more.¬† Now that he’s 16, all he wears are T-shirts with various rock bands on them.¬† So be it.¬† Be sure, though, to check out his band’s excellent studio recording of their song “Don’t Tell Me” at their MySpace page.

Next week I’ll be in Asheville, NC, and it looks like the Asheville Tourists (the class A affiliate of the Colorado Rockies) will be in town.¬† Maybe I’ll be able to buy another hat. ūüôā

%d bloggers like this: