« August 2006 | Main | October 2006 »

September 27, 2006

OpenGL at the Big Nerd Ranch

Having been greatly impressed with my first experience, I threatened to sign up for the OpenGL class at the Big Nerd Ranch in my review of their fabulous Cocoa Bootcamp. Well, as most of you already know, I did. I went. I was blown away. Again. Just like last time, the service was great, the accommodations beautiful, etc. You can read my earlier review (and those of many others) to understand the extent to which the Big Nerd Ranch represents the total nerd camp experience. What I hope to share with you today is information that you can really only obtain from a handful of people: those of us who have attended the first Big Nerd Ranch OpenGL boot camp having previously attended other Big Nerd Ranch classes.

It’s enormously difficult for an institution to handle subjects broad and deep equally well. A university may offer a broad undergraduate physics degree with genuinely interested professors teaching survey courses but is unlikely to have much to offer in the way of (say) the physics of the superfluidity of supercooled liquid helium. Big Nerd Ranch handles a very specialized subject like OpenGL equally as well as they handle the broader path to Cocoa programming. The BNR formula works in a variety of situations. Listening to short lectures on a given subtopic then typing like mad barely understanding the load of C code your reproducing actually causes a lot to sink in. I’m surprised. Now I read through the OpenGL “Red Book,” which seemed like so much Greek to me when I first opened it, and I understand it perhaps as well as I do Heinlein.

Rocco Bowling, our esteemed instructor, noted nervously that I didn’t blog about my OpenGL boot camp experience during the camp in stark contrast to my almost daily blogging habit during the Cocoa boot camp. I have a few reasons for this and I hope that Rocco can forgive me for being so quiet prior to today. First, I wanted to get more sleep than I did at the Cocoa camp. Having zero experience in OpenGL, the subject was over my head and I was working hard every day to stay afloat. Second, I wanted to withhold public statement with regard to this untested class until I had experienced the whole and had a chance for this foreign material to sink in a bit. Third, I was in largest part interested to see if I could use the class material to actually do something. I suspect that some of you find yourselves in the process of deciding whether to spend a sizable amount of money to send yourself and perhaps an employee or two for some very specialized training. If I were in that position, I would be wondering whether I could expect immediate results.

How about this for ROI?

ROI.jpg

With the Cocoa and OpenGL boot camps under my belt, I was able to reverse-engineer, design and code in probably 90 (+-) hours:
an XML parser and data model (as an embeddable framework) for the Nike+ (an awesome product, by the way).
a number of little test applications.
a (it’s getting pretty, huh?) data visualization in OpenGL.

I’m happy to report that I can produce results that I know would have taken me weeks or months of steady frustration to achieve with my prior Mac programming skills. I went from Python to Assembly in five weeks. How about that?

So! Thanks again to the fine folks at BNR. Perhaps you’re lucky enough to work for the large tech company where Rocco will be teaching this class soon and hopefully BNR will put the class on the calendar again soon. I know you’ll want to go.

September 25, 2006

Jury duty. It Ain't the DMV...

. ...and neither is the DMV, for that matter.

When I moved to New York, I vaguely expected some of the horror stories to be true. Yes, some of them are. There really is a rather rank-smelling old fellow who badgers passers by for change outside of the deli. One often notes rats chasing garbage in the subway tunnels. And, yes, some parts of New York smell. Bad.

So far, however, my experiences with municipal government have been pleasant. Today I await the call to join a jury. I'm planted on a comfortable pleather chair, sipping a diet Pepsi (a can I bought for a dollah... ahem), and enjoying free wi-fi access. There is a computer lab in an adjoining room sporting 16 little Dell desktops with Internet access and there are public telephones, vending machines, and a clean bathroom. Sure, I can't visit any clients today and it's possible that I will be watching a trial or some other matter for an indefinite period of time. Right now, though, I'm just hanging out with my Mac people watching. Not bad for government work...and neither is the DMV, for that matter.

September 23, 2006

Reality

"Reality isn't virtual enough."

Seriously. I just heard this at a game design panel.

More Data Smoothing fun and some Open GL

It's been an informative few weeks. While I feel like I've been using very thick unwaxed mental floss, I have been learning some new programming (and some data smoothing...) toys. A review of the OpenGL class at Big Nerd ranch is coming this weekend. I have my reasons for delaying this review. It was a great experience (don't worry Rocco); I just want to see if I can actually use what I've been learning in Atlanta to make something.

So! Below is an openGL rendering of the run data you saw in an earlier post. I'm getting closer to figuring out their smoothing tricks! What you are looking at is a moving average with a 14 point window. This gets us much closer to the Nike+ online graph, but we're not quite there yet. Next I try two things:
1. Throw out (or somehow attenuate) aberrant points.
2. Throw a best fit curve in there.

My goal is to be able to reproduce nike+apple's smoothing relatively reliably so that I can then present options (preferences...) to the user for data smoothing style in my cool new run logging application...

RunSmoothOpenGL.jpg

September 17, 2006

Happy Birthday

Nobody loves me but my mother and she could be jivin' too.
- BB King

(Happy Birthday to MOM!)

September 06, 2006

Nike data is smooooooooooth like budda

Looks like the Nike+ data gets... um ... just a little smoothing / averaging. Then again, I still need to test the data importer... You're looking at distance reported per 10 second interval. Raw data babeeee.


run.jpg

September 04, 2006

(Badass-mother-turtle) Feng shui

My little turtle friend has a big (compared to him) rock that he likes to sort of hide beneath. Unfortunately, the overhang the rock provides scares me; I fear he may oneday get himself stuck under there. So... I thought it might be a good idea to put some smaller, more rounded, rocks around the overhang of the big rock. Apparently "it's for your own good" isn't much of an explanation for a turtle. His unceasing (and somewhat noisy) project for the last several days has been a major "I want to hide under there" rock rearrangement. He takes breaks to eat, sleep, and occasionally stretch out under the UV lamp. Even as I write this he's treading water looking at me with a that's right, I'm a badass mother-turtle face. He deserves the moniker. Some of those rocks are almost as big as he is.

Loading files from the project directory

If you're (say) working on an xml parser and you want to load some test files from the project directory and perhaps you're using otest and the senTesting framework...

Set-up your tests in the normal way. (Apple has a pdf that tells you how to do this.)
Set the executable's path to that of your project. In my case the executable is "otest" because I'm testing a framework. (Note: The default path for the executable is the build directory, so I guess you could use ../xml/ if you need the path to be the build dir.)
In your test code (let's pretend my xml files are in a subdirectory of my project called xml), you can do something like this in your test code:


NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:\
[@"./xml/2006-08-28 14;14;17.xml" stringByStandardizingPath]];

Since -[NSString stringByStandardizingPath] knows that "./" means "this here directory, yo" it will expand the path for you. This makes your test code all kinds of happily portable for when you release source to the rest of th e world. <--- I'll be choosing a (GPL or LGPL) license and doing that sometime this week for those of you who want to use my super awesome nike+ ipod cocoa objective-c objc xml parser (The previous string is for Googlebot... chew on *that*)

September 02, 2006

They do share a first name

While I'm not in the habit of making public political statements. I just can't let this one go by.

NYTImes Article

SALT LAKE CITY, Aug. 31 — President Bush said Thursday that withdrawing now from Iraq would leave Americans at risk of terrorist attacks “in the streets of our own cities,” and he cast the struggle against Islamic extremists as the costly but necessary successor to the battles of the last century against Nazism and Communism.

“The war we fight today is more than a military conflict,’’ Mr. Bush said in a speech to veterans at an American Legion convention here. “It is the decisive ideological struggle of the 21st century.’’


Sound Familiar?

It does not matter whether the war is actually happening, and, since no decisive victory is possible, it does not matter whether the war is going well or badly. All that is needed is that a state of war should exist. The splitting of the intelligence which the Party requires of its members, and which is more easily achieved in an atmosphere of war, is now almost universal, but the higher up the ranks one goes, the more marked it becomes. It is precisely in the Inner Party that war hysteria and hatred of the enemy are strongest. In his capacity as an administrator, it is often necessary for a member of the Inner Party to know that this or that item of war news is untruthful, and he may often be aware that the entire war is spurious and is either not happening or is being waged for purposes quite other than the declared ones: but such knowledge is easily neutralized by the technique of doublethink. Meanwhile no Inner Party member wavers for an instant in his mystical belief that the war is real, and that it is bound to end victoriously, with Oceania the undisputed master of the entire world.

September 01, 2006

cocoa xml parsing

Once you get the hang of it, the NSXmlParser isn't too hard. It's event based. This means that you have to think about your code in terms of each XML open and close tag as being an event that's triggered as your parser reads through the file from top to bottom.

My Nike+ cocoa XML parser and data model is working now. I still have some tweaks and additions to do and then I'll wrap it up in a framework and release it, probably under LGPL.

If you want to see it... this is the place to be.

I added a useful method to NSNumber today as well. If you're not new to objc like I am, feel free to pimp my code. It's below. :)

//
//  NSNumberAdditions.h
//  ipodTest1
//
//  Created by Jonathan Saggau on 8/31/06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSNumber (NSNumberAdditions)

+ (NSNumber *)numberWithString:(NSString *)string;
// pass in a string representing a number...
@end

//
// NSNumberAdditions.m
// ipodTest1
//
// Created by Jonathan Saggau on 8/31/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "NSNumberAdditions.h"

@implementation NSNumber (NSNumberAdditions)

+ (NSNumber *)numberWithString:(NSString *)string;
{
NSScanner *scanner;
int scanLocation = 0;

scanner = [NSScanner scannerWithString:string];
if ([string hasPrefix:@"$"]) scanLocation = 1;
// just in case we're given a dollar value

int intResult;
[scanner setScanLocation:scanLocation];
if ([scanner scanInt:&intResult]
&& ([scanner scanLocation] == [string length] )) {
return [NSNumber numberWithInt:intResult];
}

float floatResult;
[scanner setScanLocation:scanLocation];
if ([scanner scanFloat:&floatResult]
&& ([scanner scanLocation] == [string length] )) {
return [NSNumber numberWithFloat:floatResult];
}

long long longLongResult;
[scanner setScanLocation:scanLocation];
if ([scanner scanLongLong:&longLongResult]
&& ([scanner scanLocation] == [string length] )) {
return [NSNumber numberWithLongLong:floatResult];
}

NSLog(@"WARNING::: Couldn't convert %@ to nsnumber", string);
return [NSNumber numberWithInt:0];
}
@end