end of an era
May. 28th, 2017 | 02:37 am
Crazy to close the book after... 14 years? More?
I'll leave all the posts up of course.
Link | Leave a comment | Share | Flag
Hello
Aug. 28th, 2013 | 03:36 am
Well, I don't like them in a certain way. You understand. Or you don't. Anyway.
Yeah. Moving to Seattle gave me the opportunity (as fake as it may have been; there's no reason I couldn't have done this in Cleveland) to change my life. And I did. I have become even more introverted, more of a jerk (mostly just brutally honest), and more anti-academic than I used to be. Which is hard, considering.
Still very hard on myself.
Oh, I have a two-year old son. Tycho. He is a pain in the ass. Advice: If you like your life, don't have kids. Not saying that I liked my life before I had kids, but just saying that if you don't want everything you do to be completely removed from your life, you shouldn't have a kid. Because that's what happened with me. In some respects, this was a good thing. In others, not so much. But oh well.
I kinda miss this place. It is clear it has a niche that no other social media site ever really replaced. Or ever will, probably.
Believe it or not, I still read my Friends List every so often. And maybe I just pick the right people, but it sure seems like many of you have done something exceptional with your lives. And that is awesome.
Continue being great. And write about it. I'd write about how I went from a nobody baseball trainer to giving seminars and having pros fly out to train at our facility, but the intersection of science and sports is a small one indeed - especially the one I happen to reside in. As such, no one cares. Which really kinda sucks. Well maybe you care, but you aren't interested in having a 4 hour long conversation about it with me. Which is what I really want.
But if there were enough people willing to have that conversation with me, I wouldn't be dominating my niche, I guess. I learn a lot about entrepreneurship and really how lonely it can be with each passing day.
Anyway, keep on. Especially you,
Link | Leave a comment | Share | Flag
Hmm
Mar. 3rd, 2012 | 05:16 am
I still think about a lot of you guys, believe it or not. And I still read my friends list once a week. Have done so for 11.5 years. Pretty amazing, actually.
Hope all is well out there.
Link | Leave a comment {1} | Share | Flag
Mass Geolocation Script (PHP)
Apr. 26th, 2011 | 04:02 pm
Originally published at Kyle Boddy. You can comment here or there.
I recently wrote a mass geolocation script in PHP since Google seems to be taking down all the websites that offer this vital service. Right now it:
- Checks a table for records without lat/long coordinates
- Sends those records' addresses to Google's geolocation API
- Updates your records with the lat/long coordinates
It checks for the "#" sign and handles it since Google has problems with translating "2020 Anywhere Place #200" as a real address, but there are probably other errors I haven't adequately checked for.
At the moment it updates records that are missing lat/long coordinates and writes zeroes into those fields if it can't geolocate the address correctly. As a result, if you run the script again, it will assume those records were updated correctly and will pass over them, since they are not null. This is a known issue and is one (of many) areas of improvement for the script.
I didn't want to spend a ton of hours on the script to make it a full-fledged awesome service, since Google doesn't seem to like that. It's just a basic script that handles common problems and works well enough.
You can get it over at my GitHub repo page for GeoCode. Enjoy.
Link | Leave a comment | Share | Flag
Football Outsiders is a Joke
Apr. 20th, 2011 | 04:29 pm
Originally published at Kyle Boddy. You can comment here or there.
This article is terrible and I'm not really going to explain why, but anytime you see this kind of language:
-were chosen in the first two rounds
-had at least 33 games started in college
-completed at least 58 percent of passes in college
You can be reasonably sure the author is either lying, stupid, and/or dishonest. Note that these three traits are not mutually exclusive from one another.
Link | Leave a comment {1} | Share | Flag
Newest XAMPP Doesn’t Work as Expected
Apr. 4th, 2011 | 11:23 pm
Originally published at Kyle Boddy. You can comment here or there.
I was going to type up a giant thing about why the newest XAMPP doesn't work well with MySQL because it's packaged with a beta PHP version and stuff... but I honestly don't want to elaborate. Just know that I wasted 4-6 hours of my life and about an hour of Site5's support because of the newest XAMPP being a beta product without the label.
If you use Windows, don't use XAMPP 1.7.4. Use 1.7.3 and get it from the SourceForge archive. Trust me.
Link | Leave a comment | Share | Flag
Minor League Splits Redux Launched
Apr. 1st, 2011 | 10:39 am
Originally published at Kyle Boddy. You can comment here or there.
I've launched yet another half-complete web application relating to baseball sabermetrics! ML Splits is a database of minor league baseball players (batters only for now) that shows their "splits" (performance against LHP and RHP) as well as park effects and major league equivalencies. The data is taken from Jeff Sackmann's old minorleaguesplits.com site where he made the CSVs available for import as open source.
I leaned on jQuery for front-end display purposes, as I'm getting more and more comfortable with using it for front-facing web applications. Mostly just dynamic div tagging and toggle() to keep the screen clear of distractions and make it easy to see what stats are really important. Wrote the entire thing in PHP 5.3.x, MySQL 5, CodeIgniter 2.0, and jQuery.
Enjoy!
EDIT: Pitchers are up as of April 4th.
Link | Leave a comment | Share | Flag
Springloops is awesome, HeidiSQL is annoying, Site5 disappoints
Mar. 24th, 2011 | 09:16 am
Originally published at Kyle Boddy. You can comment here or there.
I've started to use Springloops RC2 for my version control efforts, which is really awesome. They support SVN and git (no Mercurial yet), have a great interface with easy deployments to multiple servers so you can split them up into production/staging/development, a solid ticketing system, and a good code browser. Also, it's completely free!
HeidiSQL has been my Windows MySQL GUI of choice ever since I switched to it from Toad. It's generally very good, it's FOSS, and it handles most operations fairly well - except for CSV importing. Site5 is my current webhost, and I'm very happy with them 99.9% of the time, but they caused me a bit of pain recently. I have a lot of CSVs to import that are about 10-15 MB in size each, and I tried importing them through the very handy phpmyadmin tool. However, phpmyadmin has some memory leaks and issues with importing larger CSVs, so it ended up crashing due to memory problems on the larger files (even though it theoretically can handle up to 105MB CSVs). I sent Site5 a ticket to have them import the CSVs manually (they said they would), but they responded with "there's no table structure in your DB so we can't do it." Well, uh, that's what phpmyadmin does and why I wanted to use it over the 7 tables I need to make with 20 or so CSV files. They refused again without providing me an alternative, so I had do it myself.
I fired up HeidiSQL, manually created the tables, and imported the CSV. And... it didn't work. I ignored the first row (column headers), but it still responded with "invalid data." The fields were correctly cast for the rest of the data, so I didn't know what was up. A bit of Googling tells me that even if you ignore the first row, HeidiSQL still checks it against the data types in your table. This is idiotic and annoying for any number of reasons, all of which I leave up to you to figure out.
At any rate, deleting the first row and ignoring 0 rows ended up working just fine. Now to do this repetitive task over and over again...
Link | Leave a comment | Share | Flag
Advanced Injury Database: RESTful Web Service Launched
Mar. 17th, 2011 | 11:22 pm
Originally published at Kyle Boddy. You can comment here or there.
I've launched a RESTful web interface for my Advanced Baseball Injury Database. A major problem with PITCHf/x and injury databases are that people are building them over and over against on their local (or hosted) servers, and this is a huge amount of overhead for the sabermetric community. The way to properly do this is to have one giant amalgamated database with a few trusted caretakers that deal with the updating/maintenance/feature requests while everyone else accesses the data using RESTful web services.
This makes updating and standardizing a dataset much easier and gives end users a much easier back-end interface into the database.
To access the RESTful service, you must first authenticate with the Advanced Baseball Injury Database over Facebook. (Anti-Facebook users: Get over it. I'm not going to spam your wall or steal your info, and I made this database entirely open for you to use.) You can do that on the Detailed Injuries Service page. This stores a unique key in my database and grants you access to make RESTful requests.
Example of the key
Easy enough. Copy that key down. You will need this going forward.
Making the Request: High-Level Overview
All you have to do to get injury information about ANY player from 2002-2010 is to go to this URL:
http://injurydb.drivelinebaseball.com/index.php/injurydb/injuryservice/eliasid/key
(I've been told that "eliasID" is the wrong term and I'm supposed to use mlbAMID. However, I've already coded it like "eliasid" and that's what I call it in real life, so you'll just have to deal with it if it bothers you.)
For example, if you use Jered Weaver's eliasID (450308) and my key (66- wait a minute, nice try), you get this in your web browser (squashed for easier reading):
Looks pretty ridiculous, right? Well, that's JavaScript Object Notation - JSON. You can easily parse that to get this:
So, how do you do that? Good question.
Making the Request: Low-Level Overview
If you've read this far, you probably want some code examples. No problem. I am a PHP/CodeIgniter/MySQL kind of guy, so those are the examples I'm going to give to you. However, I'm including both the simple way - file_get_contents() - and the tougher (but more universal) way - cURL. They should be all you need to get going.
Here's how you can use file_get_contents() in PHP to decode the JSON and echo it out to the browser:
function testinjuryservice()
{
// point it to Jered Weaver's eliasID and return it to the browser
$contents = file_get_contents('http://injurydb.drivelinebaseball.com/index.php/injurydb/injuryservice/450308/YOURKEYHERE');
// decode the json returned from the service
$info = json_decode($contents);
// count number of injury movements
// must cast object into an array to accurately count the number of injuries
$injuries = count((array)$info);
$x = 1;
while ($x <= $injuries)
{
// echo $info->{$x}->{'DateOn'};
// you would use the above line to get the "DateOn" value for the xth injury
// repeat this with DateOff, injury, injury_type, etc
// dump contents of the given injury out
print_r($info->{$x});
echo '<br />';
$x++;
}
}
And here's the cURL example:
function testinjuryservice()
{
// open cURL
$ch = curl_init();
// point it to Jered Weaver's eliasID and return it to the browser
curl_setopt($ch, CURLOPT_URL,
'http://injurydb.drivelinebaseball.com/index.php/injurydb/injuryservice/450308/YOURKEYHERE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// assign it to $contents
$contents = curl_exec ($ch);
// close cURL
curl_close ($ch);
// decode the json returned from the service
$info = json_decode($contents);
// count number of injury movements
// must cast object into an array to accurately count the number of injuries
$injuries = count((array)$info);
$x = 1;
while ($x <= $injuries)
{
// echo $info->{$x}->{'DateOn'};
// you would use the above line to get the "DateOn" value for the xth injury
// repeat this with DateOff, injury, injury_type, etc
// dump contents of the given injury out
print_r($info->{$x});
echo '<br />';
$x++;
}
}
VERY IMPORTANT: I start the JSON array at 1, not 0. Don't be a slave to default counting. Humans start at 1 when they count up.
If you screw up the eliasID or your authentication key, you will get this error in the array's first position:
{"1":{"1":"Invalid key or eliasID given."}}
Alternatively, I may have banned you from the service for too many requests, which segues well into the next point: Don't abuse this system. This is not meant for you to spider my entire database by requesting every player's information from eliasID 10 (Kris Benson: fun fact) to eliasID 9999999999. Can't we all get along?
Where Do We Go From Here?
Well, if you like the service, drop me a line - kyle at driveline baseball dot com. I'd love to hear from you, and if you want to collaborate, that's cool too.
You can keep an eye out for my articles at The Hardball Times, where I write about PITCHf/x stuff and exercise science things. Or check out my baseball training company's site, Driveline Baseball.
I plan on developing a RESTful PITCHf/x interface in the future depending on interest, my motivational levels, free time, and how much I think this is going to wreck my bandwidth costs. Ideally a bunch of us pitch in, rent a cheap VPS, and we serve it up to all sabermetricians who are interested in this kind of stuff. We write tutorials and make it open source and grant freedom of information. Is that feasible? Who knows!
Have fun.
