<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-20282472</id><updated>2011-12-13T13:14:44.270-08:00</updated><category term='ucla'/><category term='baseball'/><category term='xml'/><category term='dvorak'/><category term='javascript'/><category term='personal'/><category term='java'/><category term='basketball'/><category term='comedy'/><category term='politics'/><category term='perl'/><category term='poker'/><category term='shopping'/><category term='jsp'/><category term='camping'/><category term='xslt'/><category term='tomcat'/><category term='wisdom teeth'/><category term='varargs'/><category term='javascript ppr'/><category term='comparator'/><category term='nephew'/><category term='vegas'/><category term='css'/><category term='netflix'/><category term='video conversion'/><category term='python'/><category term='fantasy'/><category term='spring'/><category term='outdoors'/><category term='generics'/><category term='design'/><category term='snowboarding'/><category term='tv'/><category term='football'/><category term='greasemonkey'/><category term='xp'/><category term='2008'/><category term='giants'/><category term='safe passwords'/><category term='hardware'/><category term='subversion'/><title type='text'>David Lee's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>51</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20282472.post-6606154316983871317</id><published>2009-10-27T22:27:00.000-07:00</published><updated>2009-10-27T23:01:41.635-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><title type='text'>Retiring yahoo fantasy greasemonkey scripts</title><content type='html'>Two years ago, I wrote &lt;a href="http://robobruin.blogspot.com/2007/11/2007-fantasy-basketball-script-released.html"&gt;a couple&lt;/a&gt; of popular greasemonkey scripts that allowed yahoo fantasy users to easily see live stats for their fantasy team.  At the time, users who didn't shell out the 10 bucks to buy stattracker had to wait until the following day to see how their players performed.  I didn't think that was fair so I automated the process of clicking through the boxscore link, parsing out the stat for a player, and summarizing it in a nice modal window.

Starting this football season and continuing with basketball today, yahoo has decided to offer stattracker for free!  This means that the scripts I released are no longer needed.  Competition from other fantasy sites most likely compelled yahoo to offer it for free, but I'd like that all of you who used it, told your friends about it, and sent me bug and suggestions also forced their hand :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-6606154316983871317?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/6606154316983871317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=6606154316983871317' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6606154316983871317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6606154316983871317'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2009/10/retiring-yahoo-fantasy-greasemonkey.html' title='Retiring yahoo fantasy greasemonkey scripts'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-1039080038219600237</id><published>2008-09-04T23:40:00.000-07:00</published><updated>2008-09-20T00:09:46.900-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript ppr'/><title type='text'>initializing js objects with many parameter</title><content type='html'>&lt;p&gt;For the past couple of months I've been working on a &lt;a href="http://apps.new.facebook.com/fbfantasy/landing"&gt;fantasy football&lt;/a&gt; application on facebook.  I worked primarily on the &lt;a href="http://2.bp.blogspot.com/_IX0yJPHv9K4/SNQfGxDocyI/AAAAAAAAACE/HaGQD3YI8is/s1600-h/liveDraft.png"&gt;live online draft&lt;/a&gt; and &lt;a href="http://1.bp.blogspot.com/_IX0yJPHv9K4/SNQfgum4CBI/AAAAAAAAACM/3tvmWx3vPco/s1600-h/liveScoring.png"&gt;real time fantasy scoring&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was a lot of work and also a lot of fun.  My coworkers and I spent many a night and weekend getting the site looking and working correctly.  I was worried that I would get sick of thinking about football but luckily that never happened. I want to share what I learned on this project so I thought I'd start with an easy one that is now part of my personal pattern repository (ppr).&lt;/p&gt;

&lt;p&gt;What's the best way to initialize a js object with lots of initial state?  Originally, I passed in function parameters:  function init(param1, param2, param3).  As the complexity increased, I found myself passing in more and more parameters.&lt;/p&gt;

&lt;p&gt;the init string was generated on the server side so my code looked like&lt;br/&gt; 
String.format("init(%s,%s,%s,%s);", param1, param2, param3, param4). &lt;/p&gt; 

&lt;p&gt;Whenever I added a new parameter I had to change the server side code and also the js file.&lt;/p&gt;

&lt;p&gt;After a couple of changes I wizened up and found a much better way to do things.  on the server side, I created a JSONObject and set up my parameters like so:&lt;/p&gt;

JSONObject json = new JSONObject().put("param1", param1).put("param2", param2)....&lt;br/&gt;
String.format("init(%s)", json.toString())&lt;br/&gt;

&lt;p&gt;And on the js file:&lt;/p&gt;
&lt;pre&gt;
function init(params) {
var param1 = params.param1;
var param2 = params.param2;
...
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-1039080038219600237?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/1039080038219600237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=1039080038219600237' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/1039080038219600237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/1039080038219600237'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2008/09/initializing-js-objects-with-many.html' title='initializing js objects with many parameter'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-8902571529605618879</id><published>2008-03-31T21:29:00.000-07:00</published><updated>2008-03-31T22:26:41.400-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='giants'/><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><category scheme='http://www.blogger.com/atom/ns#' term='2008'/><title type='text'>Your 2008 San Francisco Giants</title><content type='html'>&lt;p&gt;Goodbye Barry Bonds, hello Brian Bocock.  This year's team is going to be tough to watch.  The heart of our lineup is Randy Winn, Bengie Molina, and Ray Durham.  I expect Aaron Rowand to move up from his sixth spot in the lineup within a few games but as of opening day, the 3-4-5 hitters are embarrassing.  Thankfully, baseball is not all about offense and the strength of this team is the starting pitching.   Pundits predict that we'll win around 60 games this year but I really think we have a good shot at .500 if the pitching performs as expected and if our hitters exceed expectations.  Without further adieu, here are my optimistic predictions for the 2008 season.&lt;/p&gt;

&lt;p&gt;Pitching&lt;/p&gt;
&lt;p&gt;The trio of Matt Cain, Tim Lincecum, and Barry Zito will win 45 games.&lt;/p&gt;

&lt;p&gt;The Giants bullpen will be the strength of the team and will be ranked top 5 in the NL in holds, ERA, and WHIP.&lt;/p&gt;

&lt;p&gt;Hitting&lt;/p&gt;
&lt;p&gt;Aaron Rowand will hit above .300, steal 15 bases, and drive in 100 runs.&lt;/p&gt;

&lt;p&gt;Rajai Davis and Eugenio Velez will steal a combined 60 bases.&lt;/p&gt;

&lt;p&gt;Benjie Molina will hit .290 with 30 homers.&lt;/p&gt;

&lt;p&gt;sorry...I can't do this anymore.  Here's my tip for all Giants fans this season:  Don't miss Cain and Lincecum pitch and check out the &lt;a href="http://sanfrancisco.giants.mlb.com/schedule/promotions.jsp?c_id=sf"&gt;2008 promotional schedule&lt;/a&gt; for some bobbleheads.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-8902571529605618879?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/8902571529605618879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=8902571529605618879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8902571529605618879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8902571529605618879'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2008/03/your-2008-san-francisco-giants.html' title='Your 2008 San Francisco Giants'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-6122634488576610429</id><published>2007-11-04T00:06:00.000-07:00</published><updated>2008-02-22T22:41:28.149-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='fantasy'/><title type='text'>2007 Fantasy basketball script  released</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_IX0yJPHv9K4/Ry1yG0hI3KI/AAAAAAAAAB8/zmRfS5oXd68/s1600-h/basketball.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_IX0yJPHv9K4/Ry1yG0hI3KI/AAAAAAAAAB8/zmRfS5oXd68/s200/basketball.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5128881012147281058" /&gt;&lt;/a&gt;
&lt;p&gt;*update - 2/22/2008 - updated the script to handle new yahoo boxscores for in progress games&lt;/p&gt;
&lt;p&gt;I couldn't sleep last night (Friday night...actually Sat at 2am to be exact) so I stayed up and implemented the two missing features for the &lt;a href="http://userscripts.org/scripts/show/6177"&gt;live stats basketball script&lt;/a&gt;: maintaining the order of players in the modal window and displaying a summary of all active players' stats.&lt;/p&gt;

&lt;p&gt;The first feature was easy to implement since I had already solved that problem for &lt;a href="http://userscripts.org/scripts/show/5143"&gt;baseball&lt;/a&gt;.  The old technique of adding a row after retrieving a player's stats leads to indeterminate ordering because we do not wait for a boxscore request to finish before moving on to the next.  Therefore, it was possible that a UTIL player who is towards the bottom of the management page would actually be processed faster than a PG depending on how snappy the server handled the request.  The solution is to create placeholder rows that have the correct order and then update those rows later.&lt;/p&gt;

&lt;p&gt;The second feature is summarizing all your players' stats for the night.  Unlike a baseball boxscore where a player's stats appear on multiple parts of the page and some stats need to be derived, all basketball stats appear on one row.  That's why I didn't create full blown function objects that had getter/setters for stats like assists, turnovers, pts, boards, etc.  Instead, I went the lightweight route and defined two rules that are used to summarize stats.  If the stat has a dash, like 7-11, then we keep track of total made and total attempts, else we just sum up the current stat with the running total.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-6122634488576610429?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/6122634488576610429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=6122634488576610429' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6122634488576610429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6122634488576610429'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/11/2007-fantasy-basketball-script-released.html' title='2007 Fantasy basketball script  released'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_IX0yJPHv9K4/Ry1yG0hI3KI/AAAAAAAAAB8/zmRfS5oXd68/s72-c/basketball.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-503413527203514140</id><published>2007-10-31T23:00:00.000-07:00</published><updated>2007-10-31T23:16:31.124-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><category scheme='http://www.blogger.com/atom/ns#' term='fantasy'/><title type='text'>halloween treat</title><content type='html'>&lt;p&gt;No candy to pass out but I did make a few tweaks to my &lt;a href="http://userscripts.org/scripts/show/6177"&gt;fantasy basketball live scoring script&lt;/a&gt;. Like the modified &lt;a href="http://userscripts.org/scripts/show/5143"&gt;baseball version&lt;/a&gt;, the script no longer automatically loads.  The user has to trigger it by clicking on the 'show freebie stats' link.  I also ripped out the autocenter on scroll code since that was causing display issues for users on low resolution monitors.&lt;/p&gt;

&lt;p&gt;The two biggest missing features that I will tackle next are maintaining the order on the display and totaling all your active players' stats.  But I probably won't get to that until the weekend.  don't fret, yahoo provides free stats for the first couple of weeks of the season so you're covered.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-503413527203514140?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/503413527203514140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=503413527203514140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/503413527203514140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/503413527203514140'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/10/halloween-treat.html' title='halloween treat'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-6878828621618130717</id><published>2007-10-14T17:31:00.000-07:00</published><updated>2007-10-14T17:44:13.853-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comedy'/><title type='text'>annoying commercial parody</title><content type='html'>SNL lampooned one of the most annoying commercials that has been playing during the LCS.

&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fdE5UbCC1qQ"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/fdE5UbCC1qQ" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/uu04-fY_pzc"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/uu04-fY_pzc" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-6878828621618130717?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/6878828621618130717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=6878828621618130717' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6878828621618130717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6878828621618130717'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/10/annoying-commercial-parody.html' title='annoying commercial parody'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-1379880389715006164</id><published>2007-10-02T21:37:00.000-07:00</published><updated>2007-10-02T22:32:45.056-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>Fantasy baseball recap</title><content type='html'>&lt;p&gt;Back in March, Yahoo Sports invited average Joes to go head-to-head against their fantasy experts in baseball.  I answered the call and was pitted in a 16 team, head-to-head league with Big Noise himself, Brad Evans.  My key draft picks were Chipper, Magglio, Markakis, and Jose Reyes.  My waiver wire gems were Ryan Braun and Carlos Pena, who I swapped for Derek Lee just before the trading deadline.  My offense carried me the entire season because my only good pitcher was Josh Beckett.  Since it was a head-to-head league, I knew that if my offense held up, I could stream pitchers if I reached the playoffs.&lt;/p&gt;

&lt;p&gt;Only 6 out of 16 teams qualified for the playoffs and I made it as a 3rd place qualifier.  This meant that I didn't have a first round bye which is always a bit dangerous.  Luckily, my team held up and I moved on to the semifinals against the 2nd place team.  We both had off weeks but my team went on to win.  Waiting for me in the championship showdown was Brad Evans' team.  He was on a roll and I had to go through him to win the championship.  I was up to the challenge and pulled out all the stops like streaming pitchers to win the W and K categories and picking hot September additions such as Jacoby Ellsbury and Norris Hopper.&lt;/p&gt;

&lt;p&gt;Just like the regular season, my offense carried me and streaming pitchers yielded wins in the W and K categories.  In the end, it was a fun season and I'm thankful that Yahoo opened the league up and that Brad Evans took some time to go up against some of his readers.&lt;/p&gt;

&lt;p&gt;Pics or it didn't happen:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_IX0yJPHv9K4/RwMoQ6lPtDI/AAAAAAAAAB0/H2ZyF4ubfN8/s1600-h/giants.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_IX0yJPHv9K4/RwMoQ6lPtDI/AAAAAAAAAB0/H2ZyF4ubfN8/s320/giants.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5116977872691508274" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-1379880389715006164?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/1379880389715006164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=1379880389715006164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/1379880389715006164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/1379880389715006164'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/10/fantasy-baseball-recap.html' title='Fantasy baseball recap'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_IX0yJPHv9K4/RwMoQ6lPtDI/AAAAAAAAAB0/H2ZyF4ubfN8/s72-c/giants.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-6258438828573260099</id><published>2007-10-01T22:16:00.001-07:00</published><updated>2007-10-01T22:42:27.663-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>Padres out, Rockies in</title><content type='html'>Thank goodness for TBS.  Too bad &lt;a href="http://sports.yahoo.com/mlb/recap?gid=271001127"&gt;this game&lt;/a&gt; was not televised on the networks because it was an instant classic that saw the Rockies come back against the man with the most saves in the history of baseball.  I actually didn't see the comeback because I was peeved that Scott Hairston hit another clutch homer for the Padres and went to do the dishes.  This guy has been killing the Giants all year and during the last week of the regular season he tossed the bat about 20 feet after blasting a homer off Matt Cain.  Cain let him have it and it'll be interesting to see these guys matched up next year.

When I came back from doing the dishes, I saw that the Rockies had won and that Holliday scored the winning run.  What a relief that must have been since he was the one that misplayed the Brian Giles flyball that led to the Padres tying the game.  If this game was any indication how the playoffs will be played, then we're all in for a treat.  My sleeper pick is the Cubs but I think either Boston or Cleveland will win it all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-6258438828573260099?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/6258438828573260099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=6258438828573260099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6258438828573260099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6258438828573260099'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/10/padres-out-rockies-in.html' title='Padres out, Rockies in'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-3785770335556653016</id><published>2007-10-01T22:02:00.000-07:00</published><updated>2007-10-01T22:13:59.724-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video conversion'/><title type='text'>Converting a large AVI file to a smaller WMV file for picasa or youtube</title><content type='html'>&lt;p&gt;I was uploading pictures and videos from a company outing and soon discovered that the max file size for uploads to PicasaWeb is 100MB.  So I decided to give YouTube a try but the max upload size on YouTube was also 100MB.&lt;/p&gt;

&lt;p&gt;I took the video on my digital camera and it was in AVI format.  I needed something that would convert this file to a smaller size.  A couple of google searches later I discovered that Microsoft has a free WMV converter.  The program provides different output quality settings and soon I was able to get my 162MB avi file to a 11MB wmv.  Here's the download link:  &lt;a href="http://www.microsoft.com/windows/windowsmedia/forpros/encoder/default.mspx"&gt;http://www.microsoft.com/windows/windowsmedia/forpros/encoder/default.mspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you aren't running Windows, &lt;a href="http://www.mplayerhq.hu/design7/dload.html"&gt;mplayer&lt;/a&gt; might be sufficient for your video conversion needs.  But the Linux version of Picasa doesn't allow uploading to web albums so you will have to do it through the web interface.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-3785770335556653016?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/3785770335556653016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=3785770335556653016' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3785770335556653016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3785770335556653016'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/10/converting-large-avi-file-to-smaller.html' title='Converting a large AVI file to a smaller WMV file for picasa or youtube'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-7700246799817388143</id><published>2007-09-28T00:01:00.000-07:00</published><updated>2007-09-28T21:40:49.339-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>Giants 2007 Recap</title><content type='html'>&lt;p&gt;Now that the season is winding down, it&amp;#39;s time to revisit &lt;a href="http://robobruin.blogspot.com/2007/02/fresh-start.html"&gt;my extremely optimistic outlook&lt;/a&gt; for the Giants 2007 baseball season. Granted, some of these predictions (see Benitez) were best case, Brady Anderson ala 1996 scenarios, but as the 2005 White Sox proved, it can happen.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Pitching&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Prediction:  Zito will assume ace responsibilities and that new windup may give him that extra zip and movement.&lt;/p&gt;

&lt;p&gt;Reality: The new windup was abandoned in the first week of spring training because the Giants didn&amp;#39;t pay for new windup Barry.  Barry had one of his worst seasons as a professional.  &lt;/p&gt;

&lt;p&gt;Running tally: 0-1&lt;/p&gt;

&lt;p&gt;Prediction:  A seasoned Matt Cain, aka Bobby Hill, will have learned how to pitch&lt;/p&gt;

&lt;p&gt;Reality: Cain&amp;#39;s W-L record belies how he well he pitched because the record could have been reversed if the Giants gave him more run support or if the relief pitchers didn&amp;#39;t blow his leads.   He definitely matured from his rookie year and mixed sliders and change ups to go with that nasty fastball.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Running tally: 1-1&lt;/p&gt;

&lt;p&gt;Prediction:  Noah Lowry might be able to fool hitters once more&lt;/p&gt;

&lt;p&gt;Reality: Before Noah got injured he was among the league leaders in wins.  He doesn&amp;#39;t have overpowering stuff and runs a lot of counts to 3-2 but he still keeps the games close and finds ways to get guys to miss on fastballs never topping 90.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Running tally: 2-1&lt;/p&gt;

&lt;p&gt;Prediction:  Matt Morris will be able to avoid that one big inning blowup he always has&lt;/p&gt;

&lt;p&gt;Reality:  nope.  same old Morris after a promising start and eventually traded to the Pirates for Rajai Davis.&lt;/p&gt;

&lt;p&gt;Running tally: 2-2&lt;/p&gt;

&lt;p&gt;Prediction:  The fifth starter, whether it is a renewed Russ Ortiz or rookie sensations Linceum or Sanchez will surprise the league by storm.&lt;/p&gt;

&lt;p&gt;Reality: I sure gave myself some leeway here by counting on at least 1 of 3 players to have a good year.  Lincecum really did show the league that he&amp;#39;s a special player.  Whenever he pitches the opposing team is always at the railing checking him out. &lt;/p&gt;

&lt;p&gt;Running tally: 3-2&lt;/p&gt;

&lt;p&gt;Prediction:  Benitez will be in shape and less of a headcase.&lt;/p&gt;

&lt;p&gt;Reality: Nope.  same old Benitez.  Traded before the break to the Marlins for Randy Messenger.&lt;/p&gt;

&lt;p&gt;Running tally: 3-3&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Hitting&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Prediction:  old guys will be injury free&lt;/p&gt;

&lt;p&gt;Reality:  wishful thinking.  Durham, Roberts, Bonds spent significant time on the DL.&lt;/p&gt;

&lt;p&gt;Running tally: 3-4&lt;/p&gt;

&lt;p&gt;Prediction:  Barry Bonds will break Hank&amp;#39;s record by early August so the team can concentrate on the playoff push&lt;/p&gt;

&lt;p&gt;Reality: Barry broke the record in early August but playoff hopes were pretty much gone at that point.  half right = half wrong = a push&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Running tally: still 3-4&lt;/p&gt;

&lt;p&gt;Prediction:  Dave Roberts will be that leadoff hitter we haven&amp;#39;t had since Brett Butler&lt;/p&gt;

&lt;p&gt;Reality: injured for most of the first half, came on strong for awhile and then leveled off.  Splitting time with Rajai Davis so can&amp;#39;t say he&amp;#39;s that good.&lt;/p&gt;

&lt;p&gt;Running tally: 3-5&lt;/p&gt;

&lt;p&gt;Prediction: Rich Aurilia pounds 40 homers and shows Seattle fans why they once signed him to big bucks&lt;/p&gt;

&lt;p&gt;Reality: yeah right.  that was the last prediction so I went for the juggernaut.  Rich Aurilia couldn't beat out Ryan Klesko for the starting first base job.&lt;/p&gt;

&lt;p&gt;Final tally: 3-6 which pretty much sums up the Giants season.  But next year, we&amp;#39;ll be back.&lt;br&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-7700246799817388143?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/7700246799817388143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=7700246799817388143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/7700246799817388143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/7700246799817388143'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/giants-2007-recap.html' title='Giants 2007 Recap'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-3426574987305836002</id><published>2007-09-26T22:10:00.000-07:00</published><updated>2007-09-26T22:14:17.562-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Logging request and response headers in Tomcat</title><content type='html'>&lt;p&gt;What&amp;#39;s the best way to dump out request or response headers in Tomcat?&lt;/p&gt;

&lt;p&gt;Before rolling up your own solution, take a look at the &lt;a href="http://tomcat.apache.org/tomcat-5.0-doc/config/valve.html"&gt;valve&lt;/a&gt; component that Tomcat supports.  In particular, the aptly named &lt;a href="http://tomcat.apache.org/tomcat-5.0-doc/config/valve.html#Request Dumper Valve"&gt;RequestDumperValve&lt;/a&gt; will log all the request and response headers in Tomcat.  To enable the valve,  just go to your server.xml file in the /conf directory and uncomment this line:  &lt;/p&gt;

&lt;p&gt;&amp;lt;Valve className=&amp;quot;org.apache.catalina.valves.RequestDumperValve&amp;quot;/&amp;gt;&lt;/p&gt;

&lt;p&gt;Then restart your server and the headers will appear in your log file.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-3426574987305836002?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/3426574987305836002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=3426574987305836002' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3426574987305836002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3426574987305836002'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/logging-request-and-response-headers-in.html' title='Logging request and response headers in Tomcat'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-8605522356859646334</id><published>2007-09-25T23:12:00.000-07:00</published><updated>2007-09-26T22:13:07.869-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Javascript composite comparator</title><content type='html'>&lt;p&gt;Since it's available on every modern web browser, Javascript captures the title as the world's most deployed programming language.  But while its availability is almost universal, its reputation is less than stellar.  Douglas Crockford wrote a great piece on Javascript being the &lt;a href="http://www.crockford.com/javascript/javascript.html"&gt;world's most misunderstood programming language&lt;/a&gt;.  He lists several reasons such as design errors, bad early implementations, and even naming the language Javascript which implied it being like Java and it being no more than a simple scripting language.&lt;/p&gt;

&lt;p&gt;I'll admit that my initial opinion was quite down as well.  I used it strictly as a C clone and cringed anytime I had to debug a script.  But now that I have had more exposure to and experience with the language features such as closures and first class functions, I've definitely reversed my opinion.  It's so useful to perform client side processing with such a full fledged language at my disposal.&lt;/p&gt;

&lt;p&gt;This post wouldn't do Javascript justice if it didn't have some accompanying code, so I'll revisit my &lt;a href="http://robobruin.blogspot.com/2007/09/composite-comparator-fun-with-generics.html"&gt;Java generics and varargs post&lt;/a&gt; and reimplement the composite comparator using Javascript.&lt;/p&gt;

&lt;p&gt;To recap, the composite comparator (aka cascading comparator or chained comparator) is a comparator made up of several other comparators.  My Java 1.5 implementation uses the varargs language feature to yield a simple to use api that accepts a variable amount of comparators.&lt;/p&gt;

&lt;p&gt;Since javascript is dynamically typed and supports variable length arguments, the implementation looks pretty similar.&lt;/p&gt;

&lt;code&gt;
This is our player object:&lt;br /&gt;
&lt;br /&gt;
function player(name, hr, rbi, sb) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;this.name=name;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;this.hr=parseInt(hr);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;this.rbi=parseInt(rbi);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;this.sb=parseInt(sb);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Let's create some players and populate a players array:&lt;br /&gt;
var a = new player('Arod',50,150,1);&lt;br /&gt;
var b = new player('Reyes',50,150,2);&lt;br /&gt;
var c = new player('Bonds',50,150,3);&lt;br /&gt;
&lt;br /&gt;
var players = new Array(a,b,c);&lt;br /&gt;
&lt;br /&gt;
Next, we need to create some comparators:&lt;br /&gt;
function sortRbi(a, b) {&lt;br /&gt;
&amp;#160;&amp;#160; return a.rbi - b.rbi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function sortHr(a,b) {&lt;br /&gt;
&amp;#160;&amp;#160; return a.hr-b.hr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function sortSb(a,b) {&lt;br /&gt;
&amp;#160;&amp;#160; return a.sb-b.sb;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Here's the composite comparator:&lt;br /&gt;
function compositeSort() {&lt;br /&gt;
&amp;#160;&amp;#160;var args = Array.prototype.slice.call(arguments);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; return function(a,b) {&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (var i=0;i&amp;lt;args.length;i++) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var result = args[i](a,b);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;if (result!=0) { &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return result;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; return 0;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Here's a negate comparator:&lt;br /&gt;
function negate(func) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;return function(a,b) {&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;var i=func(a,b);&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;if (i==0)&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;return i;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;else&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;return -i;&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This comparator will sort by hr ascending, rbi ascending, and sb descending.&lt;br /&gt;
var comp = compositeSort(sortHr,sortRbi,negate(sortSb));&lt;br /&gt;
&lt;br /&gt;
And now we pass the newly created comparator to the built in sort method in arrays.&lt;br /&gt;
players.sort(comp)
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-8605522356859646334?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/8605522356859646334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=8605522356859646334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8605522356859646334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8605522356859646334'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/javascript-composite-comparator.html' title='Javascript composite comparator'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-3194370182406712517</id><published>2007-09-24T23:20:00.000-07:00</published><updated>2007-09-25T00:01:14.677-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='xslt'/><title type='text'>xslt stylesheet to convert xml to tab delimited file</title><content type='html'>Sometimes, you just want a tab delimited text file.  For those occasions, here's the xslt to convert an xml file to a tab delimited file.   the tab and newline characters might get converted when displayed on the screen so do a view source if the select=" " shows whitespace

&lt;textarea class="code"&gt;
&lt;xsl:stylesheet version='1.0'
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    &lt;xsl:output omit-xml-declaration="yes"/&gt;
    &lt;xsl:variable name="tab" select="'&amp;#09;'" /&gt;
    &lt;xsl:variable name="newline" select="'&amp;#10;'" /&gt;

    &lt;xsl:template match="/"&gt;
        &lt;xsl:apply-templates select="//player"/&gt;
    &lt;/xsl:template&gt;

    &lt;xsl:template match="player"&gt;
        &lt;xsl:value-of select="first_name"/&gt;
        &lt;xsl:value-of select="$tab" /&gt;
        &lt;xsl:value-of select="last_name"/&gt;
        &lt;xsl:value-of select="$newline" /&gt;
    &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
&lt;/textarea&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-3194370182406712517?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/3194370182406712517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=3194370182406712517' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3194370182406712517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3194370182406712517'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/xslt-stylesheet-to-convert-xml-to-tab.html' title='xslt stylesheet to convert xml to tab delimited file'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-4488797279467462896</id><published>2007-09-21T17:21:00.001-07:00</published><updated>2007-09-26T22:15:01.500-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>It's official.  The Barry Bonds era has come to an end</title><content type='html'>&lt;p&gt;&lt;a href="http://sanfrancisco.giants.mlb.com/news/article.jsp?ymd=20070921&amp;content_id=2222175&amp;vkey=news_sf&amp;fext=.jsp&amp;c_id=sf"&gt;It's official&lt;/a&gt;.  Barry Bonds will not be a San Francisco Giant next year.&lt;/p&gt;

&lt;p&gt;Many people outside of the Bay Area don't understand the relationship Giants fans have with Barry.  We know he took steroids.  We know he's arrogant.  We know he's mean to reporters.  So why is it that we don't hate him like the rest of America?  Because he's a Giant.  Because he grew up in the Bay Area. Because his dad played for the Giants and because his godfather is Willie Mays.  Because he's not the only guy that ever took steroids and because he was a hall of famer caliber player before he juiced up.  Because 1993 was a magical season.&lt;/p&gt;

&lt;p&gt;To be competing for a division title a year removed from a woeful season and rumors of a move to St. Petersbug was invigorating.  Suddenly it was fun to be a Giants fan again.  Barry put the franchise on his back and carried the organization through the opening of Pac Bell Park, into the World Series in 2002, and even up to when he broke the home run record.  That's a lot of great memories.   He's been the face of the Giants for 15 years and when you're loyal to your team,  you're going to be loyal to the face of the franchise too.  Go Giants!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-4488797279467462896?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/4488797279467462896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=4488797279467462896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/4488797279467462896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/4488797279467462896'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/its-official-barry-bonds-era-has-come.html' title='It&apos;s official.  The Barry Bonds era has come to an end'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-4045747844893259256</id><published>2007-09-20T22:47:00.001-07:00</published><updated>2007-09-26T00:30:56.495-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><title type='text'>Would you leave 63 million on the table?</title><content type='html'>&lt;p&gt;&lt;a href="http://sports.espn.go.com/nba/news/story?id=3029816"&gt;Andrei Kirilenko would.&lt;/a&gt;   He's so unhappy playing for Jerry Sloan that he's willing to forego the rest of his max contract which equates to 63 million dollars.  Is this guy for real?  Most guys want to void or renegotiate their contract to make &lt;span style="font-style:italic;"&gt;more&lt;/span&gt; money.  Kirilenko's already got a max deal and the way he's played the last two years he's never going to get that sweet a deal again. &lt;/p&gt;

&lt;p&gt;He played for the Russian team this summer and was the main man so maybe he missed being the go to guy.  Maybe he just really misses home.  Maybe he was misquoted and the interview was taken out of context.  Maybe a Russian oil tycoon has promised him even more cash to play in Russia. &lt;/p&gt;

&lt;p&gt;Whatever the reason I'm sure more of the story will come out in the coming weeks.  I've always been a big Kirilenko fan.  He won me over many years ago when he went ballistic in a Rookie vs Sophomore game during All star weekend.  The other players were playing lackadaisically and AK was subbed in and was a beast of defense.  He guarded guys tight, swatted shots, and went to the basket hard.  It was refreshing to see since those games are more and1 than nba.  He's also been a favorite because he resembled Ivan Drago from Rocky IV so my old roommates and I would shout out the "I must break you" voice every time he blocked a shot.&lt;/p&gt;

&lt;p&gt;Good luck Kirilenko!  I hope you get whatever makes you happy.  I'd definitely like to see you in a Warriors uniform.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-4045747844893259256?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/4045747844893259256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=4045747844893259256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/4045747844893259256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/4045747844893259256'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/would-you-leave-63-million-on-table.html' title='Would you leave 63 million on the table?'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-7344370388415776075</id><published>2007-09-19T21:49:00.000-07:00</published><updated>2007-09-26T00:33:49.277-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Schwarzian Transform</title><content type='html'>&lt;p&gt;I like to remind myself of this Perl gem every so often.  I always call it Schwarzian transform but it's actually &lt;a href="http://en.wikipedia.org/wiki/Schwartzian_transform"&gt;Schwartzian transform&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;
#using schwarzian transform
#@sorted contains objects sorted by their distance
my @sorted=
map {$_-&gt;[1]}
sort { $a-&gt;[0] &lt;=&gt; $b-&gt;[0] }
map { [$_-&gt;distance(), $_ ] } @{$paObject};

map EXPRESSION, list returns a new list whose elements are the outcome of the expression
Example: @newArray = map {uc $_}, @array
is just
@array = qw(a b c d);
@newArray = ();
foreach my $temp (@array) {
   push @newArray, uc $temp;
} 

back to the example...
$paObject is a pointer to an array of objects.   The object has a method name distance() that returns an int
@{$paObject} dereferences the array.
working backwards,

map { [$_-&gt;distance(), $_ ] } @{$paObject}, creates an array like [[10,object reference 1],[2,object reference 2]]

and then feeds that into sort { $a-&gt;[0] &lt;=&gt; $b-&gt;[0] } which sorts according to the element at index 0

keeping with this example it yields [[2,object reference 2],[10, object reference 1]] 
which is fed into map {$_-&gt;[1]} which selects element at index 1

so now @sorted contains [object reference 2, object ref]

The benefit of the algorithm is that you only call the distance() method for each object once.  
If this method is computationally intensive and the list is large, the savings can be quite large.  
If your list is small, it's probably better to something like: @sorted =  {$a &lt;=&gt; $b} @unsorted
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-7344370388415776075?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/7344370388415776075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=7344370388415776075' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/7344370388415776075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/7344370388415776075'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/schwarzian-transform.html' title='Schwarzian Transform'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-749997898023470771</id><published>2007-09-18T20:02:00.000-07:00</published><updated>2007-09-18T20:10:28.810-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>fixing IE checkbox padding/margin</title><content type='html'>Support for CSS is built in to every modern browser so theoretically we shouldn't have to deal with too many layout issues. Unfortunately, a lot of browser specific quirks still exist.

One I've dealt with recently is getting a checkbox to line up exactly to the left of a div.  Setting the left margin and padding did not work in IE and I was going to try really drastic measures like setting float or absolute positioning until I found a really easy solution.  To fix the extra padding for checkboxes in IE, we just need to give the checkbox a fixed width.

I've summarized the results in the table with some screenshots.  The markup I want to style is:
&lt;pre&gt;
&lt;code&gt;
&amp;lt;div&amp;gt;
&amp;lt;p&amp;gt;some text before&amp;lt;/p&amp;gt;
&amp;lt;input type="checkbox"/&amp;gt; checkbox 1&amp;lt;br/&amp;gt;
&amp;lt;input type="checkbox"/&amp;gt; checkbox 2&amp;lt;br/&amp;gt;
&amp;lt;p&amp;gt;some text after&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;
&lt;br/&gt;
&lt;table valign="top" border="1" cellspacing="10"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th width="10%"&gt;FireFox&lt;/th&gt;
&lt;th width="10%"&gt;IE&lt;/th&gt;
&lt;th width="40%"&gt;CSS&lt;/th&gt;
&lt;th width="40%"&gt;notes&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://2.bp.blogspot.com/_IX0yJPHv9K4/RvAm5HYXrVI/AAAAAAAAABE/YM4Cjzhhauo/s1600-h/ff_no_cb_style.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_IX0yJPHv9K4/RvAm5HYXrVI/AAAAAAAAABE/YM4Cjzhhauo/s200/ff_no_cb_style.png" alt="" id="BLOGGER_PHOTO_ID_5111628339741175122" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://4.bp.blogspot.com/_IX0yJPHv9K4/RvAnEnYXrWI/AAAAAAAAABM/3npVjptpAQY/s1600-h/ie7_no_cb_style.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_IX0yJPHv9K4/RvAnEnYXrWI/AAAAAAAAABM/3npVjptpAQY/s200/ie7_no_cb_style.png" alt="" id="BLOGGER_PHOTO_ID_5111628537309670754" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
div {border: solid 1px #000;width:150px;}

p {padding:0;margin:0;}

&lt;/td&gt;
&lt;td&gt;no styling on checkbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="http://4.bp.blogspot.com/_IX0yJPHv9K4/RvAnPnYXrXI/AAAAAAAAABU/XNes3WYgMxQ/s1600-h/ff_no_margin.png"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_IX0yJPHv9K4/RvAnPnYXrXI/AAAAAAAAABU/XNes3WYgMxQ/s200/ff_no_margin.png" alt="" id="BLOGGER_PHOTO_ID_5111628726288231794" border="0" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://1.bp.blogspot.com/_IX0yJPHv9K4/RvAna3YXrYI/AAAAAAAAABc/B0AGYo8DZg8/s1600-h/ie7_no_margin.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_IX0yJPHv9K4/RvAna3YXrYI/AAAAAAAAABc/B0AGYo8DZg8/s200/ie7_no_margin.png" alt="" id="BLOGGER_PHOTO_ID_5111628919561760130" border="0" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
div {border: solid 1px #000;width:150px;}

p {padding:0;margin:0;}

input {padding-left:0;margin-left:0;}

&lt;/td&gt;
&lt;td&gt;style checkbox to have no left padding or margin.  only Firefox behaves as expected&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;a href="http://1.bp.blogspot.com/_IX0yJPHv9K4/RvAnk3YXrZI/AAAAAAAAABk/KqKEWMXUPcM/s1600-h/ff_fixed_width.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_IX0yJPHv9K4/RvAnk3YXrZI/AAAAAAAAABk/KqKEWMXUPcM/s200/ff_fixed_width.png" alt="" id="BLOGGER_PHOTO_ID_5111629091360451986" border="0" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://3.bp.blogspot.com/_IX0yJPHv9K4/RvAntXYXraI/AAAAAAAAABs/wkOkAlev2oY/s1600-h/ie7_fixed_width.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_IX0yJPHv9K4/RvAntXYXraI/AAAAAAAAABs/wkOkAlev2oY/s200/ie7_fixed_width.png" alt="" id="BLOGGER_PHOTO_ID_5111629237389340066" border="0" /&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
div {border: solid 1px #000;width:150px;}

p {padding:0;margin:0;}

input {padding-left:0;margin-left:0;width:15px;}

&lt;/td&gt;
&lt;td&gt;
added a fixed width and now IE7 looks fine too!
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-749997898023470771?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/749997898023470771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=749997898023470771' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/749997898023470771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/749997898023470771'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/fixing-ie-checkbox-paddingmargin.html' title='fixing IE checkbox padding/margin'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IX0yJPHv9K4/RvAm5HYXrVI/AAAAAAAAABE/YM4Cjzhhauo/s72-c/ff_no_cb_style.png' height='72' width='72'/><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-5913918346258695267</id><published>2007-09-17T21:32:00.000-07:00</published><updated>2007-09-26T00:35:37.417-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>spring initbinder example that registers custom editor</title><content type='html'>&lt;p&gt;One of the nice features in Spring is the automatic databinding that occurs if you use one of the subclasses of BaseCommandController such as AbstractCommandController or SimpleFormController. By automatic databinding, I mean Spring initializing your command object based on the request parameters.
The magic behind this feature is Spring's builtin property editors which do things like convert strings to integers. Sooner or later, however, you'll run into a situation where you need to do some custom databinding by registering your own PropertyEditor through the initBinder() method.&lt;/p&gt;
&lt;pre&gt;
Suppose this is my command class:

&lt;code&gt;
class FootballPlayer {

static enum POSITION {RB, WR, QB, DB, LB}



POSITION _position;



public POSITION getPosition() {

return _position;

}



public void setPosition(POSITION position) {

_position = position;

}

}

&lt;/code&gt;


So if my request parameter is ?positon=rb and I want my command class to have the correct enum set, do the following:
First, create a custom property editor.
&lt;code&gt;
class FootBallPlayerEditor extends PropertyEditorSupport {

public String getAsText() {

FootballPlayer editor = (FootballPlayer) getValue();

return editor.getPosition().name();

}



public void setAsText(final String text) {

setValue(FootballPlayer.POSITION.valueOf(text));

}

}

&lt;/code&gt;

then override initBinder
&lt;code&gt;
protected void initBinder(HttpServletRequest request,

ServletRequestDataBinder binder) {

binder.registerCustomEditor(FootballPlayer.POSITION.class, new FootBallPlayerEditor());

}

&lt;/code&gt;

And you're all set.
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-5913918346258695267?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/5913918346258695267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=5913918346258695267' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/5913918346258695267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/5913918346258695267'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/spring-initbinder-example-that.html' title='spring initbinder example that registers custom editor'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-3889909777596435828</id><published>2007-09-16T23:06:00.000-07:00</published><updated>2007-09-26T00:34:44.615-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shopping'/><title type='text'>'Best Buy'er Beware</title><content type='html'>&lt;p&gt;I picked up an item at my local Best Buy and it rang up at 3 times the listed price.  I politely mentioned to the cashier that this must be a price mistake so she led me to the aisle where she knew the item was being sold.  The problem was that this wasn't the aisle where I picked up my product so I brought her to where &lt;span style="font-style: italic;"&gt;I&lt;/span&gt; found the item.  Sure enough, the price was the lower and so she sold me the item at the price I originally saw. &lt;/p&gt;

&lt;p&gt;Seems odd that the same item was listed at different prices in two parts of the store.  I found mine near the back and the other one was near the cashier.  Either I got lucky or this is a Best Buy ploy to overcharge their customers.  Moral of the story is twofold.  One, do a walk through to see if your item is priced differently at a different spot in the store. Two, make sure you're watching when they ring up your order.  Buyer beware.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-3889909777596435828?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/3889909777596435828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=3889909777596435828' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3889909777596435828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3889909777596435828'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/best-buyer-beware.html' title='&apos;Best Buy&apos;er Beware'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-6703032291914064578</id><published>2007-09-15T12:12:00.000-07:00</published><updated>2007-09-26T00:36:35.930-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='football'/><title type='text'>And you thought Roger Goddell was a disciplanarian</title><content type='html'>&lt;p&gt;Roger Goddell is the commissioner of the NFL.  Since he's taken over the top role about a year ago, he's suspended numerous players for 'conduct detrimental to the league' and now he's laid the law down among the coaches too.&lt;/p&gt;

&lt;p&gt;The Patriots were caught taping the Jets as they were relaying defensive signals down to the field.  The penalty for this action?  A $500,000 fine for Belichick, head coach of the Patriots, a $250,000 fine for Bill Kraft, the owner of the Patriots, and the loss of a first round draft pick.   The penalty wasn't too severe since Belichick wasn't suspended but it definitely wasn't a slap on the wrist either.  I thought it was actually pretty fair since the lost of a first rounder could come back to bite them down the line and Belichick now has less cash to buy hooded sweatshirts and warmup pants.&lt;/p&gt;

&lt;p&gt;Contrast this penalty with the &lt;a href="http://canadianpress.google.com/article/ALeqM5gqtOoiYBSBPPYMCHRmZ-20tvUJYw"&gt;hammer that was dropped&lt;/a&gt; when Mclaren was found in possession with Ferrari's playbook.  A 100 million dollar fine and suspension from the team championships.  That's right...100 miiiiiilliooooooon dollars!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-6703032291914064578?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/6703032291914064578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=6703032291914064578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6703032291914064578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/6703032291914064578'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/and-you-thought-roger-goddell-was.html' title='And you thought Roger Goddell was a disciplanarian'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-2432305796314956645</id><published>2007-09-14T19:10:00.000-07:00</published><updated>2007-09-26T00:28:51.284-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='comparator'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='varargs'/><title type='text'>Composite Comparator - Fun with generics and varargs</title><content type='html'>&lt;p&gt;A couple of new features in Java 5 are the additions of &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html"&gt;generics&lt;/a&gt; and &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html"&gt;varargs&lt;/a&gt;. We use generics a lot when returning a list from our &lt;a href="http://java.sun.com/blueprints/patterns/DAO.html"&gt;DAOs &lt;/a&gt;but I've never had to implement a method that accepted varargs until I implemented this &lt;a href="http://www.greatschools.net/school/parentReviews.page?id=6397&amp;amp;state=CA"&gt;parent reviews page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a typical page where a user may sort by date or by rating. Another feature is that a principal's review for a school always comes first. So the sorting is like so:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By Principal, then date descending&lt;/li&gt;
&lt;li&gt;By Principal, then date ascending&lt;/li&gt;
&lt;li&gt;By Principal, then rating, then descending&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First thing I needed to do was create a couple of comparators. I used the static final comparator approach that that Josh Block talks about in Effective Java. I'll demonstrate with a baseball class.  The nice thing about the composite comparator is that now I can create a comparator based on hr,rbi, and anything else I wanted to add later like sb, runs, etc.&lt;/p&gt;
Example:&lt;br/&gt;
&lt;code&gt;
&lt;pre&gt;
public class BaseBallPlayer {

   private int _rbi;

   private int _hr;



   public BaseBallPlayer(int rbi, int hr) {

       _rbi = rbi;

       _hr = hr;

   }



   public static final Comparator HR_COMPARATOR = new Comparator&amp;lt;BaseBallPlayer&amp;gt;() {

       public int compare(BaseBallPlayer o1, BaseBallPlayer o2) {

           return o1.getRbi() - o2.getRbi();

       }

   };



   public static final Comparator RBI_COMPARATOR = new Comparator&amp;lt;BaseBallPlayer&amp;gt;() {

       public int compare(BaseBallPlayer o1, BaseBallPlayer o2) {

           return o1.getHr() - o2.getHr();

       }

   };



   public int getHr() {

       return _hr;

   }



   public int getRbi() {

       return _rbi;

   }

}

public class GenericComparator {

   public static &amp;lt;T&amp;gt;Comparator&amp;lt;T&amp;gt; createComparator(final Comparator&amp;lt;T&amp;gt;... c) {

       return new Comparator&amp;lt;T&amp;gt;() {

           public int compare(T r1, T r2) {

               int result = 0;

               for (Comparator&amp;lt;T&amp;gt; comp : c) {

                   result = comp.compare(r1, r2);

                   if (result != 0) {

                       break;

                   }

               }

               return result;

           }

       };

   }

}

   Comparator&amp;lt;BaseBallPlayer&amp;gt; HR_RBI_COMPARATOR = GenericComparator.&amp;lt;BaseBallPlayer&amp;gt;createComparator(

                   BaseBallPlayer.HR_COMPARATOR, BaseBallPlayer.RBI_COMPARATOR);

&lt;/pre&gt;
&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-2432305796314956645?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/2432305796314956645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=2432305796314956645' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/2432305796314956645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/2432305796314956645'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/composite-comparator-fun-with-generics.html' title='Composite Comparator - Fun with generics and varargs'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-1475322737541652156</id><published>2007-09-13T16:13:00.000-07:00</published><updated>2007-09-26T00:37:02.844-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Gauntlet thrown</title><content type='html'>&lt;p&gt;I'm challenging myself to do a posting at least once a day for the next 30 days.  This might not sound like a big deal to you super posters out there but have you seen my last posting date?  It's been months and the updates have been sorely lacking.&lt;/p&gt;

&lt;p&gt;I know what some of you may be thinking..."But Dave, I come here only for the thoroughly researched content and the essay like blog postings!"&lt;/p&gt;

&lt;p&gt;Fear not loyal readers, quantity &lt;span style="font-style: italic;"&gt;can equal&lt;/span&gt; quality.  Plus, have you mistaken this blog for &lt;a href="http://www.paulgraham.com"&gt;Paul Graham's&lt;/a&gt;?  I'll continue to write is my stream of consciousness manner, but this time it will be a lot more often so expect a new blog entry for the next 30 days.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-1475322737541652156?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/1475322737541652156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=1475322737541652156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/1475322737541652156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/1475322737541652156'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/09/gauntlet-thrown.html' title='Gauntlet thrown'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-3846548336679563790</id><published>2007-04-12T19:37:00.000-07:00</published><updated>2007-09-26T22:51:35.330-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='fantasy'/><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>2007 yahoo fantasy baseball script</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_IX0yJPHv9K4/Ri7bH7yzC3I/AAAAAAAAAA8/thX3D7An7PM/s1600-h/freebieStatsBaseball.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_IX0yJPHv9K4/Ri7bH7yzC3I/AAAAAAAAAA8/thX3D7An7PM/s200/freebieStatsBaseball.jpg" alt="" id="BLOGGER_PHOTO_ID_5057220360939965298" border="0" /&gt;&lt;/a&gt;
&lt;p&gt;update 4/24/2007&lt;br/&gt;
&lt;a href="http://userscripts.org/scripts/show/5143"&gt;Script updated&lt;/a&gt;.  Fixed issues &lt;a href="http://code.google.com/p/freebiestats/issues/detail?id=3"&gt;3&lt;/a&gt; and &lt;a href="http://code.google.com/p/freebiestats/issues/detail?id=6"&gt;6&lt;/a&gt; reported by Rodric Rabbah and lots of code refactoring.
The script no longer automatically loads the window.  You have to activate it by pressing on the
blue "Show Freebie Stats" button on the top right.&lt;/p&gt;

&lt;p&gt;update 4/18/2007&lt;br/&gt;
&lt;a href="http://userscripts.org/scripts/show/5143"&gt;Script updated&lt;/a&gt;.  Fixed issues &lt;a href="http://code.google.com/p/freebiestats/issues/detail?id=4"&gt;4&lt;/a&gt; and &lt;a href="http://code.google.com/p/freebiestats/issues/detail?id=5"&gt;5&lt;/a&gt; reported by Ethan Herbertson.&lt;/p&gt;

&lt;p&gt;update 4/16/2007
To use the script, follow these 3 steps
&lt;ol&gt;&lt;li&gt;download &lt;a href="http://www.getfirefox.com/"&gt;firefox&lt;/a&gt;&lt;/li&gt;&lt;li&gt;install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;greasemonkey&lt;/a&gt; extension&lt;/li&gt;&lt;li&gt;after installing greasemonkey, &lt;a href="http://userscripts.org/scripts/show/5143"&gt;install the script&lt;/a&gt;
&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;

&lt;p&gt;I just updated my &lt;a href="http://robobruin.blogspot.com/2006/08/greasemonkey-fantasy-baseball-script.html"&gt;fantasy baseball script&lt;/a&gt; for 2007.   The most obvious change is that I incorporated the UI from my &lt;a href="http://robobruin.blogspot.com/2006/10/yahoo-fantasy-basketball-live-scoring.html"&gt;fantasy basketball script&lt;/a&gt; but there are also a bunch of under-the-hood fixes too.  I go into some detail in those two blog postings on how the scripts are implemented so I won't recap any of that here but I will describe one bug fix.  Stolen bases and homers are not part of the boxscore and they require extra parsing.&lt;/p&gt;

&lt;p&gt;The stolen base string is of the form: D. Roberts 2 (2nd Inning off J. Bard), B. Bonds (3rd inning off J. Bard)&lt;/p&gt;

&lt;p&gt;My old regular expression was a simple check to see if a players name was part of the string.  The problem was that if  I had J. Bard on my team, then he got a stolen base even though he was the one that allowed the steal.  To fix the problem, I deleted everything in parentheses first.&lt;/p&gt;

&lt;p&gt;That regular expression looks like:  statLine = statLine.replace(/\([^\)].+?\)/gi,'');  The key is '?' which makes it a non greedy match and [^\)] which tells the engine when to stop.&lt;/p&gt;

&lt;p&gt;Another thing that bothered me was calling mozilla's childNodes method on a table row returned some unexpected results.  Instead of returning a list of td elements, it would also return some additional children.  To remedy this annoyance, I call row.getElementsByTagName("TD") and then I get a list of td elements that I expect.  That said, I'm much happier with Mozilla's handling of the dom api and the development plugins available in FireFox.  My day job is as web developer for a high traffic site where we strive for pixel, perfect perfection between IE 6,7 and firefox so developing for just one browser was a nice break.&lt;/p&gt;


&lt;p&gt;&lt;a href="http://userscripts.org/scripts/show/5143"&gt;Install the script&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-3846548336679563790?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/3846548336679563790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=3846548336679563790' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3846548336679563790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/3846548336679563790'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/04/2007-yahoo-fantasy-baseball-script.html' title='2007 yahoo fantasy baseball script'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_IX0yJPHv9K4/Ri7bH7yzC3I/AAAAAAAAAA8/thX3D7An7PM/s72-c/freebieStatsBaseball.jpg' height='72' width='72'/><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-8753844463683513251</id><published>2007-04-08T22:30:00.000-07:00</published><updated>2007-04-08T22:37:01.042-07:00</updated><title type='text'>Best DNP description ever</title><content type='html'>My good friend Johnny sent me a link to the &lt;a href="http://sports.yahoo.com/nba/boxscore?gid=2007040524"&gt;best boxscore DNP description&lt;/a&gt; ever.  We know Robert Horry is not the same player he used to be, but come on San Antonio, the man with six rings deserves a bit more respect.
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_IX0yJPHv9K4/RhnQrwcHUQI/AAAAAAAAAA0/i4OpY9uvtEU/s1600-h/dnp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_IX0yJPHv9K4/RhnQrwcHUQI/AAAAAAAAAA0/i4OpY9uvtEU/s320/dnp.jpg" alt="" id="BLOGGER_PHOTO_ID_5051297907228496130" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-8753844463683513251?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/8753844463683513251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=8753844463683513251' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8753844463683513251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8753844463683513251'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/04/best-dnp-description-ever.html' title='Best DNP description ever'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IX0yJPHv9K4/RhnQrwcHUQI/AAAAAAAAAA0/i4OpY9uvtEU/s72-c/dnp.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-4271317414957368022</id><published>2007-03-25T18:24:00.000-07:00</published><updated>2007-09-26T22:52:39.947-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>inspiron 700m broken cd rom drive</title><content type='html'>&lt;p&gt;the cd rom drive on my laptop broke a couple of months ago and I never bothered to get it replaced since it never got any use.  then yesterday I wanted to install turbotax.  To workaround the missing drive, I mounted my desktop's cd rom drive and then accessed it through the network.  problem solved!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-4271317414957368022?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/4271317414957368022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=4271317414957368022' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/4271317414957368022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/4271317414957368022'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/03/inspiron-700m-broken-cd-rom-drive.html' title='inspiron 700m broken cd rom drive'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-5674185004021471500</id><published>2007-02-20T10:14:00.000-08:00</published><updated>2007-09-26T22:53:11.141-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><title type='text'>2007 nba dunk contest</title><content type='html'>&lt;p&gt;Two thoughts entered my mind when I was watching the slam dunk competition:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt; Must be a direct correlation between the winner and the win pct of their team because the last couple of years players from the Celtics, Knicks, and Hawks have won.&lt;/li&gt;&lt;li&gt;Dwight Howard was robbed.  That &lt;a href="http://youtube.com/watch?v=K5saBDOE6Sc"&gt;sticker dunk&lt;/a&gt; was original and difficult.  He also had to do it in one attempt or else the shock factor would have been lost.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-5674185004021471500?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/5674185004021471500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=5674185004021471500' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/5674185004021471500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/5674185004021471500'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/02/2007-nba-dunk-contest.html' title='2007 nba dunk contest'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-7781590078994239541</id><published>2007-02-16T10:49:00.000-08:00</published><updated>2007-09-26T22:54:25.164-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>a fresh start</title><content type='html'>&lt;p&gt;It's a great time of year to be a baseball fan.  The weather is warming up, your team has made some key offseason moves, and everyone is tied for first.  I first became a fan in 1987 while rooting for my hometown team, the San Francisco Giants.  I read every single baseball book in my elementary school library and became fascinated by larger than life personalities with colorful nicknames like the '&lt;a href="http://en.wikipedia.org/wiki/Babe_Ruth"&gt;Sultan of Swat&lt;/a&gt;', the '&lt;a href="http://en.wikipedia.org/wiki/Willie_Mays"&gt;Say Hey Kid&lt;/a&gt;', and the '&lt;a href="http://en.wikipedia.org/wiki/Joe_DiMaggio"&gt;Yankee Clipper&lt;/a&gt;'.  I sneaked a walkman to bed and either fell asleep disappointed or happy depending on the outcome of that night's game.  It remains the only sport where the radio broadcast is just as enjoyable as the television broadcast.&lt;/p&gt;

&lt;p&gt;I also like the team and individual aspects of the game.  A pitcher relies on the players playing behind him to make plays and to score runs.  Yet, at its core is the battle between the hitter making solid contact against a pitcher.  There's also the little things about the game that just work.  Ninety feet is the perfect distance between first and home since the speediest runner can still be thrown out when defense is played perfectly.  That distance is as cool to me as &lt;a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29"&gt;closures&lt;/a&gt;. While the infield is of uniform dimension, the outfield can vary widely between stadium to stadium.  A ball crushed to right-center will be an out in Pac Bell Park but a homer in practically every other stadium.  While park designers may embellish these idiosyncacies, *cough Minute Maid Park hill*, there's no denying the beauty of the Old Tiger Stadium and Fenway Park.&lt;/p&gt;

&lt;p&gt;The optimist in me believes the Giants can make a playoff push bolstered by their improved pitching.  Zito will assume ace responsibilties and that new windup may give him that extra zip and movement.  A seasoned Matt Cain, aka Bobby Hill, will have learned how to pitch, Noah Lowry might be able to fool hitters once more, and Matt Morris will be able to avoid that one big inning blowup he always has.  The fifth starter, whether it is a renewed Russ Ortiz or rookie sensations Linceum or Sanchez will surprise the league by storm and Benitez will be in shape and less of a headcase.&lt;/p&gt;

&lt;p&gt;On the offensive end, the old guys will be injury free.  Barry Bonds will break Hank's record by early August so the team can concentrate on the playoff push and Dave Roberts will be that leadoff hitter we haven't had since Brett Butler.  Rich Aurilia pounds 40 homers and shows Seattle fans why they once signed him to big bucks.&lt;/p&gt;

&lt;p&gt;Its a great time to be a baseball fan.  We're currently in first place.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-7781590078994239541?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/7781590078994239541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=7781590078994239541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/7781590078994239541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/7781590078994239541'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/02/fresh-start.html' title='a fresh start'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-97825676415983213</id><published>2007-02-02T23:56:00.000-08:00</published><updated>2007-09-26T22:55:08.463-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>yahoo sports redesign</title><content type='html'>&lt;p&gt;Wow, yahoo sports has had a &lt;a href="http://sports.yahoo.com/"&gt;major makeover&lt;/a&gt;.   About a year ago, I blogged about &lt;a href="http://robobruin.blogspot.com/2006/01/espns-redesign-my-first-homepage.html"&gt;espn's redesign&lt;/a&gt; and how it was an upgrade.  I feel similar about the new yahoo site but not as excited since espn was the real trailblazer with their css based layout.&lt;/p&gt;

&lt;p&gt;Both sites look really similar now with a huge pic on the LHS and links to articles on the RHS.  But there are some improvements that differentiate the designs.  Yahoo's links to articles has multiple tabs "Headlines", "Rumors", and "Most Popular" which allows for a bunch of links &lt;a href="http://en.wikipedia.org/wiki/Above_the_fold"&gt;above the fold&lt;/a&gt;.  Yahoo also lists the top fantasy performers on the front page which is a nice touch for &lt;a href="http://userscripts.org/scripts/show/6177"&gt;fantasy fanatics like myself&lt;/a&gt;.  That said, the yahoo designers had a year to come up with new stuff and the fact that the site kinda looks like espn really speaks volumes about the espn design.&lt;/p&gt;

&lt;p&gt;The only site I've been visiting for years that remains the same is &lt;a href="http://craigslist.org/"&gt;craigslist&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-97825676415983213?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/97825676415983213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=97825676415983213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/97825676415983213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/97825676415983213'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/02/yahoo-sports-redesign.html' title='yahoo sports redesign'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-8057153906789183990</id><published>2007-01-12T15:21:00.000-08:00</published><updated>2007-09-26T22:57:25.399-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shopping'/><category scheme='http://www.blogger.com/atom/ns#' term='dvorak'/><title type='text'>my first ebay purchase, the kinesis maxim ergonomic keyboard</title><content type='html'>&lt;p&gt;"Welcome to the late nineties!", my coworker Chris jokingly exclaimed when I mentioned during lunch that I had made my first ebay purchase.&lt;/p&gt;

&lt;p&gt;I've been checking out keyboards without number pads and finally splurged on the &lt;a href="http://www.kinesis-ergo.com/max-spec.htm"&gt;maxim kinesis&lt;/a&gt;.  Other models I considered were &lt;a href="http://www.keyovation.com/pc-65-2-goldtouch-adjustable-keyboard-white.aspx"&gt;keyovation's goldtouch&lt;/a&gt;, &lt;a href="http://www.pfu.fujitsu.com/en/hhkeyboard/hhkbpro/black.html"&gt;happy hacking&lt;/a&gt;, and some lower-priced ones: &lt;a href="http://www.amazon.com/Sony-Playstation-2-USB-Keyboard/dp/B00008OQTI"&gt;logitech model made for the playstation 2&lt;/a&gt;, and &lt;a href="http://www.newegg.com/Product/Product.asp?Item=N82E16823128001"&gt;zippy.&lt;/a&gt;    I picked the maxim because I found a new one available for a great price on ebay.  I wanted a keyboard without a number pad so that I wouldn't have to reach as far for the mouse.&lt;/p&gt;

&lt;p&gt;The keys on the maxim are a bit stickier than my old dell quietkey, but I soon got used to the feeling.    The maxim has some neat variable split and tilt features that's supposed to reduce hand fatigue.  The purchase of the maxim also gave me a great excuse to try the &lt;a href="http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard"&gt;Dvorak keyboard layout&lt;/a&gt;.       Since I was getting accustomed to the keyboard anyway, I decided to up the ante.       As an engineer, I've always been impressed with the efficiency of the layout and  plus it's another way to geek out.  &lt;/p&gt;

&lt;p&gt;Dvorak studied letter frequency and designed the layout to maximize hand alternation and minimize movement away from the home keys. The &lt;a href="http://en.wikipedia.org/wiki/QWERTY"&gt;qwerty &lt;/a&gt;layout, on the other hand, was designed to minimize the jamming of keys back when folks still used typewriters.&lt;/p&gt;

&lt;p&gt;Learning Dvorak takes patience and practice.  The first couple of days were a mess.       It took me forever to write a simple email.  I finally had to switch back to qwerty to get any work done.  But I've never been one to give up, so  I practiced at home and by day four I was able to make the switch at work.&lt;/p&gt;

&lt;p&gt;I've been using the new layout for two weeks now and I'm finally competent.  My WPM is around 30 and I expect that to improve since there's usually a month long acclimation process.      One benefit I'm already enjoying is how fresh my hands and wrists feel at the end of the day.  This was my main motivation for making the switch and so far it's paying off.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-8057153906789183990?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/8057153906789183990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=8057153906789183990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8057153906789183990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/8057153906789183990'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/01/my-first-ebay-purchase-kinesis-maxim.html' title='my first ebay purchase, the kinesis maxim ergonomic keyboard'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-2948568991900941615</id><published>2007-01-12T14:23:00.000-08:00</published><updated>2007-09-26T23:04:22.161-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='outdoors'/><category scheme='http://www.blogger.com/atom/ns#' term='snowboarding'/><title type='text'>snowboarding at Donner Ski Ranch</title><content type='html'>&lt;p&gt;I finally hit the slopes last week and it was a great time out.  We went up to &lt;a href="http://www.donnerskiranch.com/"&gt;Donner Ski Ranch&lt;/a&gt; which is a perfect mountain for beginner and intermediate riders.  Perfect because the lift lines are short, the price is cheap, and the slopes aren't too steep.   I concentrated on perfecting my turns and by the end of the day I was leaving some nice 'S' tracks.  I had a couple of hard falls but that was offset by some good runs.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_IX0yJPHv9K4/RaiV3hsfCzI/AAAAAAAAAAM/-3Xgtqh4Has/s1600-h/IMG_1664.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_IX0yJPHv9K4/RaiV3hsfCzI/AAAAAAAAAAM/-3Xgtqh4Has/s320/IMG_1664.jpg" alt="" id="BLOGGER_PHOTO_ID_5019426565874715442" border="0" /&gt;&lt;/a&gt;

&lt;p&gt;I also got to use my new &lt;a href="http://www.leedomhelmets.com/frame_load.php?id=prophet"&gt;Leedom helmet&lt;/a&gt; with built-in speakers for my mp3 player.   The music kept my energy level up while I was practicing toe-side tracks.  The helmet had lots of vents and was really lightweight.   I bought it for $75 from costco online and am really happy with it.&lt;/p&gt;

&lt;p&gt;I definitely see and feel the improvement and look forward to making a few more trips this season.  Here are more pics courtesy of Simon.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_IX0yJPHv9K4/RaiX9xsfC1I/AAAAAAAAAAc/-RM1VuIaJzk/s1600-h/IMG_1673.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_IX0yJPHv9K4/RaiX9xsfC1I/AAAAAAAAAAc/-RM1VuIaJzk/s320/IMG_1673.jpg" alt="" id="BLOGGER_PHOTO_ID_5019428872272153426" border="0" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_IX0yJPHv9K4/RaiXyhsfC0I/AAAAAAAAAAU/1q8Dukbzg_M/s1600-h/IMG_1668.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_IX0yJPHv9K4/RaiXyhsfC0I/AAAAAAAAAAU/1q8Dukbzg_M/s320/IMG_1668.jpg" alt="" id="BLOGGER_PHOTO_ID_5019428678998625090" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-2948568991900941615?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/2948568991900941615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=2948568991900941615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/2948568991900941615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/2948568991900941615'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2007/01/snowboarding-at-donner-ski-ranch.html' title='snowboarding at Donner Ski Ranch'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_IX0yJPHv9K4/RaiV3hsfCzI/AAAAAAAAAAM/-3Xgtqh4Has/s72-c/IMG_1664.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-2537329429523532169</id><published>2006-12-14T13:29:00.000-08:00</published><updated>2007-09-26T22:58:52.321-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='safe passwords'/><category scheme='http://www.blogger.com/atom/ns#' term='wisdom teeth'/><title type='text'>wisdom teeth and remembering passwords</title><content type='html'>&lt;p&gt;This Monday, I had all four of my wisdom teeth removed.  I went the local anesthesia route so I was awake during the procedure while my oral surgeon drilled and pulled at my molars.  The main reason I didn't want to be put under was so that I could eat a ton of food before the removal.  Even though listening to your teeth crack isn't the most pleasant experience, having a full stomach and not being nauseous afterward is a good trade off.  I still can't really chew on food so I've been eating jook, mashed potatoes, and soup for the past few days.  Most of the bleeding and pain is gone by day 2 but my cheeks are still pretty swollen.  I look like a chipmunk blowing a bubble minus the bubble.  I've had a couple of days to rest and so I've been reading, watching tv, surfing the web, and now blogging.  &lt;/p&gt;

&lt;p&gt;In fact, this entry was triggered by the &lt;a href="http://reddit.com/blog/theft"&gt;security breach at reddit.com&lt;/a&gt;.   A hard drive was stolen and reddit recommends that passwords be changed.  Because of the recommendation, commenters assume that the passwords were stored as plain text.  Another top story on reddit, was an &lt;a href="http://www.schneier.com/blog/archives/2006/12/realworld_passw.html"&gt;article on weak passwords&lt;/a&gt; written by security guru Bruce Schneier.  So what better time that to share how I deal with passwords.  For freebie or temp accounts that have no personal info, I use a simple password.  For accounts that need better security, I remember one main password and then use that main password and a unique key that is based on the web url and some other string to generate a password.  I use this &lt;a href="http://www.angel.net/%7Enic/passwd.html"&gt;standalone, javascript password generator&lt;/a&gt; which I have saved on my local machine.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-2537329429523532169?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/2537329429523532169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=2537329429523532169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/2537329429523532169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/2537329429523532169'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/12/wisdom-teeth-and-remembering-passwords.html' title='wisdom teeth and remembering passwords'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-116327864951631057</id><published>2006-11-11T12:33:00.000-08:00</published><updated>2007-09-26T22:59:55.758-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>why I like perl</title><content type='html'>&lt;p&gt;At work, we're primarily a java shop but yesterday I had to edit a perl module that is used by our editorial department.  I looked at an existing function and wanted to refactor it since there was a lot of code duplication.  To do so, I needed to dynamically generate an sql statement.  The statement was of the form:&lt;/p&gt;

Insert into table (col1, col2, .. colx) values (?,?,...,?)&lt;br/&gt;
or Replace into table (col1, col2, .. colx) values (?,?,...,?)&lt;br/&gt;

&lt;p&gt;Array @columns contains the name of the columns.
so to generate the string "col1, col2, col3", it's just: $string1 = join ',', @columns&lt;/p&gt;

&lt;p&gt;now to generate the "?,?,?" strings, it's just $string2 = join ',', map '?', (1.. scalar @columns)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-116327864951631057?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/116327864951631057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=116327864951631057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/116327864951631057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/116327864951631057'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/11/why-i-like-perl.html' title='why I like perl'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-116236548262669172</id><published>2006-10-31T21:41:00.000-08:00</published><updated>2007-11-04T00:33:40.891-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><title type='text'>yahoo fantasy basketball live scoring greasemonkey script</title><content type='html'>&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Updated 2007-Nov-04:&lt;/span&gt; &lt;a href="http://robobruin.blogspot.com/2007/11/2007-fantasy-basketball-script-released.html"&gt;Updated&lt;/a&gt; the script to calculate team totals and also maintain roster order as it appears on management page.&lt;/p&gt;

&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Updated 2006-Nov-05:&lt;/span&gt;  I cleaned up the boxscore processing code to implement a feature my friend Simon requested: Viewing the live stats of other managers' teams.  Be sure to &lt;a href="http://freebiestats.googlecode.com/svn/trunk/basketball.user.js"&gt;update the script&lt;/a&gt; to use the new features.&lt;/p&gt;

&lt;p&gt;I didn't write a &lt;a href="http://robobruin.blogspot.com/2006/08/greasemonkey-fantasy-baseball-script.html"&gt;baseball script&lt;/a&gt; until after the all-star break and I passed on writing a &lt;a href="http://robobruin.blogspot.com/2006/09/its-boy.html"&gt;football script&lt;/a&gt; since it wouldn't save me much time.  But tonight I finished a &lt;a href="http://freebiestats.googlecode.com/svn/trunk/basketball.user.js"&gt;greasemonkey script&lt;/a&gt; that provides live scoring for yahoo's fantasy basketball leagues.&lt;/p&gt;

&lt;p&gt;To use it, download the newest version of greasemonkey and then install the &lt;a href="http://freebiestats.googlecode.com/svn/trunk/basketball.user.js"&gt;script&lt;/a&gt;.  Yahoo provides live scoring until nov 11 so you've got plenty of time to dissect the code to make sure it's safe :)  Don't worry, unless someone has hacked into my code repo (very unlikely since it's hosted by google), the script does not contain nefarious code.    That's always my biggest concern when installing scripts written by others since it's so easy to place code then sends data to other remote servers.  That said, the script is provided as is so if it drops Kobe or Lebron from your team then oops :)  I'm only kidding...I've tested it on windows xp prof running firefox 2 and the latest version of greasemonkey and have had no problems.&lt;/p&gt;

&lt;p&gt;Here's a screenshot of the script in action.  Note that the bench players have a darker background color:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/fantasybball_scoring.0.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/5037/2028/320/fantasybball_scoring.0.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The logic of the script was similar to the baseball one. First, I parsed out the boxscore links and then I made an ajax request to retrieve the contents of each boxscore.  Finally, I used xpath to find the stats for my player.  The techniques I used for xpath and ajax are explained in &lt;a href="http://robobruin.blogspot.com/2006/08/greasemonkey-fantasy-baseball-script.html"&gt;detail here&lt;/a&gt;.  Although the business logic for the script is similar, I employed a vastly different view for presentation.  Instead of embedding the stats directly into the existing table cells like in the baseball script, I placed the basketball stats inside a &lt;a href="http://en.wikipedia.org/wiki/Modal_window"&gt;modal window&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using a modal window greatly simplified my code because I didn't have to keep track of each stat and its corresponding display cell.  Instead, I could &lt;a href="http://developer.mozilla.org/en/docs/DOM:element.cloneNode"&gt;copy&lt;/a&gt; the row node from the boxscore and place it directly into my modal window without any extra processing.  I also noticed that my fantasy football team's page on sunday night no longer had placeholders for stats.  The modal will bypass this problem should yahoo implement something similar for fantasy basketball.  &lt;/p&gt;

&lt;p&gt;There are a couple of different methods to implement modals. The contents of a modal can be from an iframe or a hidden div.  My script uses the hidden div technique since the stats are added to the DOM on the fly. If you're interested in implementing something similar, a must read is this &lt;a href="http://www.sitening.com/blog/2006/03/29/create-a-modal-dialog-using-css-and-javascript/"&gt;blog posting on modal windows&lt;/a&gt;.  I used that technique along with some others that I picked up while implementing &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/lowellModal.6.jpg"&gt;modals&lt;/a&gt; at &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/stateModal.jpg"&gt;work&lt;/a&gt;.  In fact, the autocentering code is from an enhanced, iframe-based modal library called submodal that my boss &lt;a href="http://gabrito.com/files/subModal/"&gt;Todd&lt;/a&gt; has greatly enhanced.&lt;/p&gt;

&lt;p&gt;One bug that took me a while to track down was that some players made multiple ajax requests.  I added logging using greasemonkey's GM_log api and discovered it was related to my xpath expression: &lt;br/&gt;//table[@id='statTable0']/tbody/tr/td[@class='player']/div/a[@href]&lt;/p&gt;

&lt;p&gt;this expression finds all player profile links but it also found links to the 'breaking news' about the player.   I fixed the problem by adding an extra check for the a tag: a[@class='name' and @href] ... problem solved :)&lt;/p&gt;

&lt;p&gt;Enjoy the &lt;a href="http://freebiestats.googlecode.com/svn/trunk/basketball.user.js"&gt;script&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-116236548262669172?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/116236548262669172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=116236548262669172' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/116236548262669172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/116236548262669172'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/10/yahoo-fantasy-basketball-live-scoring.html' title='yahoo fantasy basketball live scoring greasemonkey script'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-116224186910601119</id><published>2006-10-30T11:41:00.000-08:00</published><updated>2007-09-26T23:02:44.464-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='netflix'/><title type='text'>python stats functions for netflix prize</title><content type='html'>&lt;p&gt;A coworker and I entered the &lt;a href="http://www.netflixprize.com/"&gt;netflix prize&lt;/a&gt; which is a competition to improve netflix's recommendation engine.  The grand prize is 1 million dollars if your algorithm can beat netflix's by 10 percent.  The task is to predict how a user will rate a movie based on previous ratings.  The past results dataset is around 2 gigs uncompressed and it works out to 100480507 ratings for 17700 movies.  I won't disclose our algorithms just yet but here's something I will share.  It's a couple of python statistical functions that I whipped up that calculate the &lt;a href="http://en.wikipedia.org/wiki/Mean"&gt;mean&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Standard_deviation"&gt;std deviation&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Kurtosis"&gt;kurtosis&lt;/a&gt;, and &lt;a href="http://en.wikipedia.org/wiki/Skewness"&gt;skewness&lt;/a&gt; of a list.  One requirement is that you import math because I use the sqrt and pow functions in that package.&lt;/p&gt;

&lt;p&gt;There's already a &lt;a href="http://www.nmr.mgh.harvard.edu/Neural_Systems_Group/gary/python.html"&gt;python stats module&lt;/a&gt; that you should use if you plan to do some heavy lifting with stats in python but if you're just looking for something a bit simpler then here are the functions.  They make use of a neat python feature called &lt;a href="http://docs.python.org/tut/node7.html#SECTION007140000000000000000"&gt;list comprehension&lt;/a&gt; that makes the code a lot easier to write and understand.  There's no perl counterpart to this built-in language feature, but the same can be accomplished with a map and an anonymous function.  One of my main motivations for working on this project is learning python.&lt;/p&gt;

&lt;pre&gt;
def mean(x):
        """Find mean of a list"""
        return sum(x)/len(x)


def stddev(x,mean):
        """Find standard deviation of a list"""
        return sqrt(sum([pow((val-mean),2) for val in x])/len(x))

def skewness(x,mean,stddev):
        """Find skewness of a list"""
        return sum([pow(val-mean,3) for val in x])/(len(x)*pow(stddev,3))


def kurtosis(x,mean,stddev):
        """find kurtosis of a list"""
        return (sum([pow(val-mean,4) for val in x]) / ((len(x)-1) * pow(stddev,4))) - 3

&lt;/pre&gt;


After I calculated these stats for the movies, I loaded the information into a database and played around with the data.


&lt;pre&gt;
The fifteen most rated movies are:
mysql&gt; select name,ratings from movie order by ratings desc limit 15;
+--------------------------------------------------------+---------+
| name                                                   | ratings |
+--------------------------------------------------------+---------+
| Miss Congeniality                                      |  232944 |
| Independence Day                                       |  216596 |
| The Patriot                                            |  200832 |
| The Day After Tomorrow                                 |  196397 |
| Pirates of the Caribbean: The Curse of the Black Pearl |  193941 |
| Pretty Woman                                           |  193295 |
| Forrest Gump                                           |  181508 |
| The Green Mile                                         |  181426 |
| Con Air                                                |  178068 |
| Twister                                                |  177556 |
| Sweet Home Alabama                                     |  176539 |
| Pearl Harbor                                           |  173596 |
| Armageddon                                             |  171991 |
| The Rock                                               |  164792 |
| What Women Want                                        |  162597 |
+--------------------------------------------------------+---------+

the movies with the highest mean are:
mysql&gt; select name,mean from movie order by mean desc limit 15;
+---------------------------------------------------------------------+---------------+
| name                                                                | mean          |
+---------------------------------------------------------------------+---------------+
| Lord of the Rings: The Return of the King: Extended Edition         | 4.72326993942 |
| The Lord of the Rings: The Fellowship of the Ring: Extended Edition | 4.71661090851 |
| Lord of the Rings: The Two Towers: Extended Edition                 | 4.70261096954 |
| Lost: Season 1                                                      | 4.67098903656 |
| Battlestar Galactica: Season 1                                      | 4.63880920410 |
| Fullmetal Alchemist                                                 | 4.60502147675 |
| Trailer Park Boys: Season 4                                         | 4.59999990463 |
| Trailer Park Boys: Season 3                                         | 4.59999990463 |
| Tenchi Muyo! Ryo Ohki                                               | 4.59550571442 |
| The Shawshank Redemption: Special Edition                           | 4.59338378906 |
| Veronica Mars: Season 1                                             | 4.59208393097 |
| Ghost in the Shell: Stand Alone Complex: 2nd Gig                    | 4.58636379242 |
| Arrested Development: Season 2                                      | 4.58238935471 |
| The Simpsons: Season 6                                              | 4.58129596710 |
| Inu-Yasha                                                           | 4.55443429947 |
+---------------------------------------------------------------------+---------------+

the movies with the lowest mean:
mysql&gt; select name,mean from movie order by mean asc limit 15;
+----------------------------------+---------------+
| name                             | mean          |
+----------------------------------+---------------+
| Avia Vampire Hunter              | 1.28787875175 |
| Zodiac Killer                    | 1.34602081776 |
| Alone in a Haunted House         | 1.37560975552 |
| Vampire Assassins                | 1.39676117897 |
| Absolution                       | 1.39999997616 |
| The Worst Horror Movie Ever Made | 1.39999997616 |
| Ax 'Em                           | 1.42222225666 |
| Dark Harvest 2: The Maize        | 1.45238089561 |
| Half-Caste                       | 1.48739492893 |
| The Horror Within                | 1.49624061584 |
| Vampires vs. Zombies             | 1.49659860134 |
| The Bogus Witch Project          | 1.49775779247 |
| Rise of the Undead               | 1.50295853615 |
| Vampiyaz                         | 1.50391650200 |
| Underground Comedy Movie         | 1.50503361225 |
+----------------------------------+---------------+

high standard deviation
mysql&gt; select name,std_dev from movie where ratings &gt; 500 order by std_dev desc limit 15;
+----------------------------------------+---------------+
| name                                   | std_dev       |
+----------------------------------------+---------------+
| 'N Sync: Live at Madison Square Garden | 1.61672019958 |
| Dragon Ball Z: Vol. 17: Super Saiyan   | 1.58626019955 |
| Dragon Ball Z: Trunks Saga             | 1.58625769615 |
| Sailor Moon R: The Promise of the Rose | 1.54338657856 |
| Princess Nine                          | 1.54320299625 |
| Big Brother 3                          | 1.52889740467 |
| Family Guy: Live in Las Vegas          | 1.51085150242 |
| Dragon Ball Z: Imperfect Cell Saga     | 1.51082730293 |
| Cher: Live in Concert                  | 1.50970792770 |
| Cardcaptor Sakura                      | 1.50106477737 |
| Tupac Shakur: Before I Wake            | 1.49814224243 |
| Slayers Try DVD Collection             | 1.48955285549 |
| Dragon Ball Z: The World's Strongest   | 1.48337769508 |
| Dragon Ball: The Saga of Goku          | 1.48244822025 |
| Dragon Ball Z: Super Android 13        | 1.47919940948 |
+----------------------------------------+---------------+

high kurtosis (=deviation due to extreme values)
mysql&gt; select name,kurtosis from movie where ratings &gt; 500 order by kurtosis desc limit 15;
+---------------------------------------------------------------------+---------------+
| name                                                                | kurtosis      |
+---------------------------------------------------------------------+---------------+
| Lord of the Rings: The Return of the King: Extended Edition         | 8.98888015747 |
| The Lord of the Rings: The Fellowship of the Ring: Extended Edition | 8.81478309631 |
| Lost: Season 1                                                      | 8.58331871033 |
| Lord of the Rings: The Two Towers: Extended Edition                 | 7.96247339249 |
| Veronica Mars: Season 1                                             | 7.01007556915 |
| Battlestar Galactica: Season 1                                      | 6.57994556427 |
| Arrested Development: Season 2                                      | 6.34450483322 |
| Fullmetal Alchemist                                                 | 6.30700731277 |
| The Simpsons: Season 6                                              | 5.94859170914 |
| Inu-Yasha                                                           | 5.37345218658 |
| The Simpsons: Season 5                                              | 5.32154130936 |
| Fruits Basket                                                       | 5.32094144821 |
| House                                                               | 5.26964759827 |
| Family Guy: Vol. 2: Season 3                                        | 5.23487997055 |
| The Simpsons: Season 4                                              | 5.13775539398 |
+---------------------------------------------------------------------+---------------+

select name,skewness from movie where ratings &gt; 500 order by skewness desc limit 15;
high skewness (long positive tail=random people who voted a bad movie good)
+--------------------------------------------------------------------------+---------------+
| name                                                                     | skewness      |
+--------------------------------------------------------------------------+---------------+
| Underground Comedy Movie                                                 | 2.18097925186 |
| Ben &amp; Arthur                                                             | 2.11108279228 |
| Visions of Sugarplums                                                    | 1.73864912987 |
| Dracula 3000                                                             | 1.56867814064 |
| Guilty by Association                                                    | 1.49578213692 |
| Survivor Exposed                                                         | 1.48025572300 |
| Leonard Part 6                                                           | 1.40650367737 |
| Homo Heights                                                             | 1.36938285828 |
| Going Overboard                                                          | 1.35962140560 |
| Shanghai Surprise                                                        | 1.27664005756 |
| Sopranos Unauthorized: Shooting Sites Uncovered                          | 1.27566981316 |
| Twentynine Palms                                                         | 1.20583796501 |
| The Life                                                                 | 1.15580248833 |
| National Lampoon's Christmas Vacation 2: Cousin Eddie's Island Adventure | 1.05684077740 |
| Glitter                                                                  | 1.04486155510 |
+--------------------------------------------------------------------------+---------------+

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-116224186910601119?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/116224186910601119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=116224186910601119' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/116224186910601119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/116224186910601119'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/10/python-stats-functions-for-netflix.html' title='python stats functions for netflix prize'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-115940332077580573</id><published>2006-09-27T17:28:00.000-07:00</published><updated>2007-09-26T23:04:46.879-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='outdoors'/><category scheme='http://www.blogger.com/atom/ns#' term='camping'/><title type='text'>weekend in big sur</title><content type='html'>&lt;p&gt;My friends and I spent the weekend at big sur.  We camped one night at &lt;a href="http://www.campingfriend.com/BigSurCampgroundandCabins/"&gt;Big Sur Campground&lt;/a&gt;.    Unlike a lot of camgrounds, this one was in the midst of towering redwoods and it was truly a spectacular experience waking up and seeing the sunlight filtering through branches and coastal fog.  The campground also had hot showers and even a playground for kids.  Simon's coworker who made the reservation said that the premium sites by the river were booked 5 years in advance so plan ahead if you want to stay at the same place :)&lt;/p&gt;

&lt;p&gt;Big Sur is along California's central coast just south of Carmel and Monterey.  Mid september is our summertime and the weather didn't disappoint.  It was high 70s, low humidity, and clear skies all around.  We drove down saturday morning, pitched our tent and then went on a couple of hikes in Julia Pfeiffer state park.&lt;/p&gt;

&lt;p&gt;the first one was Pfeiffer Falls which is around a mile roundtrip and ends at a nice 60 foot waterfall:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/img29.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5037/2028/320/img29.jpg" alt="" border="0" /&gt;&lt;/a&gt;


&lt;p&gt;The second trail we went on is Valley View which had a nice view of the valley.  That one was about a mile or so:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/img40.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/5037/2028/320/img40.jpg" border="0" alt="" /&gt;&lt;/a&gt;



&lt;p&gt;The last one we did was Buzzard's roost which is around 5 miles round trip.  It starts with a nice walk along the big sur river&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/img52.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/5037/2028/320/img52.jpg" border="0" alt="" /&gt;&lt;/a&gt;

and then climbs up to around 800 ft at the summit.  The path to the summit was quite overgrown so we had to squeeze past some chapparal.  There was actually an old shed up there and also a some rock outcroppings to sit on.  Here's the view west toward the the pacific ocean:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/img63.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/5037/2028/320/img63.jpg" border="0" alt="" /&gt;&lt;/a&gt;


&lt;p&gt;View east toward the Santa Lucia mountains:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/img58.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/5037/2028/320/img58.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-115940332077580573?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/115940332077580573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=115940332077580573' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115940332077580573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115940332077580573'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/09/weekend-in-big-sur.html' title='weekend in big sur'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-115929489911923422</id><published>2006-09-26T10:47:00.000-07:00</published><updated>2007-09-26T23:06:28.423-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='football'/><category scheme='http://www.blogger.com/atom/ns#' term='nephew'/><title type='text'>it's a boy!</title><content type='html'>&lt;p&gt;Lots have happened since my last update.  The biggest annoucement is that my sister gave birth to the cutest little baby boy, Josh Michael on September 7th.  I've been visiting the little guy quite often and he looks more adorable every time I see him.  He's my first nephew and I look forward to going to Giants and Niners games with him.  He's also displaying tremendous strength in his left arm so maybe he'll be the Sandy Koufax or Steve Carlton of his generation.  That shouldn't be too much pressure to place on the little tyke :)  Notice I'm already picking a 'safe' sport like baseball for him instead of bone crunching football.&lt;/p&gt;

&lt;p&gt;The niners are doing more crunching this year, even though they're 1-2.  I doubt they will make the playoffs but at least they are somewhat competitive which is saying something based on what I saw last year.  Getting rid of Barlow was a good move and so was getting Norv Turner.  His track record with young quarterbacks is pretty good and I'm already seeing more offensive plays that utilize Alex Smith's mobility.  Last year, Alex Smith was primarily a pocket passer and this year I'm seeing rollouts and designed run plays.  Our O-line is providing more protection too..we finally got rid of Newberry and even though I'm sad to see him go it was time.  Sad because he was the last connection to Bob Mckitttrick but glad because he couldn't possibly hold up on two shot knees with no cartilege.  My fantasy team is currently 0-3 but to be fair I gotta say that I lost 2 of them by a combine 4 points and the most recent defeat came against a Cincinnati defense that scored over 25 points.  WTF??  I hope my luck changes.  I got Portis and Cooley in my starting lineup so hopefully Washington's offensive explosion continues.&lt;/p&gt;

&lt;p&gt;I started the football fantasy greasemonkey script but just haven't found the motivation to finish it.  Unlike my baseball version which saved me lots of time checking out box scores everyday, football games don't occur everyday.  I already pour over the boxscores anyway so I'm not really saving that time finding out how my players did.  I have gotten some good feedback from the baseball one so I'll leave it to those users...anyone want to see a football one?  or should we just wait 'til basketball season starts?  I'm definitely doing a basketball one.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-115929489911923422?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/115929489911923422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=115929489911923422' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115929489911923422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115929489911923422'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/09/its-boy.html' title='it&apos;s a boy!'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-115554400375272184</id><published>2006-08-13T22:48:00.000-07:00</published><updated>2007-09-26T23:09:40.400-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='baseball'/><title type='text'>greasemonkey fantasy baseball script</title><content type='html'>&lt;p&gt;&lt;span style="font-weight: bold;"&gt;update: 4/12/2007 &lt;/span&gt;&lt;span&gt;&lt;a href="http://robobruin.blogspot.com/2007/04/2007-yahoo-fantasy-baseball-script.html"&gt;Updated&lt;/a&gt; script for 2007 season.
&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;update: 8/21/2006&lt;/span&gt; added HR and SB support and also optimized some xpath processing.&lt;/p&gt;

&lt;p&gt;I'm a big sports fan and one of my favorite hobbies is playing fantasy sports games on yahoo.  For the season's first couple of weeks, yahoo provides real time stats for all your players.  But after that, they package this feature into their 'premium services'. The only way to get live scoring is to pay for it or to click on each box score link and then scan for your player.  If the game has already ended, it's actually two clicks since the initial link takes you to the game recap.&lt;/p&gt;

&lt;p&gt;This is can be quite time consuming if you manage multiple teams but you really have no choice.  ...that is, no choice until now:  This weekend, I wrote a greasemonkey script that iterates through all the boxscores and parses out your player's stats for the night.  Once the script has finished running, you'll have live scoring!&lt;/p&gt;

&lt;p&gt;I've written it for default baseball leagues but a football one should follow shortly once I get around to drafting my football team.  here's a screenshot of how my players performed tonight:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5037/2028/1600/scoring.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5037/2028/320/scoring.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can download the script here: &lt;a href="http://freebiestats.googlecode.com/svn/trunk/baseball.user.js"&gt;http://freebiestats.googlecode.com/svn/trunk/baseball.user.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to send feature requests or bug reports here:
&lt;a href="http://code.google.com/p/freebiestats/issues/list"&gt;http://code.google.com/p/freebiestats/issues/list&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my first greasemonkey script and I'm quite impressed with the whole framework.  After the page renders, greasemonkey kicks in and can manipulate any part of the dom.  The flow of my script is as follows:
&lt;ol&gt;
&lt;li&gt;get the box score link for each player&lt;/li&gt;
&lt;li&gt;visit that link and get the player's stats&lt;/li&gt;
&lt;li&gt;update page with the stats&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;

&lt;p&gt;Firefox has a kick ass xpath implementation so finding all the box score links was pretty easy.  It helps that my xpath was pretty sharp from all the xml feed projects I've been doing at work.  The xpath for the batters is: &lt;br/&gt;//table[@id='statTable0']/tbody/tr/td[@class='player']/div/a[@href]&lt;/p&gt;

&lt;p&gt;The only time consuming part when developing this script was figuring a way to visit and process the box score pages.  I definitely wanted to create a dom for the box score page so that I could use the aforementioned kick ass xpath functionality but my first attempt using greasemonkey's GM_xmlhttpRequest function wasn't too promising.  I had no luck transforming the raw html returned by GM_xmlhttpRequest to a dom using DomParser.  This must be a common problem because a google search yielded this &lt;a href="http://greaseblog.blogspot.com/2005/12/workarounds-for-missing-xmlhttprequest.html"&gt;workaround&lt;/a&gt; in greaseblog.  That solution:&lt;/p&gt;

&lt;p&gt;var parser = new XPCNativeWrapper(window, "DOMParser").DOMParser();&lt;br/&gt;
alert(parser.parseFromString("", "text/xml"));&lt;br/&gt;

seemed a bit hackish and it would only work for xml documents.  Since the box score page is not xhtml valid or even html valid for that matter, this was not a viable option. &lt;/p&gt;

&lt;p&gt;My second attempt was to use an iframe whose src was the box score link.  This seemed to work but then I didn't have permission to access the dom directly.  I kept getting permission problems. I'm guessing that firefox disabled this feature to combat cross site scripting issues.  If you really want to use an iframe, you'll have to use this &lt;a href="http://youngpup.net/userscripts/htmlparserexample.user.js"&gt;solution&lt;/a&gt; from youngpup.&lt;/p&gt;

&lt;p&gt;My solution was to go back to using GM_xmlhttpRequest to get the raw html of the box score, saving contents within the body tag into a string, and then creating a hidden div on the current page whose innerHTML was set to that string.  The box score page was now part of the current page's dom and I was able to write xpath expressions.&lt;/p&gt;

&lt;p&gt;after that problem was solved, everything else came together rather quickly. The script is definitely an EA, 0.1 version since it's tightly coupled to how yahoo publishes box scores and fantasy manager pages and HR and SB is not one of the available stats.  Ultimately, I plan to resuse a lot of this code in other fantasy games and automatically determing the order of the stats on the management page and  the box score page will be a common problem that will need to be solved.&lt;/p&gt;

&lt;p&gt;I'm currently hosting this project using google code which has an issue tracker and uses subversion as its version control system. My javascript editor is intellij idea.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-115554400375272184?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/115554400375272184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=115554400375272184' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115554400375272184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115554400375272184'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/08/greasemonkey-fantasy-baseball-script.html' title='greasemonkey fantasy baseball script'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-115275206055028227</id><published>2006-07-12T16:16:00.000-07:00</published><updated>2007-09-26T23:11:04.418-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>ResourceBundle bungle</title><content type='html'>&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Updated 7/13:&lt;/span&gt; used &lt;a href="http://pages.google.com"&gt;google pages&lt;/a&gt; as my online wysiwyg to generate valid html for xml files&lt;/p&gt;

&lt;p&gt;We use SpringMVC and use the built-in validator support.  I had a problem parsing in a parameter for an error message.&lt;/p&gt;

my applicationcontext contained:
&lt;p&gt; &amp;lt;bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"&amp;gt;
  &amp;lt;property name="basename"&amp;gt;
      &amp;lt;value&amp;gt;app&amp;lt;/value&amp;gt;
  &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/p&gt;the line in my resource bundle,app.property, was:&lt;br/&gt;
error_key=What's up, {0}?&lt;br/&gt;

the validator call was:&lt;br/&gt;
errors.reject(errorcode, new Object[] {"doc"}, defaultMessage);&lt;br/&gt;

&lt;p&gt;My jspx file looked like this:&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;spring:hasbinderrors name="mycommand"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div class="error"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;c:foreach var="error" items="${errors.allErrors}"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;li&amp;gt;&amp;lt;spring:message arguments="${error.arguments}" code="${error.code}"&amp;gt;&amp;lt;/spring:message&amp;gt;&amp;lt;/li&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/c:foreach&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&amp;lt;/spring:hasbinderrors&amp;gt;&lt;/p&gt;

&lt;/p&gt;I expected this to show up in my final output: What's up, doc?
Instead, the parameter was never parsed in.  It only displayed: What's up, {0}?

&lt;p&gt;Like always, the answer was found in the javadocs.  The parameter binding is backed by &lt;a href="http://java.sun.com/j2se//1.4.2/docs/api/java/text/MessageFormat.html"&gt;java.text.MessageFormat&lt;/a&gt; and what happens is that a single quote, ' , stops any binding.  So to solve the problem, use two quotes '' to represent a single quote.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-115275206055028227?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/115275206055028227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=115275206055028227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115275206055028227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115275206055028227'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/07/resourcebundle-bungle.html' title='ResourceBundle bungle'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-115217105500089835</id><published>2006-07-06T00:04:00.000-07:00</published><updated>2007-09-26T23:12:12.283-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jsp'/><title type='text'>fmt:formatNumber rounding behavior</title><content type='html'>&lt;p&gt;I was helping a coworker with a rounding "bug" earlier today.  On one of our jspx pages, we need to round some numbers up.  But she ran into a strange problem because 200.5 rounded to 200 but 21.5 rounded to 22.  She thought the problem was hibernate related but a couple of quick unit tests revealed the real culprit: jstl's fmt:formatNumber tag.  It's actually not a bug at all because according to the javadocs, it relies on the following for rounding:&lt;/p&gt;
&lt;h3 style="font-style: italic;"&gt; ROUND_HALF_EVEN&lt;/h3&gt; &lt;pre style="font-style: italic;"&gt;public static final int &lt;b&gt;ROUND_HALF_EVEN&lt;/b&gt;&lt;/pre&gt; &lt;span style="font-style: italic;"&gt;Rounding mode to round towards the "nearest neighbor" unless both  neighbors are equidistant, in which case, round towards the even  neighbor.  Behaves as for ROUND_HALF_UP if the digit to the left of the  discarded fraction is odd; behaves as for ROUND_HALF_DOWN if it's even.  Note that this is the rounding mode that minimizes cumulative error  when applied repeatedly over a sequence of calculations.&lt;/span&gt;


&lt;p&gt;Unfortunately, there's no way to change the behavior to &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigDecimal.html#ROUND_HALF_UP"&gt;ROUND_HALF_UP&lt;/a&gt; which is what we wanted.  I'll send a note to the jstl mailing list to see if anyone else would like this feature and if so submit a patch.&lt;/p&gt;


&lt;p&gt;&lt;span style="font-weight: bold;"&gt;*Update
&lt;/span&gt;Before I sent that email to the mailing list, I did more digging and discovered that fmt:formatNumber is backed by DecimalFormat.  As of Java 5, DecimalFormat does not support specifying a rounding mode other than the default ROUND_HALF_EVEN.  The good news is that &lt;a href="http://download.java.net/jdk6/docs/api/java/text/DecimalFormat.html#setRoundingMode%28java.math.RoundingMode%29"&gt;setRoundingMode &lt;/a&gt;was introduced in Java 6 to solve this exact problem.  The bad news is that it'll be a while before java 6 is out of beta and this change gets propogated down to fmt:formatNumber.  So in the meantime, the best thing to do is write your own tag is you require a rounding mode other than ROUND_HALF_EVEN.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-115217105500089835?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/115217105500089835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=115217105500089835' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115217105500089835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/115217105500089835'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/07/fmtformatnumber-rounding-behavior.html' title='fmt:formatNumber rounding behavior'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-114379303444381238</id><published>2006-03-30T23:39:00.000-08:00</published><updated>2007-09-26T23:12:59.668-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ucla'/><category scheme='http://www.blogger.com/atom/ns#' term='basketball'/><title type='text'>back in business</title><content type='html'>&lt;p&gt;Ucla is going back to the final four.  Our storied basketball program is back in business and returns to its familiar place among the hoops elite.  Like enjoying a good wine, I needed to savor the memories of defense and clutch plays before penning my ode to this tournament run. &lt;/p&gt;

&lt;p&gt;When the brackets were annouced and Ucla claimed a number 2 seed I knew we would make it to the final four.  Getting past Gonzaga was a real test of my faith but these kids came through.  We unleashed a suffocating defense and Coach Howland managed the game to perfection. &lt;/p&gt;

&lt;p&gt;Thanks to streaming video from &lt;a href="http://ncaasports.com/mmod"&gt;march madness on demand&lt;/a&gt;, I replayed the clutch Hollins free throws and the ensuing steal to find some great coaching nuggets.  After the free throws, Hollins was quickly subbed out for a quicker Collison. Collison's responsibility was to cover deep which freed Mbah a Moute to cover the player inbounding the ball and allowed Bozeman to switch over to Batista.  The ball was inbounded to Morrison who made a great pass to Batista.  Batista was quickly swarmed by Farmar and Bozeman was able to knock the &lt;a href="http://www.youtube.com/watch?v=BW-vMeKuBDg"&gt;ball loose&lt;/a&gt;.  Howland was in the game the entire time..perhaps it was coincidence that the play turned out the way it did, or maybe it's just because the guy can flat out coach.&lt;/p&gt;

&lt;p&gt;It's so great to see the maturation of the players and the team's level of playthis past season.   Ryan Hollins just became a millionaire by his play in this tournament alone.  It's great to watch and I'm looking forward to this weekend's game.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-114379303444381238?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/114379303444381238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=114379303444381238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/114379303444381238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/114379303444381238'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/03/back-in-business.html' title='back in business'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-114128425430339045</id><published>2006-03-01T23:08:00.000-08:00</published><updated>2007-09-26T23:13:37.624-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Idea 5.2 and subversion installed</title><content type='html'>&lt;p&gt;I've finally gotten around to starting my XmlEditor project.  I plan to create a swing app that validates an xml file against an xsd. I also plan to allow the app to allow editing of the file to fix errors.  This project will introduce me to swing and also to the java nio classes.  I'm not sure if it's necessary to use nio but it's something I've been meaning to learn/use for a loooong time so we'll see how it goes. &lt;/p&gt;

&lt;p&gt;Before I start my project, I want to make sure I have a revision control system (as encouraged in the pragmatic programming series) on my machine so I downloaded and installed subversion.  The new version of Idea has subversion support built in so I upgraded from 4.5 to 5.1.  It was a breeze to import settings and existing projects.  I chose subversion because I already know cvs and wanted to try something new.  I've heard the branching system makes a lot more sense and is a lot faster but  I doubt I'll need branches for this small project.  It took me around 20 days to finally start this project so let's see when it's finally finished :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-114128425430339045?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/114128425430339045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=114128425430339045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/114128425430339045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/114128425430339045'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/03/idea-52-and-subversion-installed.html' title='Idea 5.2 and subversion installed'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113979882533404227</id><published>2006-02-12T18:26:00.000-08:00</published><updated>2007-09-26T23:14:12.465-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='snowboarding'/><title type='text'>snowboarding at sugarbowl</title><content type='html'>&lt;p&gt;It was first my boarding session of the season (my 3rd time ever) yesterday and I really enjoyed it.  We rented a minivan and made it to berkeley around 6 to pick up Jonathan.  We pitted at a McDonald's in davis and arrived at sugarbowl at around 9:30pm. &lt;/p&gt;

&lt;p&gt;I'm happy to say that I've vastly improved from my previous two snowboarding trips.  I can now go down a steep hill on my board rather than my butt.  My s-curves are coming around and I hope to go a couple more times this season to practice them.  I'm defeinitely still a novice but getting better every time I get some runs in.  I brought along my mp3 player and that along with a couple of cliff bars kept my energy level up until closing time at 4ish.  I fell  hard several times so today I woke up pretty sore but it was still a good trip.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113979882533404227?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113979882533404227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113979882533404227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113979882533404227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113979882533404227'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/02/snowboarding-at-sugarbowl.html' title='snowboarding at sugarbowl'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113961739392884369</id><published>2006-02-10T16:16:00.000-08:00</published><updated>2007-09-26T23:15:27.686-07:00</updated><title type='text'>planned programming projects</title><content type='html'>&lt;p&gt;I consider myself lucky to deal with interesting programming challenges at work. It definitely keeps me on my toes to know that web applications I develop will be used by millions of our customers.  Just from work programming, I've become quite adept with Perl, MySQL, and Java.&lt;/p&gt;

&lt;p&gt;But to keep pace with all the interesting technologies and advances in this industry, it's important to hack on items outside of work too.  Reading blogs definitely keeps you updated, but there's only so much you can do by reading...sometimes doing is the best teacher.&lt;/p&gt;

&lt;p&gt;I've got two projects that I plan to work on in the coming weeks.  The first is to develop a Ruby on Rails webapp that will be used to access this &lt;a href="http://www.baseball-databank.org/"&gt;vast trove of baseball statistics&lt;/a&gt;.  The second project is a Swing app that will be used to validate XML files against a user specified XSD.  I deal with large XML files all the time and I've always wanted such a tool.  I'm leaning toward the Swing project first but I might try working on both at the same time.  Stay tuned for the code...it'll either be &lt;a href="http://en.wikipedia.org/wiki/Beerware"&gt;beerware&lt;/a&gt; or will be simple like &lt;a href="http://www.freebsd.org/copyright/freebsd-license.html"&gt;freebsd's license&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113961739392884369?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113961739392884369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113961739392884369' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113961739392884369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113961739392884369'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/02/planned-programming-projects.html' title='planned programming projects'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113953193292532150</id><published>2006-02-09T16:01:00.000-08:00</published><updated>2007-09-26T23:16:07.439-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>IE printing problems and how to fix them</title><content type='html'>&lt;p&gt;I work at a pertty high traffic site and we get immediate feedback from users if a problem occurs.  A popular section of the site is our library of articles.  Like other sites, we offer a "print view" of the article that does not contain ads, headers, and footers.  Our IE uesrs, however, were having problems printing the article out on their printers.  The rightmost side of the content was being chopped off even though it looked fine on the screen.  I wasn't aware of this problem since I'm a firefox user but it made its way to my JIRA task list under blocker status so I promptly investigated the problem. &lt;/p&gt;

&lt;p&gt;A quick search on Google revealed that this was a common IE printing problem and after refining the search I discovered the &lt;a href="http://blogs.msdn.com/ie/archive/2005/06/10/428149.aspx"&gt;IE printing problem described&lt;/a&gt; by the IE programmers themselves.  The problem was partly due to HTML designers but IE also deserves some of the blame as well since printing is fine on Firefox.  I delved into our html markup and gutted a lot of unnecessary tables and invisible images used to control width that really seems prehistoric in these web 2.0 times.  I pushed the fix live quickly and maybe..just maybe... saved some paper from having to be recycled or tossed out.&lt;/p&gt;

&lt;p&gt;if you ever run into a problem printing a page out in IE, and you don't want to download &lt;a href="http://www.getfirefox.com"&gt;firefox&lt;/a&gt; (why not?), these are the links to third party solutions that the IE bloggers recommended:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.visiontech.ltd.uk/software/#IEPrint"&gt;Internet Explorer Fitted-Width   Printing&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.htmlprinting.com/product.htm"&gt;Power Team's HTML Printing&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.fineprint.com/products/fineprint/index.html"&gt;FinePrint&lt;/a&gt;   &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113953193292532150?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113953193292532150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113953193292532150' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113953193292532150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113953193292532150'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/02/ie-printing-problems-and-how-to-fix.html' title='IE printing problems and how to fix them'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113938361920382208</id><published>2006-02-07T22:23:00.000-08:00</published><updated>2007-09-26T23:17:22.005-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><title type='text'>pair programming, sponsored links, and fuzzy matching</title><content type='html'>&lt;p&gt;I got my ass kicked by the flu last week.  Last tuesday morning I felt more tired than normal rolling out of bed and it got progressively worse throughout the day.  I left work about an hour early but thanks to the prompt and speedy service of Muni, I arrived home at the same time.  I waited for about 45 minutes in the cold for a bus to come and barely managed to squeeze on.  I wish it were hyperbole but I literally was standing in the stairwell of the bus next to a cell phone yapping fool.  When I got back home I downed some Tylenol and from then til about Friday morning I was in a haze.  I promptly caught a cold after the flu and it wasn't until yesterday that I was feeling my normal self.&lt;/p&gt;

&lt;p&gt;My first project coming back was helping my coworker pull some data to give to a client and that was actually a nice one since it was relatively easy and got me back in the flow of code.  We've been trying to do more pair programming and I'm all for it since more eyes means less errors.  Retrieving multiple datasets that aren't stored consistently isn't exactly the most exciting project either so having someone to discuss different strategies and keep the focus on usually speeds things up.  I've pair programmed before and I found it to be very fast when both programmers are at similar skills levels.  The converse is that it takes twice as long when you're paired with a rookie but that's also a great way for some knowledge share provided the rookie isn't overwhelmed ala Michael Jordan and Kwame Brown.&lt;/p&gt;

&lt;p&gt;That took up most of my morning and the rest of the day I programmed solo and implemented a sponsored link section on our site for the ad team.  After I finished that, I worked on fuzzy macthing private schools that our staff had manually entered into our database against a set of data provided by the government.  Initially I was going to use mysql's built in full text queries on the name and the addresses but the queries required can get a bit tricky and I wasn't ready to implement them in hibernate's query language.&lt;/p&gt;

&lt;p&gt;Instead my algorithm was to go through each school in the government's file and then grab all schools in our database that's located in the same city.  I computed the Levenhstein distances on the school name and also the street address and that gave me some really good matches for distances of 10-20.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113938361920382208?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113938361920382208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113938361920382208' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113938361920382208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113938361920382208'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/02/pair-programming-sponsored-links-and.html' title='pair programming, sponsored links, and fuzzy matching'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113765735366200926</id><published>2006-01-18T22:51:00.000-08:00</published><updated>2007-09-26T23:18:05.475-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ucla'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>espn's redesign + my first homepage</title><content type='html'>&lt;p&gt;Espn's front page has gone through another design iteration.   &lt;a href="http://web.archive.org/web/*/http://espn.go.com"&gt;This is how it used to look.&lt;/a&gt;   It was only a matter of time since they've been testing a similar look on their sport specific homepages.  I like it a lot..&lt;a href="http://espn.go.com"&gt;check it out when you get a chance&lt;/a&gt;...the days of a left navigation bar  are slowly fading away.  Since it's been eliminated, more space is available for content.  The readability of the top story and headlines, the main content I go to the site for, are much easier to read because of the extra space and size.  On the tech side, I know they were early adopters of css and xhtml so I'm guessing that this design change wasn't as difficult as the first time they went xhtml and css.&lt;/p&gt;

&lt;p&gt;My approach to css is quite pragmatic.  I use it whenever possible but If I have to employ too many hacks to get it to look right in a certain browser, I will ditch it for a universal solution like using tables for layout.  In fact, when I coded up the test score and census display &lt;a href="http://www.greatschools.net"&gt;for work&lt;/a&gt;, I went with tables because I needed total confidence that the achievement pages would render correctly for older browsers and drawing complex ,vertical bar charts whose display is CSS based is impossible without hacks.&lt;/p&gt;

&lt;p&gt;on a separate note, I found &lt;a href="http://web.archive.org/web/20010515204929/www.bol.ucla.edu/%7Edwlee/"&gt;my old college webpage&lt;/a&gt; while looking at the early espn pages.  be sure to check out the random quote that appears on the bottom of the page.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113765735366200926?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113765735366200926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113765735366200926' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113765735366200926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113765735366200926'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/01/espns-redesign-my-first-homepage.html' title='espn&apos;s redesign + my first homepage'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113762802971903864</id><published>2006-01-18T12:36:00.000-08:00</published><updated>2007-09-26T23:19:04.581-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ucla'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Politcal spin in today's classrooms more common than the freshman 15?</title><content type='html'>&lt;p&gt;I came across the most absurb topic today while perusing sfgate.com:  &lt;a href="http://www.sfgate.com/cgi-bin/article.cgi?f=/n/a/2006/01/18/state/n025132S91.DTL"&gt;"Radical" UCLA professors targeted by alumni group"&lt;/a&gt; The gist of the article is that some alumni group is encouraging current students to document politically biased salvos during lecture time in the form of a monetary finder's fee.  I'm not really against students who want to make an extra buck in this manner since I too was once a poor, ramen eating UCLA bruin, hence robo&lt;span style="font-style: italic;"&gt;bruin&lt;/span&gt;, I'm more against corporations/individuals who deem it necessary to patrol a professor's political views.&lt;/p&gt;

&lt;p&gt;This is college.   Students are exposed to much greater ills than a professor spending a bit too much time on Bush and the war in Iraq.  Heck, Jon Stewart probably has a greater influence and a more captivating presence on a college student's political views than his professor.  We aren't talking about a bunch of impressionable kids like in Dead Poet's Society.  Let's give UCLA students some credit here...these are some of the smartest young adults in the country and they definitely can differentiate textbook analysis and political slant during a lecture.&lt;/p&gt;

&lt;p&gt;Let's say the argument is not whether a professor is inculcating a student with his political views but rather that he's just wasting time talking about an irrelevant subject.  I checked out some of the targeted professors and they mostly teach political/social science/law classes.  Are you telling me that current political affairs are off topic?  Isn't there great debate about the legality of guantanamo bay or wiretapping US citizens by way of the Patriot Act?  If the professor is just there to repeat what's in a textbook why go to class at all?  His job is to expand and add to the textbook and that may involve some of his political views.  I'm ok with that...I've never been brainwashed by a professor..they're some of the smartest guys/gals in the world but definitely not omniscient.&lt;/p&gt;

&lt;p&gt;I'm just disappointed no Boelter hall professors were mentioned.  I wouldn't have minded hearing some political spin during my time as an undergrad in the engineering building.  That might have made those required fluid dynamic classes a bit more palpable.  And it may have been fun to see the words 'Bush' and 'Liberal'  used to demonstrate the Levenshtein distance formula.  A computer science prof could even have slipped John Kerry in a state diagram that led to a flip flopping of results.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113762802971903864?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113762802971903864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113762802971903864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113762802971903864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113762802971903864'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/01/politcal-spin-in-todays-classrooms.html' title='Politcal spin in today&apos;s classrooms more common than the freshman 15?'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113748879030520726</id><published>2006-01-17T00:41:00.000-08:00</published><updated>2007-09-26T23:20:08.324-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tv'/><title type='text'>24</title><content type='html'>&lt;p&gt;with shows like "lost" and "24", I almost can understand why people don't subscribe to cable.   cable is a big waste of money and if not for the fact that I need my sports fix I would probably cancel my subscription. I got the bill the other day and it's close to 50 bucks now. but as I type out this entry I'm really enjoying epsn's "game of the millenium" &lt;a href="http://en.wikipedia.org/wiki/Mashup_%28web_application_hybrid%29"&gt;mashup&lt;/a&gt; of the 70s steelers against the 80s niners so what can I do.&lt;/p&gt;

&lt;p&gt;What's a mashup? It's when you combine different tools/data in order to come up with something cool. Think about overlaying craigslist housing data with google maps. That's a mashup. So the fantasy matchup between the two powerhouse football teams of the 70s and 80s is like a football mashup. We can call this tv 2.0 and tag it with the keywords "1980 forty niners" "1970 steelers" "fantasy matchup" "game of the millenium"&lt;/p&gt;

&lt;p&gt;before I digress any further the impetus for this entry is to say that 24 rocks. Jack bauer is bad ass as usual and for the past two nights I've been glued to the set. What a way to hook new users..give them two back to back episodes on consecutive nights. One has to disregard reality to fully appreciate the show but once that leap of faith happens it's edge of the seat excitement.&lt;/p&gt;

&lt;p&gt;The eye candy this season has got to be the first lady's assistant played by actress Sandrine Holt. I had to dig into the 24 site forum to find her but I guess that's not as complicated as Chloe running a "double regression binary filter" on some image that has been magnified 50 times in order to pinpoint a former eastern block army sergeant. but let's get this straight, she's just a bonus (and she could be a villain later on which would suck cuz I can't root for villains..pretty sure that'snot her character though)..I'm a fan of the show for the storyline first and Sandrine second.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113748879030520726?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113748879030520726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113748879030520726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113748879030520726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113748879030520726'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/01/24.html' title='24'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113633936654496624</id><published>2006-01-03T16:55:00.000-08:00</published><updated>2007-09-26T23:20:48.669-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='poker'/><category scheme='http://www.blogger.com/atom/ns#' term='vegas'/><title type='text'>back in san francisco</title><content type='html'>&lt;p&gt;we left vegas at 2pm and arrived in San Francisco at 3am.  After dropping everyone off and returning home it was past 5 before I rolled into bed.  Fortunately, I scheduled the entire week off so I was able to sleep in this morning.  the most memorable moment of the trip was watching the countdown and the entire street erupt into celebration when the new year arrived.  the streets were closed and we we on tropicana and las vegas blvd simultaneously checking out the fireworks coming from mgm and the roof of excalibur.  the crowd wasn't too wild but there was the usual mix of drunks balanced by the ones of families with strollers.  I'm surprised when I see both sets of people...especially the families with strollers crusing the strip so late at night.   &lt;/p&gt;

&lt;p&gt;gambling wise I probably spent an hour at the blackjack tables the entire 5 days.  I also entered my first poker tournament and placed in the money.  I finished 5/40 in a no limit game and my friend finished 2nd.  The hand I busted out on was pokect 8's.  I was up against 9-2 and the guy flopped a set and then had a quad on the turn.  but that's poker...:)  I was low stacked and my all in was just his big blind.&lt;/p&gt;

&lt;p&gt;it was a pretty good trip overall and a nice way to start the new year with good friends.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113633936654496624?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113633936654496624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113633936654496624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113633936654496624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113633936654496624'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2006/01/back-in-san-francisco.html' title='back in san francisco'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113583705774171881</id><published>2005-12-28T21:55:00.000-08:00</published><updated>2007-09-26T23:21:14.893-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vegas'/><title type='text'>vegas baby</title><content type='html'>&lt;p&gt;I just returned from the airport where I dropped some friends off to pick up the minivans. We're leaving around midnight so we should be there to enjoy a nice brunch. I'm planning on catching a show there...Kanye West is going to be singing and Celine's definitely an option if I'm willing to pay a scalper since the tickets are sold out. If all else fails I'll probably check out Lance Burton's magic show.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113583705774171881?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113583705774171881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113583705774171881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113583705774171881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113583705774171881'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2005/12/vegas-baby.html' title='vegas baby'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20282472.post-113581333864354862</id><published>2005-12-28T15:06:00.000-08:00</published><updated>2007-09-26T23:22:31.799-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>Spring MVC RedirectView appends jsessionid</title><content type='html'>&lt;p&gt;Back when I worked at Sun we used to have a shutdown period the last two weeks of the year.  I'm not sure if they still have that policy but I wonder why all companies don't operate like that.  This time of year most people are either on vacation or are in vacation mode while at work.  In fact, most large projects are not considered or launched until the new year anyway. &lt;/p&gt;

&lt;p&gt;I work at a pretty small shop and it's like that for us too.  I had a day free before going on vacation so I volunteered to fix a couple of minor bugs.  One of them dealt with removing a ;jsessionid=????? that was being appended to one of our links.  If you're not familiar with what that is, it's basically tomcat's way of tracking sessions when a user does not have cookies enabled.  Instead of storing it in a cookie, that string is passed around in the URL.  But in order to see the jessionid string in the first place, it needs to be enabled somewhere in your code.&lt;/p&gt;

&lt;p&gt;One method is using c:url tags in your jsp pages.  Another is by using HttpServletResponse's encodeURL or encodeRedirectURL methods in your controller code.  Usually it's a good idea to include these calls but in our webapp we do not store session data and that string was just adding extra noise since the page where it appeared is used as a launchpad to forward to a perl page.&lt;/p&gt;

&lt;p&gt;My first intuition was to look for the c:out tag but no luck there so I searched for the encodeURL methods.  Ack..no luck there either.  Where could this be coming from?  I then saw a call to spring mvc's RedirctView class so I figured it might be in there.  The docs made no mention of jsessionid's so I looked at the source code.  A ha...RedirectView actually calls encodeURL before the redirect so that was the culprit.  Another one of the many benefits of open source...full source code view.&lt;/p&gt;

&lt;p&gt;I described the problem to Andy and he showed me how to easily view a library's source code in IDEA.  If you go to your preferences and then look at the libraries in your project, you can add an entry point to the src code on your local machine.  The same goes for api's too.  The best thing about it is that you can keep it in the zip file and IDEA will still find it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20282472-113581333864354862?l=robobruin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robobruin.blogspot.com/feeds/113581333864354862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20282472&amp;postID=113581333864354862' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113581333864354862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20282472/posts/default/113581333864354862'/><link rel='alternate' type='text/html' href='http://robobruin.blogspot.com/2005/12/spring-mvc-redirectview-appends.html' title='Spring MVC RedirectView appends jsessionid'/><author><name>Dave</name><uri>http://www.blogger.com/profile/12599422987118317308</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
