Jake Scruggs

writes ruby/wears crazy shirts

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Wednesday 6-30-04

Things got much better today. Much to my embarrassment, I drove the keyboard for a few hours. I'm slow, I can't type very well, I don't know IntelliJ (the slick Integrated Development Environment (IDE) that Object Mentor uses for writing Java code), but I banged out a few tests and made 'em pass. The problem we were having is that you can attach files to wiki pages in the Old OMwiki. But in the new, FitNesse-centric, wiki we want to put all the files in one area and have links on the pages. This is mostly just a matter of changing the file structure, but it does have the added advantage of being able to link to files from more than one wiki page (well, you could probably do that in the old wiki, but solution would be inelegant). So we wrote a program that checks the folder (of the wiki page) for files and then creates a link to them at the bottom of the page. And it worked.


Some of the files had spaces in them which made our wiki widgets quit while only part of the way through the file name. But, in the plus column, we were able to completely transfer over all the wiki pages and have them look pretty much the same. Right now Paul and I are working on a program to grab all the filenames with spaces in them and cut out the spaces.

The eighties music was off today (which is good because I was getting a little tired of 'Tainted Love') , and Paul played some Beatles on his desktop-sized laptop.

"The eighties music was off today" -- huh? I don't remember this at all. Were the Object Mentors crazed 80s fanatics?

I'm still scared about pairing with people I don't know, oddly enough. I've been doing this pairing thing for 5 years now and yet I still get wound up at the prospect of sharing a computer with another programmer -- what if they're better than me and I feel bad? Almost 100% of the time my fear is completely unfounded and I end up having a great time and learning a bunch. The only time I really hated it is when I let the other person type too much -- then I just feel like a loser. No matter what the skill difference, each pair should spend about the same amount of time driving.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Tuesday 6-29-04

Well, I didn't drive today, but I did make some progress toward figuring out what was going on. We built a few custom widgets that would translate wiki text that was problematic (for instance: Putting three single quotes around something ('''something''') makes it appear in bold, and two are italics, so 5 should be both italics and bold, right? Not exactly, the FitNesse wiki was only catching the first 3 single quotes. So we used a regular expression (what's a regular expression? A bunch of symbols, which kinda look like swearing ("'''''(.+?)'''''" or ^#[^\r\n]*(?:(?:\r\n)|\n|\r)?), that look for patterns: like a word or words surrounded by five single quotes) to build a custom widget to catch just such a case).

Susan's computer started making this squeaking noise about a week ago. Now it makes a pretty constant background variable squeak/whine. And the parts aren't due in until next week (It's the fan on the processor that's making the noise, so we're a little hesitant to douse it with WD40). Paul sez ignoring it is an exercise in concentration, but I read somewhere that periodic high pitched noises are the hardest to ignore (easiest are low pitch, constant noises).

"I didn't drive today" -- read that as I spent all day watching someone type. Which is not a fun day. Chalk that up to the fact that we were doing regular expressions and I had never seen one before. I'm decent at RegEx's now but I think I avoided them for years because of my first experience. Nothing like resolving to get more involved and then falling out of the frying pan and into the fire to dampen the old spirits. And then a whining computer in the background for extra torment. I'm surprised I didn't just type a single four letter word to sum up June 29th 2004.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Monday 6-28-04

In the morning I installed 40 meg or so of windows 'critical security updates' and after lunch I installed MS Visual Studio. Then I went home.

But seriously folks, that was a fair chunk of my day (2.5 hours alone to install MSVS). Paul and I paired on the OMwiki conversion (to FitNesse) project. I can't say that I'm understanding much. We had this big problem were we couldn't use the 'get' and 'set' methods, but I'm still not sure how we solved it. We did manage to get the conversion program to move all the files to the FitNesse wiki and emulate the FitNesse file structure. But we didn't actually convert the individual pages to FitNesse wiki text yet. I'm so out of it that, when I saw the program run and the files appearing, I thought somehow Paul had finished the conversion right under my nose. I've really got to stop him more often. He understands soooo much more than me I just can't keep up. Micah made a large scale drawing of the program on the whiteboard, but I'm having trouble applying that UML diagram (which I mostly understand, despite my lack of UML training) to the code we are producing. Tomorrow I need to look stupider and feel better about it. This staying quiet and trying guess what's going on isn't working so well.

The funny thing is that, as a teacher, I know that students must take an active role in learning. Which is quite hard if they're way behind. I've seen it before -- when a student gets lost in a class (maybe they missed a few weeks or just took a mental vacation) they tend to shut down instead of asking a lot of stupid questions. Maybe I should drive the keyboard for a while. That ought to be seriously embarrassing.

This is one of about 10 posts where I say something like: "What the hell happened today -- I need to ask more questions." Part of my role at Obtiva is to say this to our apprentices: "Yes I know you feel like a complete idiot and it seems like you can't take one more day of not knowing what the hell is going on, but believe me that I've been there and it will come. Don't be afraid to look stupid early instead of confessing at the end of a week/month/year that you have no idea." Easy to say, but hard to do.

Also the computer I was using was this Dell Inspiron laptop which was about 2 years old at the time and very slow. Installing Microsoft Visual Studio nearly killed it. I think I actually still have it in the other room - I keep meaning to throw it out but it's hard to let go of tech stuff.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Friday 6-25-04

We finished the C# class today with an exercise devoted to Threads. In case you have some operation that will take lots of time (like, say, writing to a file) you can send it off on its own while the rest of the program continues on its own way. This is called MultiThreading and it's pretty cool. We designed a thread that scans a directory (folder) every second to see if any text files have been placed in it. If it finds any, it moves them to another folder. We forgot to kill the thread when we were done with it, so the test kept running after we thought it was done. When we tried to manually place some files in the forbidden directory they automatically moved away. Because the cowboys and I are nerds, we created a whole bunch of text files and tired to jam them in the folder before the program could catch up. Alas, the program was too fast for us.

Micah's gonna be gone next week so the apprentices will be on their own.

The really weird thing about that week was that, up until that moment in my life, I truly sucked at puzzles. Somebody would start in with "You and three friends are walking through the forest and each of you has a prime number of hotdogs..." and I'd get lost and start to panic. I'd be thinking that everyone knows the answer to this but me and they are finally going to find out that I'm a fraud and the dumbest guy in the room. So I'd spend most of my thinking time worrying about how much time was left before someone figured it out and then what if they announced that they had got it but didn't tell me the answer and I had to keep thinking about it knowing that someone had beat me to it and it was probably obvious and... Etc., etc., etc.

The weird thing about that week was that I solved every puzzle without getting crazy. It was like after I got the first one I could relax and think about the problem. It's a constant surprise to me how many things essentially boil down to confidence and comfort. If people feel comfortable in a situation they will perform exponentially better than they will in a tense environment.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Thursday 6-24-04

You Cowboy has taken to saying 'sankyou' when Cowboy helps him out. Cowboy replies with an even more Asianized 'sankyou' and we move on. You Cowboy is also fond of saying 'RefRactor' and 'Ohh Cowboy'' (with this sort of world-weary sigh that's just perfect) There were times when I couldn't code because I was laughing so hard. A quality experience.

The pattern that established itself is this: Micah introduces some concept in C#, such as event handling, and we stare at him confusedly. Then we do a project involving said concept. I get really confused, while the Cowboys trade barbs. Eventually we figure it out. And Cowboy checks his eTrade account. Repeat cycle.

Incidentally, 'delegates' are really cool. They are methods that you can pass around. I have this problem in my Tic Tac Toe game where I keep having to cycle through all the spaces in the board. So my code is littered with things like this:

for( int row = 0; row < 3 ; row++)
for(int column = 0; column < 3 ; column++)
[[some function or other]]

The functions in the middle do all sorts of different things. I think that with a delegate I might be able to have just one place where that nested 'for' loop happens, but with an assignable method inside. Which would be cool. Except that TTT is written in Java and delegates are in C#. Micah thinks that using 'runable' will work, but David thinks it'll be tricky (David thinks it'd be a snap to do in Python -- always with the Python). Anyway, I'm gonna try.

When pairing goes well it's like hanging out with your friends all day, getting work done, and getting paid to do it.

To be totally honest I never did try to use Python or 'runable' to solve the TicTacToe repeated code problem. I did later learn Ruby and blocks which solved the problem quite nicely. As my friend Pat Farley once said: "Ruby is great at removing the duplication where you're doing the exact same thing repeatedly but all the words are different." I had to think about that one for a week before I got it.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Wednesday 6-23-04

More fun today with 'Cowboy' and 'You Cowboy.'

We got to a point where I was totally lost. Finally. Monday and Tuesday were all about picking up small things and differences from Java. Today we got into some full on Polymorphism and it was cool/confusing. Cowboy and You Cowboy were all over it and, unfortunately, I was driving (had control of the keyboard). Cowboy started talking a mile a minute while You Cowboy had some helpful suggestions about topics unrelated. I had just about no idea what I was typing. I don't think pair programming works very well with 'pairs' of three -- sometimes there is too much going on and rational thought is impeded. Later I was able to catch on and here's what was happening: The CheckBook can take in Deposits and Checks, both of which are children of the Transaction class. Today's big task (amongst others) was to give the CheckBook class the ability to step through all the transactions and reorder them. That meant the CheckBook had to inherit from the Enumerator class and the Check class needed to inherit from Enumeratable. And there was much Overriding and passing of classes and the casting -- don't forget the casting. In fact, just thinking about it makes me want to look over the code again. I've got to get M.S. Visual Studio installed on my laptop. Instead, I've been having fun using OM's super-fast mini-computers. They have these cute little Dells with flat panel screens that can fit four to a box in shipping crates. Pretty handy if you need to haul a bunch of computers to a conference (like, say, the XP/Agile Universe conference August 15-18 in Calgary! Whoo!).

I got another puzzle right today. What's up with that? If you want, here it is: You are in a room with three switches. In another room, not visible from your room, are three lights. Each light is controlled by one switch. All the switches are off now. If you leave the room to check on the lights, you can't come back (the door locks behind you, poison gas steams into the room, dogs are released that shoot killer bees out of their mouths when they bark, etc.). You can play with the switches as long as you like but when you go to the other room you want to be able to know which switch controls which light.

Remember: Penn and Teller say that people who love puzzles must die.

Oh 'Cowboy' and 'You Cowboy!', your antics still amuse after all these years. Not so pleasant memories about casting classes into other classes. That whole statically typed thing seems like such a fad in hindsight. I shouldn't really trash talk about Java and C# though. I think half the reason I react with aversion to them is that I was a mediocre programmer back when I was in static land. When I was in Ruby I really came into my own as a programmer and so I associate Java and C# with the times in my life when I sucked and Ruby with some actual competency and satisfaction.
Also, I love the part where I was impressed with the flat panel monitors -- this was 2004 when only the serious would shell out tall green for a 15 inch monitor with thousands of colors and a 1:50 contrast ratio.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Tuesday 6-22-04

More C# today. I was working with two paying customers: Tony and Jeff. Watching those two bounce off each other was a riot. Jeff kept wanting Tony to type faster and Tony got even with Jeff by adopting an Asian accent (Jeff's Asian). Jeff wasn't super impressed with either TDD or refactoring so he kept advocating shortcuts, but Tony kept telling him to slow down 'Cowboy.' Why 'cowboy,' I don't know but it was pretty funny.

We wrote a checkbook program today and we got to use polymorphism. A checkbook can take in deposits or checks, but both are really transactions. So we wrote an abstract Transaction class and then had the Check and Deposit classes inherit from it. It passed the tests, but I need to look it over because by the end of the day we had given in to Jeff's demands and started just doing what he said. Things went kinda fast after that.

In the category of strange but true: I solved not one but two puzzles today. Normally I end up visualizing the person who offers the puzzle as a more gasoline soaked combustible version of themselves. But today things were different.

You should stop reading now if you don't like puzzles. You have two lengths of rope that will each take 60 seconds to burn. The rate of burning, however, is not constant. So one rope may burn through 90% of it's length in 5 seconds and take 55 seconds to consume the other 5%. The ropes are not identical. While one may do 90% in 5 seconds, the other may do the first 90% in 40 seconds. The only thing that is sure is that each will take 60 seconds to burn all the way. You have a box of matches, but no access to a timer. Your goal is to use the ropes to measure 15 seconds.

Fun fact: The two guys worked at a place in my old neighborhood where I got arrested and thrown into jail. Lemme give you some advice about getting arrested -- always carry 100 dollars on you in cash so you can bail yourself out. Most non-terrible offenses have a thousand dollar bail, but they'll accept 10%. The 'jail' was a bit of a let-down as it was really just a room with a locked door and a pay phone. On the plus side I got to call my Dad from 'jail.' Remember that old 'Was not was' song 'Hello dad, I'm in Jail'? Well I do.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Monday 6-21-04

Long bike ride in the rain this morning. Only got scary when those 16 wheelers zoomed by throwing a few gallons of water at me and my wiener bike. Micah was teaching the C# class today and lots of it was familiar b/c Java and C# are pretty darn similar, but it was cool to review TDD best practices while working with someone who didn't know about 'em. I was paired up with one of the paying customers ('Tony') and we managed to figure out M.S. Visual Studio. It's kinda like FrontPage in that it tries to force you to do things the Microsoft way. The refactoring tools are pretty crappy -- no extract method option (which is my new favorite thing)! So Tony and I had to do our own refactoring which was a good exercise. C# does have a cool decimal class which gives you arbitrary precision up to 26 places. This is very cool for money programs, because, as we all know, that guy (Richard Pryor) in that Superman movie used the rounding errors to steal money from banks and we can't have that. Anyway, I feel like C# isn't going to be to hard a transition, but it should be said that today was only the beginning.

I was sleepy all day today because we had this late-night cast party at my pad this weekend. Laura's cast came over and brought their friends. All in all it was about 25 people. I'm glad my landlord (who lives below me) wasn't home because there was lots of loud music and dancing. Right in the middle of Micah's lecture he looked over at me and caught me in this huge yawn -- for the record it was the sleep deprivation and not the class.

In Tic Tac Toe news: My program is now passing 11 out of 11 tests! And the methods tested include minimax and makeTheComputerMove. Now all I gotta do is figure out how to test the human interface. Hmmm.

Yeah that bike ride was kind of a harrowing adventure each morning. The only road that went directly to Object Mentor was a four laner that got lots of traffic. Could be pretty scary.

I went to the first ever ORD session last night sponsored by Inventables and Google Chicago and worked on some metric_fu stuff. The idea of the ORD sessions is that there's a lot of open source developers in the Chicago (ORD is the O'Hare airport code) area so why not get them together to hack on some stuff. I'd say over 20 people showed up and had a great time. It didn't hurt that every one who came got an unlocked google phone as a free surprise gift. When they announced, earlier in the evening, that there would be a surprise we all thought: "Oh cool, I'll probably get a t-shirt or a squishy ball." So the phone sort of blew us away.

As to metric_fu, Jeff from Inventables and I paired on a new meta metric called "Flurn." It's a combination of FLog and chURN and it tells you about files that not only are very complex but also change all the time. This is pretty bad because if the file is in constant flux and it's got a lot of convoluted code then that's a bunch of bugs waiting to happen.

"Flurn" is available through the appropriately named 'flurn' branch of metric_fu on github if you want to check it out before it's released in a future version of metric_fu.

Speaking of future versions of metric_fu, there should be one coming out soon with 'awesome' templates and graphs of metrics over time. Stay tuned.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Friday 6-18-04

I arrived this morning to find that the Martins are back in town. Bob seems like a good guy. I didn't talk to him much, but working next to someone all day can give you a good impression of a person and Bob seemed easygoing and fun. He also was trying to quote some obscure line from a classic Star Trek episode (you know the one where the crew of the Enterprise have been captured by an alien being (again) who wants to learn about humanity (as always) by having them play out some bit of 19th or 20th century history (this time it was the shootout at the OK coral)? Well, I do.) so that gets put in the plus column. Micah took a look at our project. Then he asked us what we thought the project was.

Uh oh.

'Er, to change the OMwiki python code so that it operates more like the FitNess wiki?' Well, not really, as it turns out. What he really wanted was for us to translate the OMwiki pages into FitNess wiki pages so they could kill off the old OMwiki and have it be re-born with all the added features of the FitNess wiki. 'Oh.' We said.

So we start over.

One very cool thing about today is that Micah offered to let me sit in on the C# course that he's teaching next week. I was worried that I might slow the class down because I'm an absolute beginner (I know it's a Java knock-off, and that's about it), but that's who the class is for. Excellent.

Paul and I started writing the wiki conversion program -- TDD style of course. There will be no coding without a failing test. After a few days of Python's super easy file writing techniques, we had to stumble around with Java's roll your own types. Basically, Python is a higher level language than Java so it does a lot more for you. Yes, I grudgingly admit that Python has advantages over Java -- There, I've said it.

When I first started re-reading these blogs post I thought to myself: "Funny, I don't remember that we spent a lot of time fixing up the old Python wiki..." Yeah, that's because we didn't -- We burned a week working on the wrong project. I felt so stupid. However, it's an important point that when XPer's start going on and on about having an onsite (or highly available) customer you should probably listen. I've seen this situation many times since: Only person who knows what they want is totally unavailable and so the developers work on their own only to realize that they totally misunderstood the requirements. The awesome thing is that Object Mentor makes its living teaching people how to be Agile/XP and they still made the classic off-site customer mistake. This isn't to bash on them, but merely to say that when the major stakeholders are unavailable (or perceived to be so) then you're going to waste a lot of development time.

Also, Uncle Bob is a nerd's nerd. One time someone was using an old-school dial up modem in the office while he was around. Just from listening to the "scree scraa scraa" noises it made, which he casually heard from across the room while working on something else, he diagnosed some problem or other.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Thursday 6-17-04

You know what? I had fun today. Imagine that. Yes, some of the day was spent looking at the OMwiki pyhton code which still confuses the hell out of me, but I learned how to extract methods in Eclipse. I know I'm not the first person to say this but, the 'extract method' thingy is way cool. It makes it sooo easy to slice large pieces of crazy code into much smaller, friendly, bits. Almost fully automated creation of methods. Neato.

The other fun thing I did today was getting my Python Tic Tac Toe to not only run, but to play perfect. It takes forever, though. David and Paul say it shouldn't take that much longer than Java, but it does. If the TTT board is empty, it takes about a minute to make a move.

Yet more fun, I'm doing a TDD (Test Driven Design) re-write of Tic Tac Toe in Java. I've hidden the original code away and I'm writing the tests first using the Junit plug-in (this program works with Eclipse to make running tests easy). When your test passes, you get a green bar. Failure is red. It's amazing how addicted you can get to seeing that green bar.

Humbling moment of the day: I'm eating lunch with Paul and I'm describing my Tic Tac Toe program. Somewhere in the conversation he casually mentions that He, Micah, and Chris (former OM employee) each wrote their own chess programs awhile ago. For fun.


If you don't play chess, lemme tell you: It's scary complex. It took Paul six months. Paul's actually been working for OM for about 4 years now. He spent the first 1.5 years working year round when not at school. But then he settled into just working when he's off school. Paul's thinking of getting a Master's in Math.
No Micah today, but he should be in tomorrow. Paul has made some good progress on the OMwiki widgets so I feel much better about the project than I did Monday or Tuesday.

Writing a chess program for fun -- still blows my mind. I believe they had their chess programs play each other. I aspire to someday be that geeky.

There was a time I thought I would never go back to a non-refactoring IDE, but I've been using TextMate for a few years now. Although, one of the guys at work uses RubyMine and I have to say that it's coming along quite nicely. I've had my heart broken with Ruby IDEs so many times in the past that I don't know if I'll ever love again.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Wednesday 6-16-04

The first part of the day was more crazy python code. I was asking Paul some more questions about the Visitor pattern and at some point, while he was describing some aspect or another, he said 'It's kinda like a linked-list.'

This happens a lot. Somebody at OM explains some complicated thing with another complicated thing and I have to take a deep breath and say 'So, what is a linked-list?' At which point paper comes out and drawings are made and I realize that I hadn't really understood arrays until then. I'm so behind the curve in terminology it can be overwhelming. But, I should add, this is a thousand times better than being bored in my Java class. From way too slow to way too fast in one month.

Total immersion is supposed to be a good way to learn a language. I hope so.

We (and when I say we, I mean 95% Paul) did make some good progress on the OMwiki widgets. We've got the widgets successfully passing 5 or so tests. But the wikiWord widget is giving us problems for reasons I don't understand. Something to do with a class/method we can't call from where we are.

I, however, finally got my Tic Tac Toe to program to run without giving me some crazy sort of error. Whoo! That success was tempered by the realization that the program now plays very poorly. Wha happen? One of the big problems turned out to be Pythons' way of sending the object as an argument (the infamous 'self') We ran into that problem a lot in our OMwiki project. Many methods have to take in self and then, to address one of the object's variables, you have to write self.myVariable instead just saying myVariable.

On the way to the train today my bike's gear shifter wire slipped out and the bike defaulted to 3rd gear. Hills became interesting after that. The good people at Rapid Transit (Excellent bike shop) fixed it in 5 minutes for free! Everybody reading this (all 5 of you) should go buy something from them right now (corner of Wolcott and North in Chicago). Later, Bryn and Tina came over to my pad and we indulged in some drunken video game funness (in the interests of full disclosure, we played: 'The Simpsons: Hit and Run.' You know that one level, where you have to use the Globex Supervillain car to demolish all the free laser gun stands, and then get back to KrustyLu studios before time runs out? That's the level we couldn't beat.)

"The Simpsons: Hit and Run" is/was one of those truly great games I still think about from time to time. I wonder if I still have it... Damn! I must have sold it when I got rid of my original Xbox to that guy I met though Craigslist -- he was buying the Xbox and most of my games for his 7 year old son. Only later did it occur to me that I had a number of Grand Theft Auto titles mixed into that bundle. Oh well, that kid's gotta learn about graphic violence someday.

The 'Linked-list' moment still stands out in my brain because just before telling me "It's kinda like a linked-list," Paul had this great look on his face like he had finally thought of a super easy way to explain this concept. He was so clearly pleased with his analogy that I felt just awful fessing up that I had no idea what he was talking about. The weird thing was that, as a teacher, I was totally used to this situation -- just on the opposite side of the learning curve. But that was my job that summer: To get my mental ass kicked every day, learn from it, and come back for more.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Tuesday 6-15-04

Rough day.

There's only so long I like to stare at a mountain of code which doesn't work and I don't understand. Paul was frustrated b/c we still couldn't figure out why the tests of the OMwiki were failing. We sent Micah an email and his reply was pretty much, 'Oh yeah, I've run into that problem before. I don't remember the solution but it's one tiny thing that causes the whole suite to fail.' Nice. Well, Micah's on vacation so that's fine, but it's maddening to know that one line of code may be preventing you from even getting started. Welcome to programming.

We spent the morning banging our heads against this wall, then, having accomplished just about nothing, we went to lunch. Paul thinks John Kerry is crafty for being spineless. I think he's just spineless. We both think he stands a good chance of being elected.

Later we stared at OMwiki some more. It's kinda depressing but I still don't have a real good grasp of 'this'(in Java) or 'self'(in Python). I asked Paul for an explanation but I only sorta understood the answer. Paul sez we're trying to use a 'Visitor' pattern on the OMwiki code, like is used in the Fitness wiki, but I only have a tentative grasp of the 'Visitor' pattern. It has something to do with avoiding a big conditional method by creating a lot of smaller methods ' each of which will translate some different bit of wikiLanguage into the appropriate Html. The cool thing about wiki pages is that you type in certain commands and the code (which we are working on) automatically sets up links, or makes things bold, or does other cool formatting things. At some point, Paul figured out that the vcs (version control system) check-in function was making the files read-only (if you recall, that was our big problem from the beginning). So he commented it out and the tests all passed. Whoo. We'll need to put it back in as soon as we know how to do so (and not bring it all down around our ears), but for now we can work on the wikiWidget (the module that translates user text into links and stuff) and actually be able to test it.
During a free moment, I download TextPad and the Python plug-in that lets it color code python script. Good program ' way better than Word Pad. Unfortunately, my Tic Tac Toe program will compile but it won't run. Actually, for a time it wouldn't do anything. I'd type in:

python TicTacToe.py

(from the command line) and ... nothing. No syntax errors, but no game either. I had to take the 'main' method out and put it on its own. Now, of course, there's all sorts of run-time errors. I keep trying to call methods with no parameters like:

print aBoard.toSting()

and Python keeps telling me I passed it 1 argument. Hmm. I'm working on that one. I'm also having trouble with my program seeing global variables such as the TicTacToe board (myBoard). I kinda wish I could spend some more time working on Tic Tac Toe with David before I look at all that OMwiki stuff in Pyhton. I'm not much use if I can't even execute a simple toString call.

One last thing: Just to complete my day, I missed the train home by zero seconds. Zero, you say? Yep. I just made it but the asshole Metra guy said 'no bikes' and let the door shut in my face. For the record: the bike folds up and goes in a bag (which is perfectly Metra-legal). So I sat around for another 62 minutes waiting for the next train.

Get 'um next time, tiger.

I can still remember missing that train. Some days there was wicked wind coming in from the lake and it would add about 10 minutes to my bike ride -- this was the first time I discovered that. I was peddling my ass off to make that departure and checking my watch every 5 minutes. And then to make it just in time only to be shut down by some jerk. Ah, memories. I'm pretty sure I shouted obscenities for a full minute.

As to my problems with Python -- It's funny to see me talking about how I don't understand Python's 'self' and then wondering what's this weird extra parameter that's getting passed along to all my methods. If you've never programmed in Python you have to declare 'self' as the first parameter of all methods. Which can be a little confusing to those new to the language.

I love, btw, that our big solution to the problem of the tests that wouldn't pass was to comment them out -- not very XP. We did spend a bunch of time trying though, so I guess that counts for something.

The Chicago Tribune wrote up an article about the craftsman swap I participated in 2 months ago:

My thoughts on it are here:

Basically Obtiva and 8th Light exchanged developers for a week. If you want to know more (and why) click on the links above.

This summer I'm revisiting my short apprenticeship at Object Mentor. I'll be posting commentary on all my posts from the summer of 2004 exactly 5 years later to the day.

Monday 6-14-04

Today I took the train to Waukegan, and then unfolded my bike and rode the last five miles to OM.

Good news:

An hour to do some work on the train.

10 miles per day should help me lose some weight.

Bad news:

My commute now takes about 2 hours.

There's a lot of hills.

Now that I'm using Python, I tend to indent everything.

Speaking of Python, I spent some time this weekend translating my Tic Tac Toe program into python. Most of the stuff is pretty easy. But it still took a fair part of today to complete the translation. And when I say complete, I mean it compiles, not that it runs. I'm having trouble printing out the board (my toString method won't cooperate) and I haven't quite got the hang of making complicated calls in python.

This morning I met Paul, the other apprentice. He's been working with OM for about 3? years now. He's finishing up a Computer Science degree at DePaul. During lunch I asked him what he though about apprenticeship vs. college and he had this to say: 'Computer Science' what a joke of a degree.' Hmm. How so? 'I learned more from watching Micah program in a day than I learned in my first year.' Strong words. When I pressed him as to why he feels that academia can't teach CS, he had two points: One, CS is so new and evolving that how to teach it is continually way behind the curve. Two, it just doesn't work unless you have someone right there to help you. As a teacher, I can agree with the second statement. One of the reasons home schooling routinely kicks public school's ass is because you just can't compete with the Teacher/Student Ratio. I'm a way better teacher than just about every home-schooler, but who cares when I'm divided by 30 or even 20.

For awhile Paul and I did some pair programming (my first pair programming experience, aww), sorta. He's way farther along than me so I was only able to contribute a few things, but even so I feel reasonably good that I could do something besides sit there. Unfortunately, we ran into a pretty sticky problem just about right away. While looking at the OM wiki code(written in Python) we found that none of the tests would pass. This is a huge problem because the whole TDD thing requires that you keep checking if the code works. Well it doesn't. Except it does: The Object Mentor wiki is alive and well as we speak. So something's wrong with the tests. It seems that the tests create some temporary files when they start and then delete them after a given test is run. Problem is that the files it creates are read-only, so it can't delete them. We spent a few hours trying to figure out how this could be so, but we were flummoxed. Unfortunately nobody was around who had ever worked with the code (David just started, Lowell is on the business side of things, and others were involved in teaching a class). So we spun our wheels for awhile. At first it was kinda cool asking Paul what various code was for, but after a time he and I were getting more and more frustrated looking at code that really should work. And when you can't test, you can't do TDD. Eventually Paul started coding 'blind' -- as he put it. But by then the day was over and I had to get back on my bike. Man my ass hurts.

This was the first of 3 different summers that I rode my bike excessively to work. Every summer I was convinced the extra exercise would help me lose weight and yet it never did. I guess I ate exactly the right amount of extra calories to keep the weight on. Awesome.

Paul, in the above post, is Paul Pagel. He later went on to co-found 8th Light with Micah Martin. We spent a lot of time that summer pairing, but he was so far beyond my abilities at the time that I felt bad about holding him back. I spent a lot of my days with him thinking "Well, I have no idea what he's doing right know but I just made him stop 10 minutes ago and explain everything so I can't really do that again... Can I?" It's tough when wildly dissimilar levels pair -- in an ideal environment you should try to avoid complete mis-matches but that's easier said than done. One of the nice things about Obtiva is that we often have more than one apprentice at a time and there's always someone who just graduated from an apprenticeship so our apprentices get some exposure to pairing with someone close to their level.

I still have the foldable train-friendly bike, but I probably haven't ridden it since that summer. Wanna buy it?

I just wanted to point out that I'm not editing my original posts except where explicitly noted so all of this is really what I typed up after a day of coding. In this installment, I talk about my first day at Object Mentor as an apprentice. It's interesting to note that the "David" I refer to is actually David Chelimsky -- lead developer of RSpec. Of course Micah Martin is Bob Martin's (Uncle Bob) son and the guy who took a chance on me for the summer.

Friday, June 11, 2004

Today was my first day at Object Mentor. It took about 90 minutes to fight through traffic in the morning, so I think I'll be looking into some sort of mass transit.

Micah is on vacation in Branson, MO (he's been really nice to me, so I probably shouldn't make fun of Branson... much) so I walked in not really knowing what I would be doing. I was introduced to Susan and Telisha (secretaries), Lowell (seems like someone who's been with the company for awhile) and David. David will be working with me until Micah gets back, but David was only hired a week ago and he has been attending one of OM's classes for that week. So although he's an experienced software developer, he doesn't know a lot about the internal working of the company. I guess we'll be learning together.

We got me logged into the network and David started to explain what my project was going to be. Apparently there is this testing program called Fitness which has a wiki (a community run, although moderated, website which can quickly be updated) which is written in Java (a programming language). But there is also an OM wiki which is written in Python (another programming language). So I'm to translate the Pyhton stuff into Java stuff. I think. Since this isn't David's project he wasn't super clear on the details.

But I have only heard of Test Driven Design (which is what the Fitness program is all about) so we had to back up at this point and give me a little intro. The Bowling score intro. So if your goal is to write a program to score a bowling game based on the pins knocked down during all the rolls, you could just start coding. But that would be silly. According to TDD, you should first write a simple test of the program, which will of course fail because there no code yet. Then you should write the simplest possible code that will enable your program to pass the test. So we started with a test for all gutter balls: The score should be zero. So I wrote some code that would enable the scoring program to pass that test. Then we moved on to a test for always knocking down 1 pin, the score should be 20. Fine, I got the code to pass that test. Then I ran into some trouble.

Before I go into that, I should explain why TDD is good. Or at least the short version 'cause there's whole books on this subject. Simply put: TDD forces you to write simple working code. Simple is good because you want your code to be readable after you walk away from it (the maintainability thing). Working is good for obvious reasons. As your code gets more complex, you'll need to go back and change things which will inevitably cause something unexpected to break. If, after every change, you run the tests you will find out about problems sooner (before they get buried in all sorts of other changes all of which could potentially be the problem) and the test will tell you exactly what's not working which is a tremendous help in debugging. Cool huh?

But I have no idea how bowling is scored. Which is a bit of a problem. Strikes and spares are weird. And that last frame... So I ran into difficulty. David went back to his class while I struggled with the strike and spare thing. And it was hard not to start worrying that I was in over my head. I found myself thinking "Look, this isn't that hard so why can't you do it? Hmm? Maybe you don't have a future as a programmer. Maybe they'll realize their mistake in taking me on and get rid of me. Or worse, they'll be polite and assign me inordinately simple work so as not to tax my feeble brain." Yes, I know this all seems silly. But it was my first day and, frankly, I have a lot riding on being able to become a developer so it was hard not to feel a little panic. After a while David came back, saw I was struggling and gave me a hint. After that I got it.

Somewhere in there Lance (salesman) came in with his niece. In between making plans for the Agile/XP universe conference he mocked his niece for not being able to manage a turnstile on the 'L'. She ignored him. I ignored both of them as I was wound up in my impending failure as a developer.

But I worked through that, as previously discussed, and we moved on to the "so you don't know Python" part of my day. David showed me how to download Python and set me to work figuring out a Python tutorial. This took up the rest of the day. Python is weird. Yes I know everybody loves it, but those "for" statements and their use of "lists" are intelligible but strange. I think I might try re-doing my TicTacToe program in Python as a learning exercise. But that depends on how ambitions I am this weekend. My wife's play is opening Friday (more on that elsewhere in this site) and then there's all those videogames I just bought (T.H.U.G., Pandora Tomorrow, and True Crime: the Streets of L.A.). Tough choices.

Wow. I forgot that this was the first time I was seriously introduced to TDD -- and from David Chelimsky no less. What's funny is that TDD was still pretty new to him. Also, I started on a Friday because finals had wrapped up on Thursday (and I had graded them in a rush). I didn't even take a day of summer vacation -- that's kinda crazy now that I think back on it.

Also, also, I really did freak out of my mind when David gave me that bowling problem (which, btw I now know is a classic example of TDD) because I totally had no idea how to score a bowling game. And I was way too scared to ask. And later I was ashamed that I hadn't asked earlier. Eventually I had to just suck it up and confess that I had no idea. David was really nice about it.

It's the 5 year anniversary of my 3 month apprenticeship at Object Mentor so I thought I'd revisit my original blog posts about my time there. Why? Well mostly because I used to collect LaserDiscs and really enjoyed listening to a director's commentary on something they had done many years ago. These days commentary tends to be done either right after the movie is made or because there's a financial obligation and it kinda cheapens the whole thing -- I'm hoping I can at least do better than "Larry the Cable Guy."

Anyway, this first post was written in May of 2004 before I actually started working at O.M. And since it was the first post I think I did a pretty good job setting up my background. I should point out that I was a high school physics teacher at the time and so I was giving up my summer in a desperate gamble to get a new job. Most people, when I told them I intended to become a programmer without going to college, thought I was nuts but were nice enough to nod and smile. I was pretty sure it was a long-shot myself but I had just started teaching "remedial physics" which is physics for kids who don't know algebra and have problems with calculators so I was ready to try just about anything.

And I did. Anyway, without further ado, here is my first blog post ever:

May 2004

I'm going to be spending the summer at Object Mentor learning various programming languages, agile software development, and all sorts of other stuff. In return for dealing with me, they get free labor. All the monkey-work that would be a waste of a good programmer's time will be handled by me. No, I'm not exactly sure what that will be. Should be a pretty exciting summer.

First I should talk about my background and where I am now as a programmer. Probably the first computer I ever used was a TRS 80 in grade school. I was part of some sort of gifted pull-out program and I wrote the usual things a 4th grader would (10 print "Jake is cool." 20 goto 10). During the 80's, when I was in junior high, I got my parents to buy me a TI 99 4/a and I learned Basic. I spent a fair amount of time writing programs. Extended Basic could do sprites, but was so slow that I could never get any decent video games to work because the computer never caught any collisions. All my lasers passed harmlessly though their targets.

Getting a compiler so I could write something faster cost just about as much money as the whole computer, so I was stuck with Basic. Pretty soon I got bored with it and moved on. In high school I got interested in physics and later, in college, I decided to become a physics teacher.

Now here it is 20 some years later and I'm back learning to code. Where'd all the line numbers go? And what's an Object?

About November of 2003 I started working through Eckel's "Thinking in Java." Good, but tough for someone who doesn't know C. In January I started taking an Intro to programming in Java class at a local community college. This was pretty helpful, but also pretty easy. It gave me good footing in what modern programming is all about.

Since I wasn't going to start at O.M. for about a month and I was anxious to learn something, Micah (Micah Martin -- the guy who will be looking after me during my apprenticeship) gave me a project to work on: Design an unbeatable Tic Tac Toe program.

My first pass at this went like this: A TTT board is basically a 3X3 matrix (array), so how about empty spaces being 0, X's are 20, and O's are 1? This way I can multiply all the numbers in a row (or column, or diagonal) to see if there's a win (any zero's will make the product zero, and 3 X's or 3 O's will produce a distinctive number). So checking for a win is easy. So is checking for offense or defense. Add up the row (or column, or diagonal) and a potential win will be either 1+1+0 = 2 or 20+20+0=40. So the computer can block wins, or win itself if it sees the chance. But, there are some ways to set up two winning moves at once, so I needed a series of conditional statements to handle the first few moves (kind of like in a chess program when the computer is "on book" -- playing out well researched moves). If there were no preset moves, offense, or defense, then the program made a random legal move.
Well, it worked, but the code wasn't very elegant. Here it is: (Note: Future Jake moved the code to GitHub. The "first_pass" dir contains the code I am referencing here.) Micah had me clean up the code lots and add the ability for the computer to play itself. He also wanted the human to be able to chose between X or O. Since I wrote the program with the Human always being O, this was a pretty big re-write.

After we got that cleaned up, he had me look up the minimax algorithm and use it to make the computer move. Basically minimax has the computer create a game "tree" with each possible move being a branch. The leaves are the end points: win, lose, or draw. Winning is scored +1, losing is scored -1, and a tie is (kissing your sister) 0. The computer picks the maximal score if it is the computer's turn, but it picks the minimal score if it is the opposing player's turn (based on the assumption that the opponent will play perfectly, and that he/she/it wants to win). Now if the board is empty, the computer has to look at around 40,000 moves. So the first move takes awhile. But the cool thing is that now the computer not only doesn't lose, but it can set traps for the other player. Neat.

This algorithm uses recursion to construct the game tree, and that was pretty new to me (I had used some trivial recursion before, but nothing this involved) so this re-write took a fair bit of time. Here's the code: (Note: Future Jake moved the code to GitHub. The "second_pass" dir contains the code I am referencing here.)

Doing all that filled up the month before I started nicely (keep in mind I was still teaching full time, so this was free time work).

Isn't the part where I talk about multiplying or adding up the TicTacToe rows weird? Where the hell did I come up with that? I seriously have no idea.

Jun 7, 2009

Iteration Zero

I spent the week doing an iteration zero for new project. The idea behind iteration zero is to get the development environment as automated as possible so developers can spend their time coding when the real development begins.

So here's what we did:

1. Set up new git repository
We use GitHub so that only took a few minutes.

2. Make new Rails app
Again, just a few minutes

3. Set up geminstaller and basic gems (HAML etc.)
Geminstaller installs gems needed by the project and makes sure they are there before starting the app. This functionality has been pulled into modern versions of Rails now, but I've found it a little wonky and I'm working with a former Pivotal Labs guy who just loves the Pivotal stuff (don't even get him started on Tracker vs Mingle).

4. Set up developer tests.
We looked into Shoulda, but ultimately went with RSpec (although we may use the Shoulda macros to test ActiveRecord) because most of the criticisms of RSpec are that it's too heavy. To that I say: "Give Shoulda some time and success and then see if it's still light." Feel free to flame my comments section.

5. Set up Selenium (Integration) Tests.
We used Polonium. We could have gone with WebRat, but no one on the project had ever used WebRat and one guy had extensive experience with Polonium. Our build now fires up a browser and clicks through the app (we will be taking pains to keep this suite short -- just a smoke test really).

6. Set up Continuous Integration
We went with CruiseControl.rb. Note: Use the ThoughtWorks version on GitHub. If you go to the main CruiseControl.rb page it will direct you to an old version that doesn't support Git.

7. Set up scripted deploy
Looked into Vlad the Deployer, but it's lack of documentation did it in. I know it's supposed to be much simpler than Capistrano, but we couldn't get it to work. Capistrano is fine, but it's basic documentation starts talking about spinners and spawners at some point. Wasn't that like 4 years ago? Here's my advice: Follow the capify.org "from the beginning tutorial" but skip the spinners and spawners stuff and just put this in your capfile:

namespace :deploy do
desc "Start the server"
task :start, :roles => :app do
run "mongrel_rails start -e production -c #{current_path} -d -p 3000"

desc "Stop the server"
task :stop, :roles => :app do
run "mongrel_rails stop -c #{current_path}"

desc "Restart the server"
task :restart, :roles => :app do
That's good enough to get you going. Basically you overwrite the stop, start, and restart tasks that cap uses under the covers. I should point out that I'm using Capistrano version 2.5.5 because all the doc for cap I find on the web never mentions the version they are talking about and it drives me crazy. Cap has changed A LOT over the years and something that was perfectly good in 2006-7 may not be so relevant now. Also, we're using capistrano-ext version 1.2.1 so we can deploy to multiple environments.

8. Set up Demo and QA environments
After the previous task, this was easy. All we have to do is 'cap demo deploy:setup' and 'cap demo deploy' to get the demo environment up and running. QA was the same except for, uh, using the letters 'qa' instead of 'demo.' Now we can deploy with one command -- w00t.

9. Set up NewRelic
NewRelic lets you profile your Rails app with ease. I've used it before on apps I've written and have found it immensely useful in tracking down slow parts of the project.

10. Make Cruise Control run a Metrics Build every 24 hours.
Yep, I really do use metric_fu on my projects. I like installing it from the get-go so we can keep an eye on things and track changes to the app.

Well, that ended up being about a week for a pair of developers (with some interruptions for meetings and other stuff) and a pretty good iteration zero if I do say so myself.

I didn't. The box I was setting up CruiseControl.rb on today had some crazy early version of Ruby 1.8.6 and so test failures returned a code of '0'. Which meant the build would not fail until I upgraded to a more modern 1.8.6. Patch level 114 did the trick. Why are we using 1.8.6 on a new project? Well mostly so we can run along side an older Rails app using 1.8.6, but also because 1.8.7 doesn't really offer that much more to justify the headache of running two rubys on one box, and finnaly because I have no idea when 1.9x will be acceptable on all the gems I use.

Good times.