Archive for September 2009

Creating New Expressive Social Mediums on the iPhone

A guest lecture for the Stanford University iPhone Application Programming class called “Creating New Expressive Social Mediums on the iPhone” was hosted by Ge Wang on June 1, 2009. Professor Wang talked about some of his projects at Stanford and from Smule, including demos of Sonic Lighter, Ocarina, and Leaf Trombone.

I wish I had an iPhone instead of an iPod Touch so I could use Ocarina.

Retrosheet reader

OK, so you just got back from the Ohio LinuxFest 2009  (meh, not exactly a hoppin’ place this year, I was kind of disappointed), and you have your event files converted over to CSV files after you generated the BEVENT batch files per last weekend’s post.

Now, you would like to read in that data and start looking through it for anything useful. Well this weekend’s post will help you with the reading in part, and you can take it from there if you would like.

Here is the C# console code. I have put all of the CSV files, ROS (roster) files, and the TEAM???? file into a folder on my C: drive called baseball_data, if your folder is different then just change the constant defined in the code below:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
 
namespace RetrosheetReader
{
 
    class Team
    {
        int year;
        string city;
        string nickname;
        string abbreviation;
        string league;
 
        public Team(int y, string[] a)
        {
            year = y;
            abbreviation = a[0];
            league = a[1];
            city = a[2];
            nickname = a[3];
        }
    }
 
    class Player
    {
        int year;
        string team;
        string playerID;
        string firstName;
        string lastName;
        string bats;
        string throws;
        string position;
 
        public Player(int y, string[] a)
        {
            year = y;
            playerID = a[0];
            lastName = a[1];
            firstName = a[2];
            bats = a[3];
            throws = a[4];
            team = a[5];
            position = a[6];
        }
    }
 
    class Event
    {
        string gameID;
        string visitingTeam;
        int inning;
        string battingTeam;
        int outs;
        int balls;
        int strikes;
        // yeah, there is still some work left here to do
        // maybe next time
 
        public Event(string[] a)
        {
            gameID = a[0];
            visitingTeam = a[1];
            inning = Convert.ToInt32(a[2]);
            battingTeam = a[3];
            outs = Convert.ToInt32(a[4]);
            balls = Convert.ToInt32(a[5]);
            strikes = Convert.ToInt32(a[6]);
        }
    }
 
    class Program
    {
        const string DATA = "c:\\baseball_data\\";
 
        static void Main(string[] args)
        {
            List teamList = new List();
            List playerList = new List();
            List eventList = new List();
 
            string s;
            string[] splitLine;
            int y;
 
            Console.WriteLine("Retrosheet Reader");
            Console.WriteLine();
 
            List tfs = Directory.GetFiles(DATA, "team*").ToList();
            foreach (string tf in tfs)
            {
                y = Convert.ToInt32(Path.GetFileName(tf).Substring(4));
                StreamReader sr = new StreamReader(tf);
                while ((s = sr.ReadLine()) != null)
                {
                    splitLine = s.Split(',');
                    if (splitLine.Count() == 4)
                    {
                        teamList.Add(new Team(y, splitLine));
                    }
                }
            }
 
            List rfs = Directory.GetFiles(DATA, "*.ros").ToList();
            foreach (string rf in rfs)
            {
                y = Convert.ToInt32(Path.GetFileName(rf).Substring(3).Split('.')[0]);
                StreamReader sr = new StreamReader(rf);
                while ((s = sr.ReadLine()) != null)
                {
                    splitLine = s.Split(',');
                    if (splitLine.Count() == 7)
                    {
                        playerList.Add(new Player(y, splitLine));
                    }
                }
            }
 
            List efs = Directory.GetFiles(DATA, "*.csv").ToList();
            foreach (string ef in efs)
            {
                Console.WriteLine("Reading events in " + ef);
                StreamReader sr = new StreamReader(ef);
                while ((s = sr.ReadLine()) != null)
                {
                    splitLine = s.Split(',');
                    if (splitLine.Count() == 97)
                    {
                        eventList.Add(new Event(splitLine));
                    }
                }
            }
 
            Console.WriteLine("Number of teams: " + teamList.Count().ToString());
            Console.WriteLine("Number of players: " + playerList.Count().ToString());
            Console.WriteLine("Number of events: " + eventList.Count().ToString());
 
            Console.WriteLine();
            Console.Write("Strike any key to end...");
            Console.ReadKey();
        }
    }
}

I have an idea as to the first thing that I am going to look for in the Retrosheet data, so tune in next weekend and I will (hopefully) have some interesting insights.

Monty Hall meets Monte Carlo

In honor of CBS canceling The Guiding Light after 72 years, and replacing it with a new incantation of Let’s Make A Deal, I decided to apply a little brute force computing to The Monty Hall problem.

Here is the VB.NET code to run the simulations. I decided to only apply a few different Monty Hall behaviors and a few different player behaviors, but it should be enough to drive home the paradox.

Module Module1
 
    Sub Main()
 
        Dim i, j, ctr As Integer
        Dim doorSwitch As String = "?"
        Dim smartMonty As String = "?"
        Dim prizeDoor(3) As Boolean
        Dim rand As Random = New Random()
        Dim doorMontyOpens As Integer
        Dim doorYouOpen As Integer
        Dim carsWon As Integer = 0
 
        Console.WriteLine("The Monty Hall Problem")
        Console.Write("How many times to run the simulation? ")
        ctr = Val(Console.ReadLine())
        If ctr < 1 Then End
 
        Console.Write("Are you going to switch doors? [Y/N/M] ")
        While Not "YNM".Contains(doorSwitch)
            doorSwitch = Console.ReadKey.KeyChar.ToString.ToUpper
        End While
        Console.WriteLine()
 
        Console.Write("Does Monty know where the car is? [Y/N/M] ")
        While Not "YNM".Contains(smartMonty)
            smartMonty = Console.ReadKey.KeyChar.ToString.ToUpper
        End While
        Console.WriteLine()
 
        For i = 1 To ctr
 
            ' set up the prize doors
            For j = 1 To 3
                prizeDoor(j) = False
            Next
            prizeDoor(rand.Next(1, 4)) = True
 
            Console.Write(i.ToString() + " (")
            For j = 1 To 3
                Console.Write(If(prizeDoor(j), "$", j.ToString))
            Next
            Console.Write(") -- ")
 
            ' Monty shows you a door
            If smartMonty = "Y" Or (smartMonty = "M" And _
                                    rand.NextDouble > 0.5) Then
                doorMontyOpens = If(prizeDoor(2), 3, 2)
            Else
                doorMontyOpens = rand.Next(2, 4)
                If prizeDoor(doorMontyOpens) Then
                    carsWon = carsWon + 1
                    Console.WriteLine("Monty revealed the car!!!!!")
                    Continue For
                End If
            End If
            Console.Write("Monty reveals a goat behind door #" + _
                          doorMontyOpens.ToString + " -- ")
 
            ' pick a door to open
            If doorSwitch = "Y" Or (doorSwitch = "M" And _
                                  rand.NextDouble > 0.5) Then
                doorYouOpen = If(doorMontyOpens = 2, 3, 2)
                Console.Write("You switched to door #" + _
                              doorYouOpen.ToString + " -- ")
            Else
                doorYouOpen = 1
                Console.Write("You stayed with door #1 -- ")
            End If
 
            ' did we win?
            If prizeDoor(doorYouOpen) Then
                Console.WriteLine("You won the car!!!!!")
                carsWon = carsWon + 1
            Else
                Console.WriteLine("You won the goat.")
            End If
 
        Next
 
        Console.WriteLine(" ")
        Console.WriteLine("You won the car " + carsWon.ToString + _
                          " times out of " + ctr.ToString)
        Console.WriteLine("Winning percentage: " + (carsWon * _
                            100.0 / ctr).ToString("##0.0"))
        Console.WriteLine(" ")
        Console.WriteLine("Strike any key to end...")
        Console.ReadKey()
 
    End Sub
 
End Module

Now if CBS ever decides to cancel The Young And The Restless, we are going to have a real problem on our hands.

The illusion…

I have heard it said that the greatest danger is the illusion that all is well. This is sort of pessimistic, and I am not a pessimistic person by nature.

And then I start looking through the code and see something like this:

public Guid AddSomething(Guid id1, Guid id2, bool useAlternateValue)
{
    // stuff removed from here
    // including the creation of the obj object, 
    // which conains a default and alternate value
 
    string s = "";
    if (useAlternateValue && (obj.alternateValue != null))
        s = obj.alternateValue;
    else if ((!useAlternateValue) && (obj.defaultValue != null))
        s = obj.defaultValue;
 
    // more stuff removed from here
}

One of the developers that I work with is confused by my hatred of compounding the not operator with ands, ors, and parentheses in decision statements, and of the use of the null object. This code appears to combine both of these things in a mishmash of non functional code.

Retrosheet.org play-by-play baseball data

I have thought for a long time that Retrosheet.org was a pretty neat web site with the potential for a ton of baseball information.

They have loads of stats on their site, but it can be hard to get at sometimes.  As a result, I thought I might do some coding against their data just for fun. (I am doing this mainly because I am bored, because the Steelers are not on TV here in Ohio today, and because cable does not carry the NFL Sunday Ticket.)

The first task is to take their event data files and get them into a format that can be easily read and parsed. There are zip files on the Retrosheet web site to download entire seasons worth of event data, just go to retrosheet.org, hover over Data downloads, and select Play-by-play files.

However, once you look at these event files, you discover that they may need a little interpreting to get them into a nicer format for study. Luckily, Tom Tippett, David Nichols, and David W. Smith wrote a DOS application that does this, you just need to run this BEVENT.EXE file on each of the event files.

And of course, I couldn’t simply do that, I had to write a VB.NET console application to create a batch file do automate this.

Imports System.IO
 
Module Module1
 
    Sub Main()
 
        Console.WriteLine("BEvent Helper")
        Console.Write("Enter the directory of your event files: ")
        Dim d As String = Console.ReadLine()
 
        If d.Trim = "" Or Not Directory.Exists(d) Then GoTo App_end
        If Right(d, 1) <> "\" Then d = d + "\"
 
        Dim eventFilenames As List(Of String)
        eventFilenames = Directory.GetFiles(d, "*.ev?").ToList
 
        Dim s, cmd As String
        Dim sw As StreamWriter = New StreamWriter(d + "BEventHelper.bat")
        For Each f In eventFilenames
            s = Path.GetFileName(f)
            cmd = "bevent.exe -f 0-96 -y " + Left(s, 4) + " " + s + " > " + s + ".csv"
            sw.WriteLine(cmd)
        Next
        sw.WriteLine("pause")
        sw.Close()
 
App_end:
        Console.WriteLine("Press any key to end application...")
        Console.ReadKey()
 
    End Sub
 
End Module

So what you do is download a season zip file (find them on the Play-by-Play Data Files page), unzip the files into a directory, download the bevent.zip file from the Software tools page, unzip it and place the BEVENT.EXE file into the directory with all the event files, run the console application and enter the directory name at the prompt, and when it is all said and done, you have a BEventHelper.bat file in the directory. Once this file is run, you will end up with CSV files that correspond to the event files.

In the next episode, I will begin to read in the data and crank out some preliminary statistics.

Disclaimer: The information used here was obtained free of charge from and is copyrighted by Retrosheet. Interested parties may contact Retrosheet at “www.retrosheet.org”.

Stanford iPhone App Programming lecture 16

Lecture 16 from the Stanford University iPhone Application Programming class was hosted by Alan Cannistraro. He covered using the audio APIs, playing back video content, displaying web content in UIWebView controls, and he talked about settings on the iPhone platform.

The APIs and controls Alan demonstrated were very simple, and really meant for basic usage only, which is fine for most applications. He did talk about and demonstrate how to use a settings plist bundle so that an application’s preferences show up in the device’s Settings application, which was mildly interesting to me.

Some people use QWERTY, some Dvorak, but I use TVQUIZ

Are you looking for something silly and not too sinister to pull on a coworker who takes a week’s vacation on the beach while you are stuck in the office dealing with customers having issues with the vacationer’s product? And did I mention the week in question is one of the busiest weeks of the year for our company?

Here’s what I did to his keyboard:

0828091358

He had to rearrange a few of the keys to make it workable again, as this Dell keyboard has different shapes of the keycaps for the different rows of the keyboard. This took me about 10 minutes, and was much cheaper and quicker than wrapping everything in his office in aluminum foil.

Optimizing OpenGL for iPhone

A guest lecture for the Stanford University iPhone Application Programming class called “Optimizing OpenGL for iPhone” was hosted by Tim Omernick of ngmoco on May 22, 2009. Tim covered a lot of his thoughts on, shockingly enough, optimizing OpenGL ES code on the iPhone platform.

Since my familiarity with OpenGL is null, most of what he talked about was over my head. I do have some game ideas, and once I get motivated to look into how OpenGL works, this presentation should be helpful. Also, the fireworks demo application he showed was very fun to play with.