Saturday, June 9, 2012
Rooting your Droid Incredible
Wednesday, December 29, 2010
Debugging MapReduce in MongoDB
- Load up one of your documents that you would like to map in the browser. Since the documents are JSON, this is easy. In our project, we have JSON fixture files and a small web app that allows you to choose which fixture to use for testing.
- Mock the emit() method. You can just have it write to a Hash that you can inspect later.
- Load up the Map and Reduce functions. If you keep these in separate .js files, you can pull them in with a simple script tag.
- Bind the map function to the document so that it has the correct context. In a MongoDB mapper function "this" is set to the document that you are mapping. You can easily do this with the bind() function in Underscore.js. I'm sure that other JavaScript frameworks provide a similar function.
- Put a link on the page that will let you run the bound function.
Tuesday, December 14, 2010
Using Underscore.js with MongoDB
Wednesday, September 15, 2010
Git rm may cause insanity
$ cd /tmp
$ mkdir foo
$ cd foo/
$ git init
Initialized empty Git repository in /private/tmp/foo/.git/
$ mkdir bar
$ cd bar/
$ echo 'hello' > splat.txt
$ git add splat.txt
$ git ci -m 'adding a text file'
[master (root-commit) 069f11b] adding a text file
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 bar/splat.txt
$ git rm splat.txt
rm 'bar/splat.txt'
$ cp ~/.gitignore .
cp: ./.gitignore: No such file or directory
Monday, May 17, 2010
Gwibber on Ubuntu 10.04 issues with FiOS
$> gwibber-service -o -d
This is what I got:
Gwibber wasn't refreshing because it was timing out on the DNS lookup. I have Verizon FiOS as an ISP. FiOS having terrible DNS seems to be a problem. I switched over to Google DNS and every thing is snappy and working properly. If you're using Gwibber on FiOS and having issues, try this out. It may save you an hour or three.
Thursday, April 1, 2010
Using xargs with git
The two commands I have found handy for dealing with this situation are git ls-files and xargs.
If you run the command:
git ls-files -oIt will show you all of the untracked files in your working directory, one file per line. A problem that you will run into here is that it also shows files in your .gitignore. To get around this issue, you just need another argument to specify your .gitignore:
git ls-files -o --exclude-per-directory=.gitignoreNow that you have all of the files you want to add, you just need to run git add on all of them. This is where xargs comes in handy. It will read from standard in, break it up on line endings and then feed each line as an argument into another command. Putting it all together, you get:
git ls-files -o --exclude-per-directory=.gitignore | xargs git addThat last command will add any untracked files to your git repository. The beautiful thing here is that we can also leverage some UNIX-y goodness if we want to as well. Let's say we're working on a project and we only want to commit some XSLT we have been working on. You can do this by throwing grep into the command chain:
git ls-files -o --exclude-per-directory=.gitignore | grep xslt | xargs git addThis will only add files that contain "xslt" in their names. This same approach comes in handy when you remove files from your working copy but forget to run git rm.
Monday, November 23, 2009
Classy hData
3.1.2 POST
3.1.2.1 Parameters: type, typeId, requirement
For this operation, the value of type MUST equal "extension". The typeId MUST be a URI string that represents a type of section document. The requirement parameter MUST be either "optional" or "mandatory". If any parameters are incorrect or not existent, the server MUST return a status code of 400.
If the system supports the extension identified by the typeId URI string, this operation will modify the extensions node in the root document and add this extension with the requirement level identified by the requirement parameter. The server MUST return a 201 status code.
If the system does not support the extension, it MUST not accept the extension if the requirement parameter is "mandatory" and return a status code of 409. If the requirement is "optional" the server MAY accept the operation, update the root document and send a status code of 201.
Status Code: 201, 400, 409
and turn it into the a Shoulda context block. In the spec above, we're talking about what should happen when you POST to the root of an hData Record. The functionality being described here is how an extension can be added to the record, or how you can register a different type of thing for a record. For example, you could use this feature to add an medications extension to a record, if one did not exist there already. In our test code, we're going to try to register an allergies extension:
Saturday, October 17, 2009
Teaching at the Ruby on Rails Workshop for Women
I was a bit intimidated in teaching the class at first. I was upgraded from TA status to teacher mid-week and was a bit worried that I wouldn't know what to say. Maybe I was right to be worried. Also, many of the TA's were rockstar rubyists and I have to admit that I felt a little silly speaking authoritatively in front of them.
Once I started getting into the material I started to feel pretty comfortable. Watching people have a-ha moments is really rewarding. Trying to explain programming with out falling back on computer science terms is kinda tricky on the fly. Maybe if I do something like this again, I can speak on things a little more smoothly.
It's pretty incredible how much the students were able to pick up in a day. I know that we had some people in the class that had never written code in their life and it was really cool to see them hacking in just a few hours.
If I were to do it over again, I would suggest just a plain ruby class for beginners. Or maybe a two day class where Rails is covered in the second day. When I thought that the students were getting comfortable with Ruby, we only had one session left. I think that everyone was with me when we were modifying the default index page in Rails, but I wanted to make sure that the students saw the ruby bits too. So I rushed through controllers and views in 15 minutes and I would be surprised if anyone got anything out of it. It probably would have been best to punt on the controllers and just explain a little about HTML and CSS.
I noticed that for a lot of beginners, application switching was killer. Switching between the terminal, browser and text editor is second nature for me, but not so much for those just getting started. I wish I had a ton of screen real estate to keep all three visible at once, but I don't know if that would actually help.
We didn't get to really cover git or Heroku in the class. I was able to tell the students enough to use them, but not understand them. The localhost vs. Heroku server was definitely a stumbling block for some. For beginners, I might punt on Heroku and just work from localhost without any source control just to get started.
I got a ton of positive feedback on Twitter and in person. This was super encouraging. I've always been considering teaching at some level later in my career, so it seems like I am on the right track there.
Overall, it was an awesome experience. One thing I was surprised to hear is how intimidating it is for women to participate in local open source meet ups. I suppose that being a 6' 2" person who has played contact sports leaves me in a position where I am generally not to scared of software developers. But getting up in front of the class today with all of the TA's looking at me, I think I'm starting to get it. Hopefully, events like these can start to even out the gender balance so that more women feel comfortable participating in the Ruby and FOSS community.
Tuesday, August 18, 2009
Building Tokyo Cabinet for use with Java on OS X
To translate, what is going on here is that by default Tokyo Cabinet will build a 32 bit binaries. Java 1.6 on OS X is 64 bit and will look for a 64 bit version of the library. Here is what I did to make things happy.
When running the configure script for Tokyo Cabinet itself, I added a flag:
I tried the same trick when configuring the Java bindings, but it didn't seem to end up in the resulting Makefile. So I edited the Makefile by hand. In the end, my CFLAGS line looks like this:
After that, I was able to get a small Scala script to create a Hash database.
As an aside, the Scala IDE for Eclipse seems really nice. I had tried it out a few months ago, and it has clearly made a lot of progress since then.
Saturday, November 22, 2008
Glassfish is looking speedy
I work on Project Laika, and for our deployments we are looking to switch to JRuby. We already have java code hanging around, and it looks like we will need some more soon (I'm thinking it will be easier to deal with SOAP web services in java and calling the classes from JRuby). I wanted to run some numbers to make sure that our performance wouldn't fall through the floor.
The Setup
I decided to pit Mongrel 1.1.5 running on MRI 1.8.6 against Glassfish v3 Prelude 1 and JRuby 1.1.5 on Java 5. I'm running Rails 2.0.2 in both setups (I know we are behind the times). I ran them both on OS X 10.5.5 and had the Rails apps hit the same MySQL database.
I used ab to grab the numbers. I had it hit the site 1000 times with 10 concurrent requests. I hacked the Laika app slightly so that you didn't have to log in.
The Test
I wanted to get a feel for how the app would perform, so I did two simple tests: dynamic content from a typical page and static content. The dynamic content was the patient template library in Laika which contains code that you'd expect in a Rails app: AR pulling info from the DB and putting it into ERB templates. I also pulled down the Rails 404 page to get a feel for serving static content. This is probably less meaningful, as you'll probably have Apache or Nginx serve up your static stuff.
The Results
Glassfish, hands down. The results are the average number of milliseconds it took to serve each request.

It beat Mongrel in both static and dynamic content easily. Glassfish v3 also makes it ridiculously easy to deploy Rails apps. You can use the Glassfish gem, and serve up your app with a single command. I installed the Glassfish server, so I could run JEE apps alongside my Rails stuff, there is a single command where you point the app server to the root directory of your app and you're done.
With Rails 2.2 now out and offering thread safety, and JRuby being the only interperter that can take advantage of it... Glassfish and JRuby are really worth checking out.
Friday, September 5, 2008
SezHoo and WikiSym 2008
The way that SezHoo works is that it goes through a wiki article's history and tracks the authorship of each word in the article. We use a pretty popular technique in text analysis called shingling to help us out.
For each revision of an article, we break it up into shingles. We're using shingles that are 6 words long, so each word will have 6 shingles associated with it. We credit authorship of the word to the author of the earliest shingle.
This allows us to add some information to a MediaWiki installation:
Pages
We show the authors of a page, and the percentages at which they have contributed. We also offer this information at the section level.
The information we compute is better than doing diffs with a standard MediaWiki install. Diffs are line ending based, so changing a word in a paragraph that has a single line ending can make it difficult to determine who wrote the paragraph. In addition, since we are looking for authorship of a word across all revisions at once (as opposed to a revision vs. revision comparison with a diff), this technique is immune to copying and pasting of text and reversion of vandalism.
Authors
We create a reputation for authors with 3 dimensions: quantity, quality and value. For all metrics, we assign a 5 star rating. The way this is done is by computing a raw score for all authors and then ranking them. Authors in the top 20% have a 5-star rating in that dimension.
For quantity, we simply calculate the number of word contributed by each author. This includes words that may no longer be in the current revision of the article. Value takes the percentage authorship of a page, and multiplies that by the number of page views (it's valuable if it's being read).
Quality is a lot more tricky. We assume that wiki articles are a Darwinian environment. That is, quality text will "survive" in that as the article is edited, other authors will leave the text alone. Poor quality text will be "killed" or deleted by other authors. We determine quality by looking at the percentage of text that is expected to be alive for an author after 8 revisions (you can change 8 to whatever you like, but it works well for our internal wiki). To calculate the percentage alive after 8 revisions, we used a Kaplan-Meier estimate. This was necessary due to the fact that authors will have phrases which are "alive" (they are in the current version of an article). So if a word has survived 3 edits and is in the current version of an article, when calculating survival probabilities you don't want to say that it "died" at 3 revisions, but you don't want to lose the data either. Kaplan-Meier handles that for us.
In the end, you get a 5-star rating for each author in the dimensions of quantity, quality and value.
I'll be presenting this work at WikiSym 2008. We're doing some other interesting stuff which we haven't rolled into SezHoo yet, so it's worth coming to my talk even if you've read this blog post.
Wednesday, August 13, 2008
Using Hadoop
There are plenty of tutorials on Hadoop around the web, so I won't do any of the basic intro stuff. I wanted to write about some of the stuff I didn't find all that easily.
Most of the Hadoop documentation talks about dealing with input where your records are on a single line (like an Apache access log). From using the Google/documentation/experience, we have found that Hadoop works just fine with multi-line records. We're using Hadoop to process XML, specifically a dump from Wikipedia. The dump is a single 33 GB file, where there is a root tag, and then several million child tags (representing Wikipedia pages). Using this code I found on the Hadoop core user mailing list, we can have it so that the mapper gets the XML for one child node (or one Wikipedia page). This is nice, because the XML for a single page is relatively small. We then use JDOM to deal with the contents of the individual pages.
We are using HDFS to store our input and output. By default, it will chop files into 64MB chunks, which get shipped to the mappers so that the file can be processed in parallel. One thing that I was concerned about was how records would be handled that spanned the splits. So far, we haven't seen any issues, and this answer in the Hadoop FAQ seems to indicate that the records spanning the split will be handled. It may be possible that those records get dropped, it would be hard for us to tell at this point... but the good news for us is that it won't affect the data we're trying to collect much.
As for our setup and usage. We have 5 machines in our cluster, most of which are run of the mill dual core Intel machines running Linux. The jobs we're running on the 33GB XML file are taking around 45 minutes, which seems pretty fast to me.
Monday, July 28, 2008
OSCON 2008: Wrap Up
Hadoop was big on Thursday. Derek Gottfrid of the New York Times talked about how they used Hadoop and Amazon EC2 to process tons of data. Derek's presentation style is great, which mate the talk entertaining. Some folks from Yahoo were also getting into the nitty gritty details of how the whole thing works too.
The MySQL Proxy talk was good. It seems like a pretty handy tool for performance tuning and all sorts of SQL trickery.
The last talk that stood out to me was Selectricity. The project is a both a site to run elections as well as the software you can use to run elections where ever you want. One point that Benjamin Mako Hill made that I thought was interesting is that most election research goes into government elections... and these are the least likely to change. By building a tool to allow folks to conduct elections for simple things (what movie to see, who will lead the coffee club, etc.) using methods different from plurality, it's a good way to sneak in alternative voting methods to the masses. That way if people get familar with Condercet when voting for the next American Idol, they may be more likely to push for election reform in government elections.
I'm not sure if I'll hit OSCON again next year. I like going because it's nice to get an overview of a lot of different techologies, as opposed to something like Rails Conf. But things did feel pretty shallow this year.
Thursday, July 24, 2008
OSCON 2008: Day 3
The speaking experience was pretty cool. I was in a fairly small room, and probably had about 20 to 30 people in the audience, which was pretty non-threatening. I would have been more nervous in one of the more cavernous rooms with 200 people.
As for the rest of the conference today...
XMPP has a lot of buzz for communicating in the cloud. There were a few talks on that today.
There is a lot of Ruby stuff going on outside of web apps. RAD seems to have a lot of buzz for using Ruby to work with Arduino. Ruby's also behind Adhearsion, a tool for building IVR's.
I missed the talk on CouchDB, but some of the folks I'm out here with said it was great.
On a conference logistics note... I was kinda bummed that some of the talks had filled, so I couldn't get in. I wound up missing the talk on Hypertable as well as one on XMPP in the cloud.
Wednesday, July 23, 2008
OSCON 2008: Day 2
Practical Erlang Programming was great. Francesco Cesarini is a great speaker and delivered a great tutorial. While Erlang does make you look at things differently, I can see how it makes it a lot easier to write concurrent code.
While I was physched to see Mark Shuttleworth give a keynote (given my fondness for Ubuntu), the best keynotes tonight were definitley Robert (r0ml) Lefkowitz and Damian Conway.
R0ml's talk compared various software development methodologies to Quintilian's 1st century works on rhetoric. My take on his talk was that open software has a good development methodology since it doesn't really have a requirements phase. Code gets released early an often. Bugs are filed and patches are submitted. Then users and developers can look at bugs and patches are there to determine what is in the next release. This is different form a typical development methodology, where you need to decide what you want up front. In this model, people do what they want, and you take what you like in the end.
On the other hand Damian Conway is somewhere between insane and brilliant. His talks are hillarious, but the stuff that he is actually able to implement is crazy... I'm sure that we'll be seeing some talk of positronic variables on the tubes in the comming days.
Tuesday, July 22, 2008
OSCON 2008: Day 1
The first session I went to was Python in 3 Hours. While I do most of my work in Ruby, I do try to keep an eye on Python. It seems like a pretty clean scripting language, and quite speedy when compared to Ruby.
The tutorial was good. The material is kinda dry (it's language syntax after all, which is pretty hard to spice up). Steve Holden's presentation was clear and well thought out. I walked away feeling like I could approach Python code now without too much fear. However, I still have some pretty mixed feelings about Python... There are a lot of little things that bother me... having to add a self parameter to instance methods, double under bar naming conventions and the whole significant white space thing. At any rate, I though the tutorial was informative.
The second tutorial I did was Making Things Blink: An Introduction to Arduino. This was a lot of fun. I haven't played with a microcontroller since college... but I've always loved working at the place where software meets hardware.
In the session, we worked through coding for Arduino as well as some basic circuits. The class culminated by building an Etch-a-Sketch. This is accomplished by hooking up two potentiometers to the Arduino, which reads the values and passes them to your computer via USB. We then used Processing to read and visualize the data on the screen. This meant that you could turns the knobs on the pots and draw on the screen pretty cool stuff.
Overall, one of the vibes I'm getting from the conference this year is big data. How do deal with really big databases and how to process tons of data in parallel. We'll see if this continues throughout the conference.
Thursday, June 5, 2008
Speaking at OSCON
Wednesday, May 21, 2008
DBSlayer is taking JSON to the next level
Friday, December 7, 2007
Spring MVC, Data Binding and JPA
public class Person
{
private String name;
private List<Address> addresses;
}
As Matt mentions, using LazyList found in the Apache Commons Collections is one way to get Spring to bind dynamic collections into your beans (in the example, use a lazy list for the addresses). However, you can run into some issues if your persisting your beans using JPA.
We're using OpenJPA, and when we try to persist an object that has a LazyList in one of its properties, it chokes. The problem is that it can't proxy LazyList because it doesn't have a default constructor. To get around this, we're applying a pretty simple hack. Before Spring does the data binding, we decorate the collection with a LazyList. Before we persist the object with JPA, we copy the collection back to a plain old ArrayList.
An example of doing this can be seen with Spring MVC's SimpleFormController in DocumentLocationCreationController. To help out with the whole process, we've created a LazyListHelper to make the decorating and copying easier.
If you're using Spring MVC with JPA, hopefully this will save you some headaches.
Thursday, October 4, 2007
JRuby Compiler Performance
I was pretty excited when I heard that JRuby's compiler was complete. I figured I could run some benchmarks against the C-Based Ruby Implementation to see how it was performing. I've only run this suite once, but I hope to provide enough info so that you could replicate the results yourself. Please let me know if you think I missed something.
The Setup
The benchmarks were run on a Dell D820 laptop. It has an Intel Core Duo running at 2.17GHz and has 1GB of RAM. I'm running Ubuntu 7.04 for an OS. The only wrinkle in my setup is that my root partition is encrypted using LUKS/dmcrypt. This will probably slow down the IO benchmarks, but I'm assuming it would penalize both Ruby implementations equally.
For the C-Based Ruby Implementation, I'm using the Ubuntu packaged Ruby version 1.8.5. For JRuby, I checked out the latest from Codehaus's SVN (Rev 4474) and built the code using Sun's Java version 1.6.0.
For the benchmarks, I pulled the suite from the Ruby Lang SVN (Rev 13608).
I ran the benchmarks using the run.rb script. The C-Based Ruby Implementation was run with no command line options. I modified the script to run JRuby withe the following options:
- -C to compile the ruby code before running it
- -O to disable ObjectSpace
- -J-Djruby.thread.pooling=true to enable thread pooling
- -J-server to put the JVM in server mode
These options are explained in the Performance Tuning and Compiler pages of the JRuby Wiki.
The following shows the time it took the Ruby Implementation to perform the benchmark in seconds:
Here is the difference between the two implementations (CRuby - JRuby) again, in seconds:
As you can see, JRuby is performing really well on a lot of these benchmarks. It gets killed on eval, but I suppose that is to be expected. My guess is that JRuby is taking advantage of Java primitives to outperform CRuby at number crunching. Charles Nutter's comments at another blog entry on JRuby benchmarking seem to indicate that this would be the case. Can't wait until JRuby is 1.1