Week 2, Tuesday

March 31, 2009 at 6:57 pm (Ruby, Week 2) (, , , , , )

Today was my first day of really serious pair programming: Eric Meyer and I worked on a Rails application, learning Cucumber together along the way. Some of the most interesting things I’d read about pairing really proved true for me today: it was more fun than developing alone, it made me concentrate more and think through decisions better than I would alone, and it definitely gave us a better result than I’d get alone (I can’t speak for Eric!).

Cucumber is a great acceptance testing framework. The idea is, you write the tests in plain text, then wire them up using regular expressions to Webrat, Selenium, Watir, Mechanize, etc. There is a little more structure than that, but your best guess is to jump right in and try it out. Even if you’re not doing unit tests, these can really prove that a given feature works, and it only takes an hour or so to really get the hang of it. Cucumber even generates regexes for you to copy and paste, based on your Givens, Whens, and Thens. If you’re interested in learning Cucumber, check out Ryan Bates’ Railscast on Cucumber. It’s really clear and you don’t need to be experienced with testing to understand it (and it’s brand new – just came out yesterday). I’d definitely start here if you’re doing Rails work and are interested in getting into testing. And if you’re doing Rails work and NOT interested in getting into testing… Well, I’d still start here.

It’s nice to be doing Ruby again, where I have a lot more experience, but I quickly realized that the way I did Rails isn’t anything like the way 8th Light does Rails. Basically everything gets unit tested, including views. One result is that I’m very confident about the solidity of this application after running all of the specs, but another equally important one is that when things need to change, we find out very quickly when things get broken, and we know when everything is fixed. So we don’t waste time click-testing through sample user workflows as each change gets made, but we still know we’re OK.

I had to stop our coding process several times to ask questions and sometimes just look at the code for another minute or so to absorb the reasons for testing decisions. Mocks and stubs are looking more normal, and I’m even starting to notice ahead of time when one will be needed. I still struggle with starting out on a testing path, and I’m sure it’ll stay that way for awhile, but I know I’ll progress with time and experience.

Advertisements

Permalink Leave a Comment

Week 2, Monday

March 30, 2009 at 6:57 pm (Java, Week 2) (, , , , , , )

I feel like I’m getting close to completing the Tic-Tac-Toe game in Java. The functionality is there for Swing GUI and console modes, but I have a lot more to learn about GUI testing (simulating mousePressed and actionPerformed events) and testing threads (turns out I need to USE threads to test threads – duh).

But I’m feeling much more comfortable in Java. At Micah’s suggestion today, I took a lot of GUI-specific code (JLabel, JButton, etc.) out of my controller class and moved it into the view. This made a lot of sense since the implementation of the view should be easily swappable, without the controller worrying about it. I also refactored my old ConsoleDisplay class out to be more in line with my GUI code, so that both the console code and GUI code are just views, using the SAME controller/presenter. This was kind of a pain in that I had to add threading in the console code so that the GUI controller worked for it as well, but the big win here is that I can swap out views super-easily. It probably would have taken me another whole weekend without Micah’s help today, though.

We had an internal stand-up meeting, where everybody briefly talked about their current projects, side projects, learning experiences, blogs, kata, etc. It was short and to the point, but I think it’s a great idea for a team’s camaraderie – especially since two of the team members work at a client site. Paul just came out with a great blog post titled Material Consciousness in Software that’s well worth your time, and both Erics have blog posts in the works. Stay tuned!

Speaking of the culture here at 8th Light, I noticed very early on that everyone, without exception, shakes hands with everyone else as they arrive at work, and as they leave. It seemed very formal and quirky at first, but it’s really growing on me. So often, people show up to work with their team and barely grunt a “Morning” before diving into code. I definitely was guilty of that at my old job, and it seems like this is a good way to reinforce the team’s communication. Now that I write this down, it sounds like marketing mumbo-jumbo, but it’s a fact. I don’t know whether this is something that’s grown organically here or if the guys formulated the idea before its execution (or somewhere in between), but shaking hands feels like it solidifies a relationship each time, and at the same time heightens the importance of what you’re about to do (or have just done): software craftsmanship.

Permalink Leave a Comment

Week 1, Weekend

March 29, 2009 at 9:03 pm (Java, Week 1) (, , , )

I spent a lot of time this weekend trying to wrap my head around Java/Swing listeners and how to do TDD with this setup. Eventually I backed up a bit and dug into some more basic Java knowledge – reading from Learning Java by Patrick Niemeyer and Jonathan Knudsen. I just was a little overwhelmed with all I need to learn, and I wanted to focus things a bit more. And it turns out, after spending a good portion of the weekend looking at event listener code, I have a lot better grasp of it now. I was able to delete big chunks of my old GUI code and simplify some things. There are still LOTS of things I need to learn about testing this stuff; I think I might’ve painted myself into a corner with my console-based presenter, so that testing is difficult. Maybe there’s a way around it I’m not seeing, though. Basically, I have the core logic sending a request to a controller (for a move, the game type, or playing again), and the controller listening to the view layer for the answer. Right now there’s a lot of state-saving variables (boolean waitingForInput, stuff like that) that I know there has to be a way around.

At any rate, I’m going to spend some more time with the Java book over the coming week, so that I can get a better handle on things. I’ve been a bit spoiled in that I’ve worked with Ruby for the past couple of years, and have had all that time to absorb and read about the language. So much to learn! It’s so motivating when I come into work and literally everyone else knows so much more than I do (and are more disciplined). The advice that I’ve read from Chad Fowler (My Job Went to India) and many others to “Be the Worst” is really paying off.

I also realized that I never blogged about our Friday Lunch & Learn session – we had a Randori session, where we worked in five-minute pair programming sessions to build a small app. It was humbling to get back into Ruby, which I felt great about two weeks ago, and forget the syntax to set an instance variable in front of everybody (I was being Java-y). But it was excellent to see everybody in action and to hear people’s thought processes as we started the app, when the design was so sparse.

Permalink Leave a Comment

Week 1, Friday

March 27, 2009 at 5:28 pm (Java, Week 1) (, , , , , )

I spent some time last night experimenting with Swing and was able to get the Tic-Tac-Toe grid set up, with some listeners on the squares. Then this morning I wired up the GUI to my existing Java Code. I only had to make one major change, which was getting rid of the Dependency Inversion Principle violation I had in my display code. I just turned that into an abstract class and moved the existing, console-based code into a subclass, and then also derived a GUI display class from the abstract class.

That part was simple, but I really did a lot of monkey-hacking today to get the GUI working properly together with the existing game code. I think part of the problem was that I never really stopped the “spiking” I did last night to learn how to use Swing a little bit. I just kept right on trucking (in implementation code, without tests) until I had a working game. So I need to go back and retrofit some tests to most of the code I’ve written today, which I’m sure will mean rewriting some things. My mom got me Michael Feathers’ Working Effectively With Legacy Code for my birthday, so I may dig into that some to give me some ideas. My understanding is that the book describes legacy code as any code not under test, so I wrote a bunch of legacy code today [frown].

On a brighter note, I’m going to be working with one of the craftsmen on an internal project, most likely using Rails, so at least I’ll be familiar with the language for this one. I’m glad I’ll have a compelling reason to learn RSpec, and probably Cucumber and Selenium as well. These are the kinds of things that motivated me to want to work at 8th Light in the first place. As I told one of the craftsmen when I interviewed, it seems like all of the big names in the Ruby world use TDD/BDD, so I really was looking forward to writing code that way.

I took my first crack at estimating (our initial iteration meeting for the project was today), and only time will tell if I was being too optimistic or not. I certainly don’t think we’ll have too little to do, but as I said in a previous post, I think I’ll get better at estimating as I do it more often and measure actual velocity (stories completed per iteration) against estimates.

Since it’s the end of my first week here, I’ll just close with a general thought on TDD: it isn’t faster to write your first few lines of code in a new project. But if you have tests for those lines, then you know they work. The tests allow you to forget about them, and still be able to change other parts of the eventual system without fear of breaking old stuff. Because it’s got a test suite that you run and see that of the system’s requirements that you have encoded in tests, you’re passing. I’m looking forward to making this a habit and really having TDD become my default coding behavior.

Permalink 6 Comments

Week 1, Thursday

March 26, 2009 at 7:05 pm (Java, Week 1) (, , , , , , , )

I FINALLY got my head wrapped around the minimax algorithm today. I went more slowly and stepped away more often, and I finally have an unbeatable computer in Java. This took me a heck of a lot longer than it did in Ruby, but I think it was reasonable considering my limited Java knowledge, a new algorithm, and new knowledge about things to avoid.

My last step was kind of an interesting one: I rewrote (not refactored) part of the algorithm in a way that was easy for me to understand, very slowly and deliberately, and it came out right! Imagine that…

// before:
bestScore = Math.max(bestScore, -minimax(child, depth - 1, otherPlayer);

// after:
otherPlayerScore = minimax(child, depth - 1, otherPlayer);
maxOtherPlayerScore = Math.max(otherPlayerScore, maxOtherPlayerScore);
bestScore = -maxOtherPlayerScore;

If you take a minute or two to look through this, you’ll see that the two versions are not equivalent. Although I could break the second version down into one line, I don’t trust myself to be able to understand it as well later on, so I’m leaving it explicitly spelled out this way.

I demoed the game for Micah and indeed, it seemed to work correctly. Micah had me draw up a UML diagram of the code in its current state, with all the methods and dependencies that I knew about, and Micah pointed out violations of the SOLID principles for object-oriented class design. I’d read about them but needed a refresher and deeper understanding, so he walked me through each of the principles, asking me what they were and where I saw problems. I didn’t catch them all of, course, but I was glad I at least had a cursory introduction already. I made sure that I understood the kinds of situations in which a principle violation would bite me.

For those unfamilar with these, you can learn more on Ward Cunningham’s wiki (he’s the inventor of the wiki, among other distinctions):

I just read about these for the first time a few months ago (they’re detailed in Agile Software Development: Principles, Practices, and Patterns by Robert C. Martin (Micah’s dad, incidentally). I had more Dependency Inversion violations than anything (though certainly not as many as my Ruby version had), but there were some Open-Closed problems as well.

My next step, which seems realistic for an Agile/XP project, is to put a GUI on top of my Java code. I haven’t done anything to speak of with Swing, so I spent a couple of hours this afternoon investigating the API and figuring out sizing, colors, and other things I’m going to need to draw the board.

I have an Open-Closed violation or two around my GameDisplay class, which means that my design is going to have to change around that point in order to substitute the GUI for my command-line output. The good news is that I HAVE a display class in the first place; my Ruby display code was coupled to the rest of the game in several places.

Permalink Leave a Comment

Week 1, Wednesday

March 25, 2009 at 8:03 pm (Java, Week 1) (, , , , , )

We worked from a client site today, where Jim and Eric S. generally work. They had an iteration meeting this morning, so I was there to observe. I’m told this one was really abnormal, as the new feature demo was only a few minutes long and it was around one computer rather than a conference room: one of the customers was on a tight schedule and had actually already signed off on some other stories from the iteration.

Each time Micah sits down with me and I try to explain my way through something, I realize how differently I need to approach my coding. Here’s the conversation that ends up happening (perhaps a bit paraphrased and exaggerated for my point):

Me: So, one of my tests is failing but the others are all passing. Here’s the code…
Micah: OK, so walk me through it.
Me: Well, this thing depends on that one and needs to call on it for later on when it updates the other thing. And before, when I was working on that first thing, I had a weird problem with the other thing so I changed the implementation of that first thing to be the new thing’s gobbledygookandtrailingoff… [you get the idea]
Micah: Wait. Go back to the beginning. Let’s think through each step.

I must slow down and be more methodical, especially when I’m having a problem. And even more especially when I’m having a problem understanding why I’m having the problem. The whiteboard was VERY helpful in solidifying my understanding of the minimax algorithm itself, especially as I applied terms from the implementation to it. Recursion can be really difficult for me to understand when I don’t go step by step (or call by call).

My ComputerPlayer is getting better: it wins when it can win immediately, but it gets much dumber after the first move. I actually thought it was finished at one point, but alas, my tests weren’t extensive enough and I was able to beat it easily. I banged my head against the wall (figuratively, of course) for awhile today trying to get it working – I think I needed to step away for awhile. Jim suggested 25 minutes of continuous coding/debugging, and then a 5-minute break (the Pomodoro technique). I’ll give that a shot tomorrow.

There was a lot of refactoring today. Some of it was to sanitize some nasty stuff I’d written, but some was out of necessity. For instance, I had the Board responsible for deciding the next move possibilities, but it should have been the Player, since the move itself depends on the player’s mark (X or O). This meant I had to bring a method or two up out of my Board class into the Player before I could move on with the algorithm. I also learned a couple more refactorings in IntelliJ that will save a lot of time: Introduce Variable and Extract Method. I had to spend a little time verifying for myself that the Extract Method change wasn’t going to break anything, so I need to crack the cover of the Martin Fowler Refactoring book sometime soon. It’s in my reading queue piling up from Amazon, but there are several others as well.

I spent a little time with Java generics and Lists in the morning – I’m used to Ruby where an array resizes for you automatically, so I figured that a new Java array, even one with space for 9 allocated, would have length 0, as it does in Ruby. But of course int[] possibleMoves = new int[9] is just an array of nine ZEROS. At any rate, I’m certain this is a much better way to learn a language than trying to learn all the syntax cold before hopping into the code, but it’s frustrating sometimes. I have a good friend living in Berlin who knew only a few phrases in German like “Where is the bathroom?” when he moved there a few years back, but of course he was fluent within a year or so. I imagine it’s similar here, except that I don’t have to speak in Java to buy a sandwich. Yet…

Permalink Leave a Comment

Week 1, Tuesday

March 24, 2009 at 8:05 pm (Java, Week 1) (, , , , , , )

Okay, so today was harder. I had a flurry of discoveries this morning as I got my questions answered from some work I did last night on the Tic-Tac-Toe game, and then I hit a big roadblock this afternoon. Lesson learned: interrupt when necessary and get questions answered rather than stalling on my own if I’m really stuck.

My problem this afternoon was the Minimax algorithm. I’d looked at it briefly before, after I had finished the Ruby version of the game, but didn’t understand it and gave up. Since the algorithm is part of this assignment, I buckled down and read several descriptions of the algorithm that I found on Google. I thought I understood the mechanics of the algorithm, decision tree and all, but two things were eluding me: the implementation of the decision tree and the computation of the value of a given board position. Eventually I got close (basically translating the pseudocode to Java and Tic-Tac-Toe), but I really did need Micah to help me think through my implementation line by line in order to see a big mistake I was making with recursion. It’s not there yet, but I think it’s close.

Which leads me to the other (maybe bigger) afternoon problem: in my efforts to understand and implement the algorithm, I had neglected TDD and avoided writing tests. Because it was hard => because I’m not good enough at it yet. Well, Micah’s given me some ideas to begin with: sending in board positions where there is a definite best move, and testing that the algorithm spits out the right one, along with some other lower-level things. He did say it’s hard to test, so that makes me feel a little better, but I have to get to the point where I’m not intimidated by TDD. I caught myself jumping ahead to the implementation several times today (and once in front of Micah IN THE TEST CODE – whoops!).

On to the more complete wins of the day, from the morning: I came in with a couple of questions about how to test specific points in the project. Let’s say I have Game, Player, and Board classes. Now, I needed to test that when I told a Player to make a move, the Player would pick a move, and then populate the Board with that move. I was struggling to find a way to verify that the Player had told the Board to populate. It turned out that I just needed a mock Board object. I had an inkling that this is something mocks would be good for, because I remembered a bit of RSpec (ONLY a bit) where an object might have “should_receive(:populate)” to do something similar. I was really glad to come across this problem, because nearly every time I’d read about mocks and stubs in the past I’d come away feeling dumb and defeated. This was simple, though: I just derived a MockBoard class from Board, added a field on the class (private boolean populateCalled = false;), and overrode the populate() method, setting populateCalled = true inside it (and calling super.populate() when I needed the real behavior later).

I’m still incredibly slow in IntelliJ, so I was happy to pick up a few IDEAs about it today. Get it? Get it? I know, I’m incorrigible… Shift-F6 is the Rename refactoring. Wow, is that going to save a lot of time! I think you have to be hovering on the declaration, but the program goes through and changes the name of that method/field/variable/class, in a pretty smart way.

The biggest IntelliJ thing I’m excited to know about is Live Templates, which right now seems exactly like TextMate snippets. Micah wrote me a quick one that does the skeleton of a JUnit test on a tab-complete of “test”, and I can see how this is going to come in handy. I always liked scripting up and using snippets to blast out often-used ERB template things for Rails, and I’m definitely going to start paying more attention to the things that I end up typing over and over so that I can give those to IntelliJ to do.

Permalink 3 Comments

Week 1, Monday

March 23, 2009 at 7:07 pm (Java, Week 1) (, , , , , , )

Alright, first real day of work in the books. I started off with the normal things, getting email and other account access stuff set up, and then Micah had me install IntelliJ and JUnit. Java, I knew it! Though Micah has assured me that won’t be the only language I work in: I’m betting on C++ as well, maybe some Objective-C too?

At any rate, my first assignment is to re-implement Tic-Tac-Toe in Java. And boy oh boy, this is a lot slower going than when I wrote it in Ruby.

First of all, I know Java only a little better than I know C. Which is not well. More on that later.

Secondly, I’ve read and learned so many things about object-oriented design principles recently that I’ve spent a lot more time trying to avoid a crazy dependency structure like my Ruby version had. That’s a good thing; once I learn to do these things right it’s going to be possible for me to write clean, maintainable code. I spent a bit of time mapping out what I thought would be a decent design, and then Micah helped me with some UML concepts at the whiteboard. I got a little bit better idea of how class diagrams work (public vs. private variables, dependencies vs. inheritance, abstract classes), and I started to understand dynamic diagrams a little better as well. I’d seen these in the PPP book (Agile Development: Principles, Practices, and Patterns) but I really just used context clues to get an idea of what I was looking at there. I checked out a book on UML from the local library; hopefully I can catch up a bit with that as well.

I’m learning a lot of Java. Most of my previous knowledge was from a kind of hand-holding online course where you mainly just had to fill in the blanks to complete the programming exercises. Sure, I read a lot of articles and some API docs, but it didn’t really stick, I guess. So I’m going to have a lot of “DOH!” moments along the way. A big one today was that to initialize an array in one line, you have to use curly braces:

char[] letters = { 'A', 'B', 'C' };

Yes, I was using square brackets and couldn’t for the life of me figure that one out (though to my credit, I finally found that problem without having to ask). Without going into all of my mistakes, we’ll just say that abstract classes and methods, and parsing user input (and especially testing that!) were also problematic for me. “Doh!” say I; “Duh!” say the Java people. Well, it’s new to me; I’ll learn.

I also got to sit in on an IPM (Iteration Planning Meeting, NOT Integrated Pest Management, as Google would’ve had me believe) for Fresnel, an open-source Limelight application, and learned a bit about the estimating process. Just like I’m reading about in Extreme Programming Explained, these guys estimate units of work (stories) with story points, which don’t really stand for a specific time period. The team has measured its velocity (number of story points from the last iteration), and it assumes it can get the same number of story points done in the next iteration. If the points completed go up or down from the previous week, the velocity has changed, so next time the team takes on fewer or more story points to match the previous iteration. The team comes to a consensus (unanimous in the case of the small team I was observing), based on discussion, about how many points each story is worth. I like the idea of measuring progress and adapting on an iteration (2-week) basis – it seems like over time you’d get really good at estimating, which is definitely a skill I need to work on.

Permalink Leave a Comment

Week 0

March 23, 2009 at 6:04 pm (Pre-Apprenticeship) (, , , )

I’m not really trying to be clever by numbering the first week the same way we index arrays: my first official day as an apprentice is Monday (March 23, 2009), and Micah invited me to come in the Friday before to observe the beginning of 8th Light’s annual employee reviews. So Week 1 will be the first real week. This “week” should be the shortest since I was only in the office for a couple of hours.

I was a bit apprehensive that people wouldn’t feel comfortable giving and having reviews with me around, but the craftsmen – Micah Martin, Paul Pagel, Jim Suchy, Eric Smith, Doug Bradbury, and Eric Meyer – were gracious enough to allow me to sit in (and were very friendly and accomodating). There were two reviews over lunch. Everyone gathered around the conference table, and starting with the person being reviewed, talked about the person’s performance over the past year. It became immediately obvious that the guys really respect and trust one another – people were a lot more verbose when talking about strengths than when going through the “things to work on”, and the negatives were couched in sympathetic but honest terms. Constructive criticism was the rule: when people needed to say something negative, they also gave advice on a solution. Another commonality was that people being reviewed really already knew most of their strengths and weaknesses, which says to me (and I believe someone else mentioned this during the reviews) that they’re also thoughtful and self-aware.

I’d like to see this kind of trust and respect in any team I’m going to be a part of, so it was great to see this kind of cooperation. I’ve been in other teams (mostly chamber music groups I’ve played trumpet in), where any suggestion that someone could improve some aspect of their performance would have resulted in a great deal of anger and tension. I really didn’t sense that kind of atmosphere here, which is both encouraging and exciting.

Permalink Leave a Comment

To the Starting Line!

March 21, 2009 at 10:40 pm (Pre-Apprenticeship) (, , , , , , , )

I’ll just give you a quick summary of my software career up to this point and how I came to be an apprentice at 8th Light.

I really lucked into my first job, which started out as a part-time XHTML/CSS web development job and grew to full-time. I was a 3rd-year grad student in trumpet performance, worrying about career options, so I answered an ad in the university newspaper, and soon I was off and running. I learned a ton there: cutting up Photoshop mockups into XHTML/CSS, writing small apps in Ruby on Rails, basic Linux system administration, and lots more. I owe them (Plexus) a lot, and I’ll be forever grateful.

In the past year or so I’ve started reading and coding a lot outside of work, and I’ve realized more than ever before how much I have to learn about the process of creating software.  Here are the most important books I’ve read, just to give you more of an idea of where I am: Ruby for RailsLinux: The Textbook (Sarwar), The Rails Way, The Pragmatic Programmer, The Ruby Way, MySQL (Dubois), My Job Went to India, Design Patterns for Ruby, and I’m currently working on Agile Software Development, Principles, Patterns, and Practices, Extreme Programming Explained, and Clean Code.

Frankly, my software development experience beyond that is minimal: I took an introductory C++ course in undergrad, and last year took an online (introductory) Java course and watched online lectures in C and PHP. When it comes to TDD, design patterns, refactoring, object-oriented principles, Agile, XP, data structures, algorithms… I just need much deeper knowledge of these and other areas if I want to become a real software craftsman. And I do.

I heard about software apprenticeship and found the Software Craftsmanship Google Group, where I posted asking for pointers on improving my skills. Micah Martin, one of the founders of 8th Light, was kind enough to invite me to dinner to discuss opportunities (I lived in Athens, Georgia, and he had a client near Atlanta). He told me about 8th Light’s apprenticeship program, which I’d read about, and said if I was interested in talking more about it, I’d need to write a Tic-Tac-Toe game that always won when it could, and tied in all other cases.

I’ll be honest, it sounded really tough, but I was excited about it, so I spent a couple of late nights hacking on it. There was no language requirement, so I used what I knew: Ruby. I knew Micah wanted to see unit tests (with which I had basically zero experience besides playing around with Rails unit test tutorials), so I did my best to write tests first. I actually did mostly TDD until it came to the game AI, which I wasn’t really sure how to handle. At any rate, once I thought I was done (and pretty proud of it, I’ll admit), I sent it off to Micah, who was nice but helped me to rethink some very bad decisions I’d made. Some of these bad decisions were due to my deficiencies in object-oriented principles, some due to my deficiencies in algorithms, and some [cringe] due to my lack of thinking through the knowledge I already had. It was a great lesson in humility and discipline.

Fast forward a bit to my interview in Libertyville (a Chicago suburb): four of the 8th Light craftsmen interviewed and/or pair-programmed with me, and I was really impressed by the quality of code and depth of thinking that these guys were doing. I was inspired to write better code, and I wanted to do it as soon as possible. The official apprenticeship job offer (and immediate acceptance) came on February 16, and my first day of work is March 23. Meanwhile, I moved 834.2 miles from Athens, Georgia to Mundelein, Illinois—whew!

So while I’m not really at the very beginning of my learning process as a software developer, I’m nowhere near the end. I know I’ll continue learning as long as I’m around, but I’m definitely ready to start moving faster.

Permalink 4 Comments