Document Home


Previous Revising the Database Structure
Previous The New Event Record Structure
Previous The New Entry Interface
Previous The Bare-Bones Interface
Previous Starting with Javascript and the Document Object Model

Restructuring the Events and Results Tables



I know that the readers out there who have gotten to this point are an incredibly savvy bunch. Almost by definition. Anyone who has gotten to this point must have an extraordinarily fine appreciation for the "real deal", and a razor-sharp mind. Therefore, it comes as absolutely no surprise to me that I can sense a growing unease about the ability of the information stored in the event and event_result tables to adequately represent the game detail implicit in the new structure. Clearly, the events recorded for the results of an at-bat and those that should be recorded for a runner on base are considerably different. At a minimum, it makes absolutely no sense to scroll through a long series of options when only a relative few apply to any given context. Therefore, before I launch into deeper work on the interface I want to put into place a set of codes that both makes sense and can be readily extended to cover events that have not occurred to me.


The strategy I am going to employ in assigning these codes will involve nesting the classes under which individual items will be grouped within the codes themselves. This will allow me to store the codes and their descriptions in a single table, selecting those appropriate to a given context by passing the appropriate value to a placeholder in a prepared database statement. In that sense, this will be something of a model for the manner in which a single database statement can serve multiple purposes.


The basic structure that I will employ here will therefore be something like this, albeit somewhat more sophisticated:

Code Descriptor
ABR:01:01 Strikeout
ABR:01:02 Groundout
... ...
ABE:01:01 Ball
ABE:01:02 Strike-Taken
... ...
OBE:01:01 Out-Picked off
OBE:02:01 Advance-Hit

In this manner the information regarding the applicability of the code are present within the code itself. The pertinence of that is n ot readily apparent within the structure of the table in which the codes are stored, because I will be adding columns to independently specify the applicability of the code, provide a ready selection criteria, and improve the legibility of the entries in the table, as in:

Code Descriptor Context Class
ABR:01:01 Strikeout ABR Out
... ... ... ...
ABE:01:01 Ball ABE
... ... ... ...
OBE:01:01 Picked off OBE Out


The value of a structure like this lies primarily in its ability to force the creation of unique codes, and thus to help promote the integrity of the information stored in the system. The code itself becomes the primary key for the table, and specification that it be unique will prevent the insertion, inadvertent or otherwise, of a second row with the same code. A second benefit of this layout lies in the potential for streamlining both queries and the manipulation of the resultant result sets. As the code value incorporates all of the pertinent levels of detail, a query to return all of the on base events that fall into a certain class need not require a link to the source table holding the codes. In sql, such a link is known as a join, and every join added to a query results in slower response and the consumption of more computer resources, because the database server must assemble the composite record before it can return the result. (While more sophisticated database servers employ a variety of techniques to minimize the toll required by this process, a query requiring joins still takes longer than one that does not.) There will be times in any reasonably complex application when a join is required to return the desired information. After all, virtually all database engines are relational databases; establishing relationships between tables is inherent in the design of a relational system. At the same time, measures such as this can reduce the number of joins required, thus optimizing overall system response and reducing the complexity of those statements that do require joins.


The actual assignation of the codes is the kind of drudge work that makes everything else easier if done adequately. As is the case with virtually everything, the first 80% takes 20% of the effort and the last 20% requires 80%. Anticipating the set of events that will be recorded in the ab_results table is not all that taxing:

At Bat Results
Class Event
Out Strikeout
Out Groundout
Out Flyout
Out Foulout
Out Sacrifice Fly
Out Sacrifice Bunt
Out Dropped Third Strike
Out Double Play
Out Triple Play
Hit Single
Hit Double
Hit Triple
Hit Home Run
Other Walk
Other Hit by Pitch
Other Error

Even though these code values seem relatively straightforward, a bit of thought about them begins to raise some of the questions that will characterize the more detailed code values that will follow. Just as in the more simple version of the entry process used earlier, at heart the issue is one of determining the level of specificity at which events should be recorded. In this context, that level is in effect determined by what I have decided is a system requirement. That is, I have decided that the minimum level of specificity that I can accept is that which will allow the state of the inning and key pieces of baseball data to be tracked as automatically as possible. As will become apparent, that level of specificity will, as a result, be primarily determined by the rules of baseball, representing the business logic of this system. In this vein, the codes for sacrifice fly, sacrifice bunt, and hit by pitch, for example, will have both descriptive value and provide key information for automatic tracking, in that sacrifices represent an out in the inning but do not result in the batter being charged with an out (or an at-bat, for that matter), while a dropped third strike creates the inverse result, with the batter being charged with an out, but no out being assigned to the team at bat. Such considerations, in concert with things like the limitation on the number of games to be played on a given day of the week, are called "business logic" because they relate to the nature of the domain being modeled rather than the internal logic that implements that model.


The final versions of the codes assigned will be more finely-grained, in that they will, for example, include the position that committed an error. It is worth restating, however, that this is just enriching the detail of the events recorded. In the absence of the more detailed codes, more specific information could simp[ly be recorded in the notes associated with that record.


The events that will be recorded in the ab_event table essentially represent the stream of balls and strikes that will be associated with an individual at bat. This description, however, belies the underlying detail required to automatically tabulate the state of the at bat.

At Bat Events
Ball
Strike-Taken
Strike-Swinging
Foul Ball-Out of Play-Strike
Foul Ball-Out of Play-No Strike
Foul Ball-In Play-Strike-No Play
Foul Ball-In Play-Strike-Error
Foul Ball-In Play-No Strike-No Play
Foul Ball-In Play-No Strike-Error
Ball in Play

These events illustrate the more finely-grained structure required by some of the finer points of the game. The first three events are straightforward, but once one ventures into the area of foul balls things start to get a bit muddy. There are three conditions that bear on what should be recorded for a foul ball. First, if the current count on the batter has less than two strikes, any foul ball is a strike, but when the count reaches two strikes foul balls do not count as strikes, outside of one context that I will mention shortly. Second, a foul ball can be either in play or out of play. If the ball is out of play, of course, the only operative consideration is the current strike count, determining whether the foul is a strike or not. (As a result, in this particular circumstance the decision regarding which code to store for the event could be made at the server rather than through the entry mechanism.) If, however, the ball is in play there can be a play on it. Anyone who has watched a baseball game knows that there are numerous contexts in which foul balls are hit that no fielder has a reasonable chance to catch. The official scorer for the game generally designates those as "no play". If the batter hits a foul ball that is caught by a fielder before it touches the ground, that batter is of course out, and that would be recorded as the result of the at bat. If, however, the player should drop the ball, it can be charged as an error. Hence the addition of the appropriate codes. (The exception to this is a foul tip, in which the ball does not rise above the batter's head and on which a play is made by the catcher. With less than two strikes, a foul tip that is caught by the catcher is simply a strike, but on the third strike any foul tip is regarded as in play and a foul tip caught by the catcher is scored as a foul-out. As pre-two strike foul tips are scored as swinging strikes, I have not created a seperate code for the event, at this point regarding "foul tip" as a descriptive entry in the associated text.) Given the relative difficulty of getting to foul balls, it is not unusual to see difficult catches in foul territory rules as "no play", but there are times when players are charged with errors on foul balls. In a formal setting with an official scorer, this is the scorer's call.


The exception to which I referred earlier is the context in which a batter with two strikes attempts a bunt which goes foul. To prevent batters from bunting pitch after pitch foul to wear out the pitcher, this is recorded as a strikeout. Again, the specific context of the strikeout would be recorded in the associated text box.


Defining the events to be recorded for runners on base is also more difficult than it might seem. The following provides a start.

On Base Events
Class Event
Out Steal Attempt
Out Picked Off
Out Force Play
Out Doubled Off
Advance Hit
Advance Stolen Base
Advance Error
Advance Wild Pitch
Advance Passed Ball
Advance Walk
Advance Sacrifice
Other Pickoff Attempt-Safe

First, it is easy to see that these are derived for an offensive context, because the classes here are clearly oriented toward recording the status of runners on the bases. Remember, the idea here is to create a dialog in which the entry person can select the appropriate even by making choices from a series of select boxes, each of which contains a manageable number of options. That is the purpose of the classification scheme presented here. (It is worth noting that should I ever get around to constructing an interface and supporting structure to facilitate recording the game events from a defensive perspective, I could use the same set of events from a defensive perspective. Realistically, however, it is likely that some additional events reflecting that perspective would have to be added to the set.


A little reflection reveals that these codes should encapsulate somewhat more detail. As an example, during a season fans of any given team might complain that their team is playing "station to station" baseball, which means that the team's runners have gotten into a patterm in which they advance only when there is a base hit, and then often only by the number of bases that the hitter was able to garner from the hit. Potentially, of course, the actions of runners on the basepaths are much more fluid than that. In at least half of the circumstances in which a batter singles with a runner on first, for example, that runner will advance to third. There is no intermediate event to associate with the move from second to third; the runner advanced from first to third as a result of the hit. Therefore, the table of on base event codes must have seperate values distinquishing the potential locations of the runner as a result of the play. I gave consideration to two potential formulations of these codes, in the first specifying the number of bases advanced and in the second specifying the endpoint of the runner, in the end adopting the latter to ease the load on the server by reducing the contexts to which the server must respond. If I were to implement the first type of code values, the task of automatically registering key events, such as a run scored and a RBI credited to the batter, would be complicated by the necessity of comparing the nature of the recorded event with the state of the bases at the time of the event. In contrast, by specifying the endpoint of the runner's advance many of those items can be registered in a straightforward manner. It is worthwhile, however, to briefly engage in what Albert Einstein used to call a "thought experiment". Imagine, if you will, <nod to The Twilight Zone> that the number of bases runners advanced as a result of a given individual's at bats was a key piece of baseball information. (While this may seem to be important, it is likely to primarily reflect the relative speed of the individuals preceding the subject individual in the batting order, so two individuals of equivalent effectiveness at the plate would have significantly different values for this statistic.) If, however, this were important information, the first form of code value assignment would better lend itself to the accumulation of those values.


In any event, the initial form of the ob_events codes will look something like this:

On Base Events
Event Result Code
Pick-Off Attempt Out OBE:01:01:00:00
Pick-Off Attempt Safe-Return to Base OBE:01:02:00:00
Pick-Off Attempt Steal-Safe OBE:01:03:00:00
Pick-Off Attempt Steal-Out OBE:01:04:00:00
Pick-Off Attempt Advance-E1 (error on pitcher)-2nd (on seconnd base as result) OBE:01:05:E1:02
Pick-Off Attempt Advance-E2-2nd OBE:01:05:E2:02
Pick-Off Attempt Advance-E3-2nd OBE:01:05:E3:02
Pick-Off Attempt Advance-E4-2nd OBE:01:05:E4:02
Pick-Off Attempt Advance-E5-2nd OBE:01:05:E5:02
Pick-Off Attempt Advance-E6-2nd OBE:01:05:E6:02
Pick-Off Attempt Advance-E7-2nd OBE:01:05:E7:02
Pick-Off Attempt Advance-E8-2nd OBE:01:05:E8:02
Pick-Off Attempt Advance-E9-2nd OBE:01:05:E9:02
Pick-Off Attempt Advance-E1-3rd OBE:01:05:E1:03
Pick-Off Attempt Advance-E2-3rd OBE:01:05:E2:03
Pick-Off Attempt Advance-E3-3rd OBE:01:05:E3:03
Advance on Play Advance-2nd OBE:02:04:00:02
and so forth. While this set may seem repetitive, its inclusion of each potential circumstance will make event handling on the server as straightforward as possible. While it is extraorinarily unlikely that an outfielder would be charged with an error directly on a pickoff play, as opposed to a fielding error retrieving a ball rolling loose as a result of someone else's error, it is by no means impossible; my high school team had a pickoff play designed in which the shortstop and second baseman would stay far away from a runner on second, thereby encouraging the runner to take a lengthy lead. At that point the center fielder would sneak in behind the runner to take a throw from the pitcher. (The only time I can recall the play being called, the opposing coach saw it coming and called out a warning.) To repeat a point I have made before, it is ironically the case that system users frequently judge its utility by how well it handles such unusual cases.


For those who may question my concern with maintaining straightforward logic on the server, in the past several weeks I have been experimenting with a couple of collaborative environments that can be run an an apache server, specifically twiki and scoop. Each is interesting, but as a result of this experimentation the additional load on the server exacted by the construction of an environment capable of responding to a wide range of request became very obvious. in both cases, the machine I was employing to host the environment was several times as powerful as the root ralphzilla machine, yet the application was less responsive. This should not be interpreted as a criticism of those packages, the process of building an environment that can be customized to represent a free-form collaborative environment is a daunting one, requiring that the server respond to a wide range of requests. It does, however, illustrate the load that such entails. As the application I am building here can be constructed in such a manner as to be very specific in the manner in which requests are handled, the server's responses will be much quicker. The price that is required is the kind of specificity I am employing in the development of these codes.


Note the final code in the table above, described as "Advance on Play". This will be used to describe a circumstance in which a user advances, or attempts to, as another play is taking place. A common example of this often occurs when a batter hits a sacrifice fly with more than one runner on base. If an attempt is made to throw the lead runner out, generally at the plate, the remaining runner(s) may attempt to advance a base. Such plays are independent actions within the context of the game, not associated with other events beyond the fact that they happen while a play is being made on another runner. It is therefore my intent that such events will be tied to the events around them by simply including a short description in the associated text box.


When I wrote the draft of this chapter I had intended to simply link to a text file containing the first version of the codes I am going to run into the relevant table (Release 1.0 <grin>), rasoning that there was no point in including a big table with more than 200 seperate rows in the document itself. As I have finalized the chapter, however, I have come to believe that such a listing will have real value, that a quick scan down a formatted listing of the codes can impart a visceral understanding of their structure that will serve to augment the written description.


Before I do that, however, I want to explicitly specify the internal structure of the code values.

Segment Description
XXX:xx:xx:xx:xx The first segment, of course, represents an acronym identifying the context for which the code is appropriate.
xxx:XX:xx:xx:xx In the at bat results and on base events context, for which I have gouped the codes into classes, the second segment identifies the pertinent class, while in the much smaller set of codes pertinent to at bat events it is used to identify the major types of events that happen during an at bat (ball,strike,other) thus serving much the same purpose.
xxx:xx:XX:xx:xx In the third segment the code value identifies the specific event, as in the at bat event of a foul ball on which there was an error, and on which a strike was charged.
xxx:xx:xx:XX:xx The fourth segment in the codes represents the position that fielded the ball, where appropriate. While the table above uses the character "E" to preface the position code, in that more limited context being used to identify the position that had committed an error, in the release version of the code values below the position codes 1-9 are prefaced with "0". Thus in this version the segment simply identifies the position making the play; the type of play is identified by the preceding segment. While the standard position code occupies only one character, I have maintained a two-character representation to allow for unusual circumstances, as in softball leagues which employ the tenth position of short center fielder.
xxx:xx:xx:xx:XX The final code segment is occupied by a value representing the final position occupied by the batter/runner as the result of the play. Here again I have used two characters to hold a value that requires only one, as a hedge against potential future use of the segment in an extended context. (In older database systems that used fixed-length hierarchical structures, empty spaces were frequently left in a record structure to allow for expansion. Those old enough may recall forms with areas defined as "reserved for future use". What I am doing here is analogous to that.) In both this and the preceding segments I occupy the segment with the string "NA" if not pertinent to the context of the specific event.


Again, it is worth noting that this structure is not at all normalized. While some degree of normalization would reduce the number of codes in this table, that benefit would be far outweighed by the overhead engendered by adding one or two joins to any statements accessing records that met specific criteria. If this system were part of a larger system, and one of the non-normalized elements of this table represented the link between parts of the system, that overhead would be justified.


Given that introduction, here are the code values:

Code Description Context Class
ABE:01:01:NA:NABallABE
ABE:02:01:NA:NAStrike-Taken
ABE:02:02:NA:NAStrike-SwingingABE
ABE:02:03:NA:NAFoul Ball-out of play-strikeABE
ABE:02:04:NA:NAFoul Ball-in play-strike-no playABE
ABE:02:05:01:NAFoul Ball-in play-strike-error pitcherABE
ABE:02:05:02:NAFoul Ball-in play-strike-error catcherABE
ABE:02:05:03:NAFoul Ball-in play-strike-error first basemanABE
ABE:02:05:04:NAFoul Ball-in play-strike-error second basemanABE
ABE:02:05:05:NAFoul Ball-in play-strike-error third basemanABE
ABE:02:05:06:NAFoul Ball-in play-strike-error shortstopABE
ABE:02:05:07:NAFoul Ball-in play-strike-error left fielderABE
ABE:02:05:08:NAFoul Ball-in play-strike-error center fielderABE
ABE:02:05:09:NAFoul Ball-in play-strike-error right fielderABE
ABE:03:03:NA:NAFoul Ball-out of play-no strikeABE
ABE:03:05:01:NAFoul Ball-in play-no strike-error pitcherABE
ABE:03:05:02:NAFoul Ball-in play-no strike-error catcherABE
ABE:03:05:03:NAFoul Ball-in play-no strike-error first basemanABE
ABE:03:05:04:NAFoul Ball-in play-no strike-error second basemanABE
ABE:03:05:05:NAFoul Ball-in play-no strike-error third basemanABE
ABE:03:05:06:NAFoul Ball-in play-no strike-error shortstopABE
ABE:03:05:07:NAFoul Ball-in play-no strike-error left fielderABE
ABE:03:05:08:NAFoul Ball-in play-no strike-error center fielderABE
ABE:03:05:09:NAFoul Ball-in play-no strike-error right fielderABE
ABE:03:04:NA:NAFoul Ball-out of play-no strike-no playABE
ABE:04:01:NA:NAHit by pitchABE
ABE:05:01:NA:NABall batted fairABE
ABR:01:01:NA:NAStrikeoutABROut
ABR:01:02:01:NAGroundout-PitcherABROut
ABR:01:02:02:NAGroundout-CatcherABROut
ABR:01:02:03:NAGroundout-First BasemanABROut
ABR:01:02:04:NAGroundout-Second BasemanABROut
ABR:01:02:05:NAGroundout-Third BasemanABROut
ABR:01:02:06:NAGroundout-ShortstopABROut
ABR:01:02:07:NAGroundout-Left FieldABROut
ABR:01:02:08:NAGroundout-Center FieldABROut
ABR:01:02:09:NAGroundout-Right FieldABROut
ABR:01:03:01:NAPopout-PitcherABROut
ABR:01:03:02:NAPopout-CatcherABROut
ABR:01:03:03:NAPopout-First BasemanABROut
ABR:01:03:04:NAPopout-Second BasemanABROut
ABR:01:03:05:NAPopout-Third BasemanABROut
ABR:01:03:06:NAPopout-ShortstopABROut
ABR:01:03:07:NAFlyout-Left FieldABROut
ABR:01:03:08:NAFlyout-Center FieldABROut
ABR:01:03:09:NAFlyout-Right FieldABROut
ABR:01:04:01:NAFoulout-PitcherABROut
ABR:01:04:02:NAFoulout-CatcherABROut
ABR:01:04:03:NAFoulout-First BasemanABROut
ABR:01:04:04:NAFoulout-Second BasemanABROut
ABR:01:04:05:NAFoulout-Third BasemanABROut
ABR:01:04:06:NAFoulout-ShortstopABROut
ABR:01:04:07:NAFoulout-Left FieldABROut
ABR:01:04:08:NAFoulout-Center FieldABROut
ABR:01:04:09:NAFoulout-Right FieldABROut
ABR:01:05:01:NASacrifice Fly-PitcherABROut
ABR:01:05:02:NASacrifice Fly-CatcherABROut
ABR:01:05:03:NASacrifice Fly-First BasemanABROut
ABR:01:05:04:NASacrifice Fly-Second BasemanABROut
ABR:01:05:05:NASacrifice Fly-Third BasemanABROut
ABR:01:05:06:NASacrifice Fly-ShortstopABROut
ABR:01:05:07:NASacrifice Fly-Left FieldABROut
ABR:01:05:08:NASacrifice Fly-Center FieldABROut
ABR:01:05:09:NASacrifice Fly-Right FieldABROut
ABR:01:06:01:NASacrifice Bunt-PitcherABROut
ABR:01:06:02:NASacrifice Bunt-CatcherABROut
ABR:01:06:03:NASacrifice Bunt-First BasemanABROut
ABR:01:06:04:NASacrifice Bunt-Second BasemanABROut
ABR:01:06:05:NASacrifice Bunt-Third BasemanABROut
ABR:01:06:06:NASacrifice Bunt-ShortstopABROut
ABR:01:06:07:NASacrifice Bunt-Left FieldABROut
ABR:01:06:08:NASacrifice Bunt-Center FieldABROut
ABR:01:06:09:NASacrifice Bunt-Right FieldABROut
ABR:01:07:02:NAOut-Dropped Third StrikeABROut
ABR:01:08:NA:NAOut-Double PlayABROut
ABR:01:09:NA:NAOut-Triple PlayABROut
ABR:02:01:NA:01Hit-SingleABRHit
ABR:02:02:NA:02Hit-DoubleABRHit
ABR:02:03:NA:03Hit-TripleABRHit
ABR:02:04:NA:04Hit-Home RunABRHit
ABR:03:01:NA:01Other-WalkABROther
ABR:03:02:NA:01Other-Hit by PitchABROther
ABR:03:03:01:01Other-Reached first on error-pitcherABROther
ABR:03:03:02:01Other-Reached first on error-catcherABROther
ABR:03:03:03:01Other-Reached first on error-first basemanABROther
ABR:03:03:04:01Other-Reached first on error-second basemanABROther
ABR:03:03:05:01Other-Reached first on error-third basemanABROther
ABR:03:03:06:01Other-Reached first on error-shortstopABROther
ABR:03:03:07:01Other-Reached first on error-left fielderABROther
ABR:03:03:08:01Other-Reached first on error-center fielderABROther
ABR:03:03:09:01Other-Reached first on error-right fielderABROther
ABR:03:03:01:02Other-Reached second on two-base error-pitcherABROther
ABR:03:03:02:02Other-Reached second on two-base error-catcherABROther
ABR:03:03:03:02Other-Reached second on two-base error-first basemanABROther
ABR:03:03:04:02Other-Reached second on two-base error-second basemanABROther
ABR:03:03:05:02Other-Reached second on two-base error-third basemanABROther
ABR:03:03:06:02Other-Reached second on two-base error-shortstopABROther
ABR:03:03:07:02Other-Reached second on two-base error-left fielderABROther
ABR:03:03:08:02Other-Reached second on two-base error-center fielderABROther
ABR:03:03:09:02Other-Reached second on two-base error-right fielderABROther
ABR:03:03:01:03Other-Reached third on third-base error-pitcherABROther
ABR:03:03:02:03Other-Reached third on third-base error-catcherABROther
ABR:03:03:03:03Other-Reached third on third-base error-first basemanABROther
ABR:03:03:04:03Other-Reached third on third-base error-second basemanABROther
ABR:03:03:05:03Other-Reached third on third-base error-third basemanABROther
ABR:03:03:06:03Other-Reached third on third-base error-shortstopABROther
ABR:03:03:07:03Other-Reached third on third-base error-left fielderABROther
ABR:03:03:08:03Other-Reached third on third-base error-center fielderABROther
ABR:03:03:09:03Other-Reached third on third-base error-right fielderABROther
ABR:03:03:01:04Other-Scored on four-base error-pitcherABROther
ABR:03:03:02:04Other-Scored on four-base error-catcherABROther
ABR:03:03:03:04Other-Scored on four-base error-first basemanABROther
ABR:03:03:04:04Other-Scored on four-base error-second basemanABROther
ABR:03:03:05:04Other-Scored on four-base error-third basemanABROther
ABR:03:03:06:04Other-Scored on four-base error-shortstopABROther
ABR:03:03:07:04Other-Scored on four-base error-left fielderABROther
ABR:03:03:08:04Other-Scored on four-base error-center fielderABROther
ABR:03:03:09:04Other-Scored on four-base error-right fielderABROther
OBE:01:01:NA:NAPick-off-outOBEOut
OBE:01:02:NA:NASteal Attempt-outOBEOut
OBE:01:03:NA:02Force play out at 2ndOBEOut
OBE:01:03:NA:03Force play out at 3rdOBEOut
OBE:01:03:NA:04Force play out at homeOBEOut
OBE:02:01:NA:NAStealOBEAdvance
OBE:02:02:01:02steal attempt-error on pitcher-runner reaches 2ndOBEAdvance
OBE:02:02:01:03steal attempt-error on pitcher-runner reaches 3rdOBEAdvance
OBE:02:02:01:04steal attempt-error on pitcher-runner scoresOBEAdvance
OBE:02:02:02:02steal attempt-error on catcher-runner reaches 2ndOBEAdvance
OBE:02:02:02:03steal attempt-error on catcher-runner reaches 3rdOBEAdvance
OBE:02:02:02:04steal attempt-error on catcher-runner scoresOBEAdvance
OBE:02:02:03:02steal attempt-error on first baseman-runner reaches 2ndOBEAdvance
OBE:02:02:03:03steal attempt-error on first baseman-runner reaches 3rdOBEAdvance
OBE:02:02:03:04steal attempt-error on first baseman-runner scoresOBEAdvance
OBE:02:02:04:02steal attempt-error on second baseman-runner reaches 2ndOBEAdvance
OBE:02:02:04:03steal attempt-error on second baseman-runner reaches 3rdOBEAdvance
OBE:02:02:04:04steal attempt-error on second baseman-runner scoresOBEAdvance
OBE:02:02:05:02steal attempt-error on third baseman-runner reaches 2ndOBEAdvance
OBE:02:02:05:03steal attempt-error on third baseman-runner reaches 3rdOBEAdvance
OBE:02:02:05:04steal attempt-error on third baseman-runner scoresOBEAdvance
OBE:02:02:06:02steal attempt-error on shortstop-runner reaches 2ndOBEAdvance
OBE:02:02:06:03steal attempt-error on shortstop-runner reaches 3rdOBEAdvance
OBE:02:02:06:04steal attempt-error on shortstop-runner scoresOBEAdvance
OBE:02:02:07:02steal attempt-error on left fielder-runner reaches 2ndOBEAdvance
OBE:02:02:07:03steal attempt-error on left fielder-runner reaches 3rdOBEAdvance
OBE:02:02:07:04steal attempt-error on left fielder-runner scoresOBEAdvance
OBE:02:02:08:02steal attempt-error on center fielder-runner reaches 2ndOBEAdvance
OBE:02:02:08:03steal attempt-error on center fielder-runner reaches 3rdOBEAdvance
OBE:02:02:08:04steal attempt-error on center fielder-runner scoresOBEAdvance
OBE:02:02:09:02steal attempt-error on right fielder-runner reaches 2ndOBEAdvance
OBE:02:02:09:03steal attempt-error on right fielder-runner reaches 3rdOBEAdvance
OBE:02:02:09:04steal attempt-error on right fielder-runner scoresOBEAdvance
OBE:02:03:01:02Pick off attempt-error on pitcher-runner reaches 2ndOBEAdvance
OBE:02:03:01:03Pick off attempt-error on pitcher-runner reaches 3rdOBEAdvance
OBE:02:03:01:04Pick off attempt-error on pitcher-runner scoresOBEAdvance
OBE:02:03:02:02Pick off attempt-error on catcher-runner reaches 2ndOBEAdvance
OBE:02:03:02:03Pick off attempt-error on catcher-runner reaches 3rdOBEAdvance
OBE:02:03:02:04Pick off attempt-error on catcher-runner scoresOBEAdvance
OBE:02:03:03:02Pick off attempt-error on first baseman-runner reaches 2ndOBEAdvance
OBE:02:03:03:03Pick off attempt-error on first baseman-runner reaches 3rdOBEAdvance
OBE:02:03:03:04Pick off attempt-error on first baseman-runner scoresOBEAdvance
OBE:02:03:04:02Pick off attempt-error on second baseman-runner reaches 2ndOBEAdvance
OBE:02:03:04:03Pick off attempt-error on second baseman-runner reaches 3rdOBEAdvance
OBE:02:03:04:04Pick off attempt-error on second baseman-runner scoresOBEAdvance
OBE:02:03:05:02Pick off attempt-error on third baseman-runner reaches 2ndOBEAdvance
OBE:02:03:05:03Pick off attempt-error on third baseman-runner reaches 3rdOBEAdvance
OBE:02:03:05:04Pick off attempt-error on third baseman-runner scoresOBEAdvance
OBE:02:03:06:02Pick off attempt-error on shortstop-runner reaches 2ndOBEAdvance
OBE:02:03:06:03Pick off attempt-error on shortstop-runner reaches 3rdOBEAdvance
OBE:02:03:06:04Pick off attempt-error on shortstop-runner scoresOBEAdvance
OBE:02:03:07:02Pick off attempt-error on left fielder-runner reaches 2ndOBEAdvance
OBE:02:03:07:03Pick off attempt-error on left fielder-runner reaches 3rdOBEAdvance
OBE:02:03:07:04Pick off attempt-error on left fielder-runner scoresOBEAdvance
OBE:02:03:08:02Pick off attempt-error on center fielder-runner reaches 2ndOBEAdvance
OBE:02:03:08:03Pick off attempt-error on center fielder-runner reaches 3rdOBEAdvance
OBE:02:03:08:04Pick off attempt-error on center fielder-runner scoresOBEAdvance
OBE:02:03:09:02Pick off attempt-error on right fielder-runner reaches 2ndOBEAdvance
OBE:02:03:09:03Pick off attempt-error on right fielder-runner reaches 3rdOBEAdvance
OBE:02:03:09:04Pick off attempt-error on right fielder-runner scoresOBEAdvance
OBE:02:04:01:02batted ball-error on pitcher-runner reaches 2ndOBEAdvance
OBE:02:04:01:03batted ball-error on pitcher-runner reaches 3rdOBEAdvance
OBE:02:04:01:04batted ball-error on pitcher-runner scoresOBEAdvance
OBE:02:04:02:02batted ball-error on catcher-runner reaches 2ndOBEAdvance
OBE:02:04:02:03batted ball-error on catcher-runner reaches 3rdOBEAdvance
OBE:02:04:02:04batted ball-error on catcher-runner scoresOBEAdvance
OBE:02:04:03:02batted ball-error on first baseman-runner reaches 2ndOBEAdvance
OBE:02:04:03:03batted ball-error on first baseman-runner reaches 3rdOBEAdvance
OBE:02:04:03:04batted ball-error on first baseman-runner scoresOBEAdvance
OBE:02:04:04:02batted ball-error on second baseman-runner reaches 2ndOBEAdvance
OBE:02:04:04:03batted ball-error on second baseman-runner reaches 3rdOBEAdvance
OBE:02:04:04:04batted ball-error on second baseman-runner scoresOBEAdvance
OBE:02:04:05:02batted ball-error on third baseman-runner reaches 2ndOBEAdvance
OBE:02:04:05:03batted ball-error on third baseman-runner reaches 3rdOBEAdvance
OBE:02:04:05:04batted ball-error on third baseman-runner scoresOBEAdvance
OBE:02:04:06:02batted ball-error on shortstop-runner reaches 2ndOBEAdvance
OBE:02:04:06:03batted ball-error on shortstop-runner reaches 3rdOBEAdvance
OBE:02:04:06:04batted ball-error on shortstop-runner scoresOBEAdvance
OBE:02:04:07:02batted ball-error on left fielder-runner reaches 2ndOBEAdvance
OBE:02:04:07:03batted ball-error on left fielder-runner reaches 3rdOBEAdvance
OBE:02:04:07:04batted ball-error on left fielder-runner scoresOBEAdvance
OBE:02:04:08:02batted ball-error on center fielder-runner reaches 2ndOBEAdvance
OBE:02:04:08:03batted ball-error on center fielder-runner reaches 3rdOBEAdvance
OBE:02:04:08:04batted ball-error on center fielder-runner scoresOBEAdvance
OBE:02:04:09:02batted ball-error on right fielder-runner reaches 2ndOBEAdvance
OBE:02:04:09:03batted ball-error on right fielder-runner reaches 3rdOBEAdvance
OBE:02:04:09:04batted ball-error on right fielder-runner scoresOBEAdvance
OBE:02:05:NA:02Advance on hit-runner reaches 2ndOBEAdvance
OBE:02:05:NA:03Advance on hit-runner reaches 3rdOBEAdvance
OBE:02:05:NA:04Advance on hit-runner scoresOBEAdvance


In the next section I will begin to fill out the structure of the data entry interface.



Next-Fleshing out the Data Entry Interface