How common are walk-off walks (on four pitches!) in baseball?

I’ve been following the Astros pretty closely this season (since they’re very good this year!), and so when I saw they had won a game on a walk-off walk, I was curious how common that was.

A walk-off is when the home team wins the game on that play, by scoring a run to go ahead in the ninth or later inning. So a walk-off walk is when that happens because the batter is walked. It’s kind of very dramatic and anticlimactic at the same time!

In this case, the walk was on four pitches, which seemed exceptionally rare, because you might as well throw at least one strike, right? At first I thought “maybe this has never happened before!”, but (spoiler!) it turns out there are a lot of baseball games that have been played. So I wanted to at least know how common it was.

My baseball win expectancy finder is powered by a Python script that can parse games, so I extended the parsing code to make it easier to run these sorts of reports and ran it. (source available on GitHub, see WalkOffWalkReport in parseretrosheet.py)

So, the numbers: in the ~128000 games I have data for, a walk-off walk has happened only 442 times. That sounds like a lot but it’s only around 7 times a season. Not all the games have pitch-by-pitch data, but ~73500 of them do, and walk-off walks on four pitches have happened only 60 times. (not including data from this year)

Since there are roughly 2100 games per season (including the playoffs), this means we’d expect this to happen around 1 time per season. Which is indeed pretty rare!

In fact, Altuve got his walk-off walk with 2 outs – walk-off walks with 2 outs have only happened 257 times (~4 times/season), and ones on four pitches have only happened 41 times, which is around 2 every 3 seasons!

When I was in the middle of this work I remembered that baseball-reference has an incredibly powerful Event Finder, and lo and behold it can do this search as well. In fact, at first our numbers were pretty far off so I found some bugs in my script 🙂 (the numbers are still off by a few because it’s counting a walk where the fourth ball was a wild pitch and a runner scored, while my script doesn’t count those)

My original thought was that I could make it easier to use my script to find stuff like this, but the baseball-reference Event Finder is so incredibly powerful and relatively easy to use I probably won’t bother. Kudos to them!

clue solver – now in TypeScript!

Here’s a new version of my Clue solver! It works exactly the same as the old version, but now it uses a more standard React build system (so maybe it’s a little faster?) and I ported it to TypeScript.

TypeScript is now my favorite way to write React apps. It’s really nice to have a real type system with compile-time errors, and it gives me much more confidence when I refactor things.

For a comparison, here’s the old code in plain JavaScript, and here’s the new code in TypeScript. One representative sample of how much nicer things are, in the History class’s render method:

Old code:

for (var i = 0; i < this.props.history.length; ++i)
{
    var event = this.props.history[i][0];
    var eventType = event[0];
    var description = '';
    if (eventType === "suggestion") {
        description = this.props.playerInfo[event[1]][0] + " suggested " + CARD_NAMES[0][event[2]].external + ", " + CARD_NAMES[1][event[3]].external + ", " + CARD_NAMES[2][event[4]].external + " ";
        if (event[5] == -1) {
            description += " - no one refuted";
        }
        else {
            description += " - refuted by " + this.props.playerInfo[event[5]][0] + " with card ";
            if (event[6][0] == -1 && event[6][1] == -1) {
                description += "Unknown";
            }
            else {
                description += CARD_NAMES[event[6][0]][event[6][1]].external;
            }
        }
    } else if (eventType === "whoOwns") {
        var player = "Solution (case file)";
        if (event[1] < this.props.playerInfo.length) {
            player = this.props.playerInfo[event[1]][0];
        }
        description = CARD_NAMES[event[2][0]][event[2][1]].external + " owned by " + player;
    }
    entries.push(<li key={i}>{description}</li>);
}

New code:

let entries = [];
for (let i = 0; i < this.props.history.length; ++i)
{
    let event = this.props.history[i].event;
    let description = '';
    switch (event.history_type) {
        case "suggestion":
            description = this.props.playerInfos[event.suggester_index].name + " suggested " +
                cardNameFromCardIndex({ card_type: CardType.Suspects, index: event.suspect_index }).external + ", " +
                cardNameFromCardIndex({ card_type: CardType.Weapons, index: event.weapon_index }).external + ", " +
                cardNameFromCardIndex({ card_type: CardType.Rooms, index: event.room_index }).external + " ";
            if (event.refuter_index == -1) {
                description += " - no one refuted";
            }
            else {
                description += " - refuted by " + this.props.playerInfos[event.refuter_index].name + " with card ";
                if (isNull(event.refuted_card_index) || isNone(event.refuted_card_index)) {
                    description += "Unknown";
                }
                else {
                    description += cardNameFromCardIndex(event.refuted_card_index).external;
                }
            }
            break;
        case "whoOwns":
            let player = "Solution (case file)";
            if (event.player_index < this.props.playerInfos.length) {
                player = this.props.playerInfos[event.player_index].name;
            }
            description = cardNameFromCardIndex(event.card_index).external + " owned by " + player;
            break;
    }
    entries.push(<li key={i}>{description}</li>);
}

The new code is so much more readable! To be fair, some of the refactoring I could have done in JavaScript to begin with, but TypeScript gives me much more confidence to do bigger refactors.

Also, Visual Studio gives me Intellisense and the ability to rename variables and whatnot. I really don’t want to go back to writing JavaScript in a non-IDE!

us-state-map – a React component for a US map of states!

After releasing State Election Map, my first step was to publish a React component with just the map stuff in it. And after messing around for a while with npm and TypeScript and React, I got it working! The us-state-map component is now available on GitHub and npm, and State Election Map uses it. (it includes the map itself and the date slider)

As with whenever I mess around with React I’m pretty sure I’m doing some parts idiomatically “wrong”. (the build step in particular is pretty hacked-together) I like to work on stuff like this to learn how to do things, but it makes me wonder how much I actually learn if I’m just hacking things together and not doing it 100% the correct way. At least it does give me something to copy if I want to do something similar in the future, and I do feel a sense of accomplishment 🙂

State Election Map now available!

My latest project, State Election Map, is now available! It’s a neat way to visualize US presidential election results from 1972 to 2016.

The coolest part is that you can look at each state’s result relative to the national popular vote, so you can see states becoming more Democratic/Republican over time. (check out California and Alabama going on opposite trajectories…)

Other interesting observations: Nixon won by a ton in 1972 (which means that whole Watergate stuff was really unnecessary!), Reagan won by a ton in 1984, and check out the 1976 bizarro-world map! I guess that’s what you get when you have a Southern Democrat running before the Southern Strategy had entirely taken hold…

From a technical perspective, the map is built in React, which I’ve used before, and TypeScript, which was new to me. And I’m a big fan! Using Visual Studio + TypeScript meant I got helpful syntax errors at edit-time, which I’m really not used to in a JavaScript-y language.

I did my best to separate the map/timeline parts into separate components, so I’m hoping to publish them separately and eventutally rewrite my same-sex marriage map to use them too. But that’s a ways down the line!

ProbabilityToFriendlyString for Javascript/Python/C#!

The 538 forecast for the House recently came out, and one of the things they’re trying is expressing probabilities in a friendlier way to try to make them more intuitive. So instead of “72.3%” it will say “5 in 7”, etc.

This seemed like a neat idea, so I wrote probabilityToFriendlyString, a library in Javascript/Python/C# to do this! Here’s a live demo.

I went through the effort to publish it on npm and NuGet. It’s pretty cool that I published these this week with no notice or anything, and already they’ve been downloaded a total of almost 50 times. Are these actual people using it already? Or some kind of automated…something?

Android development makes me angry sometimes

So I’m working on making an Android version of my baseball win expectancy finder, and things are going pretty well! (anyone want to beta test it??) Except…

I’m using Xamarin.Forms so I can write all my code in C#/XAML, which is neat! I was even able to add Google ads in just an hour or two thanks to this handy guide after some fighting with NuGet packages.

Then I decided to build it in Release and deploy it to my actual phone, and it started to crash on launch. The Debug version didn’t have this problem, and launching the Release build through the debugger did not give any useful information, but after some Binging and fiddling with some project settings I managed to at least see that it was crashing with an Android.Views.InflateLayoutException. Sadly there was no data in the exception or call stack or anything.

So, OK, I figured there must be something with my XAML, so I commented out everything except the main TabbedPage control, but that didn’t help. At a loss, I went back to Bing and Google (yes, pulling out the big guns!) and after looking through a bunch of links and trying a handful of random things I looked more closely at the log and saw a line like

W/resourcetype: entry identifier 0x14c is larger than 0x84

So OK, this looks bad, I guess, and after some more Bing/Googling, I stumble across a this StackOverflow question that points to this Google Groups thread with a suggestion that this is a bug in “HistoryRecord over in the framework” (?) is trying to read the theme, and there isn’t anything wrong with your code. So I try this suggested workaround of adding this to the top of styles.xml:

<style name=”Stub”></style>
<style name=”Stub1″></style>
<style name=”Stub2″></style>
<style name=”Stub3″></style>
<style name=”Stub4″></style>
<style name=”Stub5″></style>
<style name=”Stub6″></style>

These don’t do anything, they’re just there to try to work around the bug.

This didn’t work, but I figured “in for a penny, in for a pound” and added a few more, which also didn’t work. Then I changed them to the self-terminating XML tag form <style name="Stub" /> and lo and behold, the crash went away!

The kicker? That Google Groups post was from 9 years ago. This bug, which causes a crash on startup with no obvious cause and requires a basically-impossible-to-guess workaround has been around for at least 9 years.

*incoherent muttering*