< prev 18 Nov 2014 to 11 Nov 2014 next >

Posts from November 2014

  • Week 2 Day 1 - "We can refactor that later"

    Today's partner: Marc

    Today was the day of the first assessment. It went well—I was less nervous than when I did the practice assessment, which I guess is the point—but I ended up tripping on the same edge cases as I had doing the practice. Derp.

    (Technical gore ahead: I was writing a sort method per the instructions, specifically bubble sort—I know, I know—and wrote a helper method to implement bubble_sort! that was called by bubble_sort. Somewhere along the way I started getting wrong argument errors—0 for 1 or 1 for 0, depending on what I was doing at the time—and it took me ten minutes to see that I had been checking the function signatures for errors, when it was the call out to the helper method that was causing the problem.)

    I felt guilty for finishing early since it seemed like most everyone else was still working, but looking around it seemed a couple people finished earlier than me. Sure enough, looking at tumblrs, another student finished absurdly quickly—the specific student I expected—and really, I ought to have been just a bit slower than him.

    A lot of students have that moment when they first enter a highly selective program where they realize they're can't easily be the best anymore. I've had enough time in life to get used to that idea, but really there's little enough excuse for me not to push harder to get better. Having a decent target to reach has helped my typing speed (compared to just typing gibberish in a typing trainer) but I still have to test my assumptions about what a method can handle and what it returns too often for comfort. What I'd like, by the end of this program, is to be in the running as the "best" student and not just coast on … whatever it is that's gotten me this far in life. That will take work, and prioritization.

    As any regular reader of this blog will be able to understand, most of my biggest demons are of my own creation.

    We spent the entirety of the rest of the day working on Minesweeper. I can tell after a solid week that one of the critical pieces of Pair Programming is how well or poorly the personal dynamic plays out. Historically, I haven't been one who can easily convince another to adopt my priorities. This is another thing that I think raw competence can help with: people will listen to someone who seems to know what they're talking about, especially if they have easy confidence, even if that person doesn't actually know what they're doing (until, of course, that person is revealed as a sham). Further, sometimes the people you have to work with really want to go in one direction when you wholeheartedly believe that another route will bear more fruit. Wrestling with this sort of thing can be exhausting, because either you defend your idea and "win", or you realize the other person has the better idea and concede your point. Either way, you've expended a lot of mental energy.

    I'm not saying, mind you, that my partner was particularly difficult to work with. I have had some amazing pairings so far, but today was one of those days where we each had an idea for what needed to happen, and we were pulling in different directions—vectored off from one another just enough that it was a challenge to move forward.

    We got where we needed to be by the end of the day. The game worked, we had a somewhat clean data model, and our logic held up. We were even able to add some extensions—we changed the symbols used from rough ASCII to some nice Unicode that I think was much more readable on-screen. But toward 3:00 or so I began to think we ought to order T-shirts that say "Don't worry about that; we'll refactor later." Were this a production codebase, we'd have accumulated a lot technical debt today. Compare this to most of the projects in the first week: my style was much more comfortable and easy to read, with only a couple places (typically method chains) where I could benefit from some cleanup, and I think that's a direct consequence of having a solid idea of where we needed to be and the route we would have to take to get there in the first thirty minutes of class.

    That is to say, all of our problems can be traced back to an overall bad approach to architecting the solution, specifically the separation of class responsibilities and the mechanism for passing certain objects. Prototyping, or figuring out a full schema earlier on, may have helped protect us from some wild goose chasing, but as Fred Brooks said, when solving a new problem teams should design a throw-away system first, because you're going to throw the first one out anyway. (See also: Annie Lamott's "Shitty First Drafts")

    It's not easy to see your own failings, but looking around some common ones that others demonstrate include a resistance to learning skills that are not core to the "purpose" of a course (the purpose being debatable—I've been at enough colleges to know that what's on the final is a small fraction of what a student needs to learn), stubbornness about one particular approach (kill your darlings!), not being able to listen to others at all, not telling others what you're doing because it's obvious to you, not giving people the benefit of the doubt… to some small extent each of these has manifested in my time here, and I'm on the lookout for those times when I, myself, am guilty of these. Small sins can be hard to see.

    It was a good day, overall. I love the people here, but the difference in energy level between a good day an an average day is really noticeable. Still, every day so far has been far better than any day of work or school until this point.

  • Week 1 Day 5 - Painted into a corner

    Today's partner: Connie

    It's a bit of a challenge to reconstruct my memory of Friday after I failed to save my draft Friday evening, so excuse this entry for being perhaps a bit vague. Also, I'm going to speak in the tense I would have had I completed this entry Friday.

    Today was the first day where there wasn't enough work to actually fill out the day. We had two main projects: a small class that built trees of moves for a Knight navigating a chessboard in order to find the shortest possible route between two points via knight's moves, and a Tic-Tac-Toe solving AI (on top of a couple small vignettes). Of course, the point of the AI wasn't to show any great details about AIs; rather, we were working more on Object Oriented programming, data structures, and algorithms.

    These algorithms can broadly be called "paint bucket", or "flood fill" algorithms: starting at a point, do some action to all the "neighbors" (keep in mind that a knight's neighbors on a chessboard are moves of 1,2 away, and not adjacent squares - one of those mathematical things where you have to keep in mind the context you're dealing with), and then repeat for the neighbor's neighbors, ad nauseam until there are no more valid spaces to apply the action.

    Doing this sort of naive AI over and over has certainly helped drive home how to best write recursive OO code to do breadth-first search in different contexts, with different types of objects, but again we're not making contest-winning AIs here.

    Our biggest problem today was a weird edge case bug in the TTT AI. The spec was a bit hard to read, and once we nuked the half-dozen syntax errors in our collected source files, we found the logic as stated in English in the instructions to be a bit vague on what the various parameters means and how to pass them around. It took the better part of an hour or more to vary the code and make the lynchpin methods work properly, but once we got those right, the tests all passed without a hitch, and it was glorious.

    Of course, at that point, we only had an hour left to work. Without a bonus problem to chew on, there wasn't much to be done except to dip our toes into this weekend's reading and talk about the course as a whole. I showed my partner a couple resources I had seen on using git, which I hope she found valuable, and then just chatted about stuff. I know I'll pay for it this weekend in terms of worktime lost, but sometimes you just need a break, you know?

  • What's this about?

    I'm using this tumblr to keep a couple people up-to-date on my doings and not only for assignments, so I thought I'd offer an overview of what the program's about.

    It is, of course, twelve weeks long. The first nine weeks are mainly curriculum, followed by three weeks of project development—looking at what the previous cycle is doing, this consists of cloning the functionality of another public website as an proof of skills. I don't think most people choose to make a novel project (it's easier to solve a solved problem), but I don't know whether it's banned per se.

    As for the "curriculum", it consists of a couple languages in a sequence that ramps up in relevance to web design. So, to start, we're using Ruby to script basic stuff—algorithms, data structures, the fundamentals of programmatic thinking, that sort of thing—and then add in other elements, like JavaScript, SQL databases, CSS for visual design, and so forth. I haven't looked at the elements of the curriculum for a bit because I'm trying to stay focused on the here and now for the time being, but it's basically web development from end to end, from core scripting to design.

    Of course, one part of the program is blogging your reflections on a public tumblr. My alumnus friend tells me that the only people who will be interested in most of this will be fellow students, but I try to cover enough other topics that maybe others will want to read about my time in aA.

    Central to the instruction methodology is a working strategy called Pair Programming. How this works is a single computer is hooked to two monitors, and one person controls the keyboard and mouse, while the other talks about their thought process and, almost but not quite, tells the other person word-by-word how to get through the problem.

    In practice what ends up happening is one of a couple things. First and most ideal, the pair is matched well, at which point you can easily forget who's actually in charge at any given moment—it feels like the executive portion of your brain is the other person, and you become the mechanical/error checking portion, or vice-versa.

    Second, there's a close disparity, or a symmetrical disparity—A knows something B doesn't, and maybe B knows things A doesn't. My pet peeve is people doing motion commands multiple times, so I am constantly teaching my partners motion commands (delete line is ctrl-shift-K, select line is cmd-L, etc.). I don't restrict myself to this sort of thing—I've been spotting a lot of errors and edge cases while driving, which I don't do as much when navigating because I'm thinking of the overall strategy. It's sort of like the source of the analogy—the navigator in a car doesn't tell the driver how to pass or avoid an accident, but s/he does make damned sure the driver doesn't pass their exit.

    My perennial weakness is syntax specifics; I don't bother spending a lot of brainpower memorizing the syntax of every command when the reference material is right there. What I have spent time on, by contrast, is understanding what the elements of the function signatures in the documentation are, so I can quickly parse and interpret what sorts of things a function is capable of, and what sorts of things it returns. I'd like to think I'm helping others learn how to do these things with greater facility.

    Third and most rarely, one person is completely clueless and is basically told by the driver what to tell them ("okay, so how are we going to solve this problem? What search algorithm should we use?"), and then when they're the driver, they're simply a glorified typist. I think this is why Pair Programming often gets a bad rap—in organizations with programmers of vastly different skill levels, you won't always have two people who can pair well.

    One of the advantages that you'll see regardless is that, as long as one person isn't a complete pushover, the pair will produce cleaner, more readable code, and each person will come away knowing more than when they started, either about programming and problem solving, or about communication and education.

    The office, on Cooper Square, is relatively compact and a bit on the old side. It's not all glitz and glamour; it's functional, in a building that could really benefit from a bit of TLC from a motivated DIYer. The local shopping options, especially for food, are amazing—it's going to be hard not burning through my savings by going out to eat every day, especially because some of the best conversations happen at lunch when everyone has a chance to relax—and it's nice and central to a lot of people and train lines.

    We only use the school's computers, not our own. I guess previous cycles had mechanisms for students to bring their own computers, but there are logistical problems with that, especially when it comes to supporting non-default install environments and version conflicts. Further, we all use the same editor to work—Atom, by the same people who make the git version control system (ed: this isn't true; it's made by the github people)—which is a good editor, but not great, out of the box. One advantage to learning Atom is that, in time, you can add plugins to do almost anything any other editor does, but it can be quite frustrating not having some of the more clever IDE shortcuts available by default (TextMate's "Command-enter autocompletes a function signature" is one I miss almost daily.)

    One thing I'm noticing is that if you learn Unix shortcuts, specifically readline mode's motion and deletion commands, and the shortcuts for a single editor, most of the other editors out there will support the same shortcuts. So really, the learning curve to switching to Sublime or TextMate after using Atom should be quite low. Atom does file browsing better than TextMate, so even though I bought the latter, I am considering just sticking with Atom. (If you don't understand, navigating the file hierarchy of a big project can be quite a pain in the ass with bad tools.)

    Their current stats are 98% of grads are hired within a certain timeframe for a median salary of $84,000 (in NYC). This is promising, because I run out of money mid-March :)

  • Tumblr usability nightmare

    Did you know that the stupid damn button in the bottom left isn't actually a button, it's a "menu-button" ? Meaning, that you have to click it to select its mode, and then fucking click it to execute… WTF ARE YOU DOING, TUMBLR? WHERE THE HELL IS THE POST I SPENT THE PAST HALF HOUR DRAFTING?

    Yahoo!, and UI fails, can go diaf.

  • Week 1 Day 4 - Applied telepathy

    Today's partner: Michael C. (since there are two)

    I think I adapt to things within three days. Today just felt normal, like what I should be doing with my life. I know it's going to get much harder before we finish, and I keep pushing things onto the stack to go into more depth on over the weekend—but there is already plenty to keep me busy. Life's going to be tough enough on its own, and I should probably be getting up early Saturday morning and diving right in. I may have to work remotely to get away from distractions (although this hasn't been as big a problem as I might have thought - Facebook and reddit just aren't very interesting to me now that I have a stack of things to think about).

    I am still not getting enough sleep, and it doesn't seem to actually affect my engagement or 'awareness' during the day. It's an awesome feeling.

    The highlights of the day were working with procs and, again, the big projects toward the end of the day. We were wrestling with understanding how to write our own versions of a couple Enumerable class methods (my_each, my_select, etc) but the breakthrough on this matter came when we tried to express the same things in "normal" ruby code and then translated that work into our functions.

    For instance, normally, to double all elements in an array, you might write

    1
    
    array.map { |i| i * 2 }
    

    When defining your own function to receive that proc, you can start with something done in the standard ruby function calls:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    def my_map(&prc)
      result = []
    
      self.each do |item|
        result << prc.call(item)
      end
    
      result
    end
    

    Simply replace "each" with "my_each" and you've basically re-created standard ruby functionality. I assume that, even if it's not now written this way, at some point the ruby "standard library" looked something like this (albeit with more error handling).

    My partner mentioned at the beginning of the day that he didn't really understand why you'd use procs, and within a half hour we both got it.

    The work on recursion was solid practice. The first example took ten minutes, the second five, and each one after was simply an exercise in analyzing the higher-level problem. Satisfying, and excellent practice/pedagogy, but nothing earth-shattering. :)

    make_change, the recursive method for taking a list of coin values (for instance, in the US, 25, 10, 5, and 1 for quarters, dimes, nickels, and pennies) as well as an amount that you're trying to target and yielding the list of coins you'd return in order to make the target amount with the minimum number of coins, was easy, then absolutely maddening. We managed to describe the core logic within a half hour - about one line every 90 seconds, go figure - and then took another half hour in order to track down a crazy edge-case bug that was killing most of our results.

    Constance looked at our code for a good ten minutes before we nailed down what was actually going wrong. We had a specific test case that broke the method quickly, a bunch of ghetto debug statements (p for the win!) and basically total awareness about the state of the internal variables, and we still struggled to find what was causing this failure.

    It turned out that there was a loop condition that this edge case was falling through, returning nil when our calling function was expecting an array. It was such a specific edge case that I should have seen earlier, but I kept looking in the wrong places for this, and the doubt caused by that sort of weakened my learning. I spent five minutes doubting each level of my knowledge, until finally I was doubting whether < actually means "less than". I'll definitely need more practice overall, and to develop more facility with debugger… and I've gained some specific respect for the challenges software maintainers face every day.

    WordChainer, today's "capstone", was a blast. The spec was thorough, and my partner and I basically spent fifteen minutes reading sections of it to one another and getting code into the editor. What a delight a properly detailed spec is! Too bad I'll probably never see one again in my life, unless I write it myself! ;)

    It took us about two hours to get a very respectable and pretty clean class for this portion, overshooting the end of class by a half hour. Remarkably, by the last hour, I wasn't sure which one of us was actually driving or navigating. Michael and I were basically on a single wavelength, and passing the keyboard back and forth was mostly a formality.

  • Week 1 Day 3 - The time machine

    Today's partner: Louie

    Today was much shorter, mentally, than the previous days. We had two blocks of programming to do—Mastermind, which I've written in J before and which we mostly knocked out before lunch—and Hangman, which was actually quite a bit more interesting than I expected.

    I have to take a moment to say how lucky I got with my partners the first two days. Day 1, I learned quite a few tricks, and day 2 I felt like I was really getting used to a writing in a clean style with my partner. By the start of the day today, I felt really ready to build a clean framework for our code and create some really concise, effective methods to solve bite-sized problems.

    Listening to some other groups and reading some of the other tumblr blogs, I can tell that not all groups had such an easy time. Louie and I, though, really found it pretty easy to set out in a direction and digest one task at a time without worrying about the larger scope.

    There haven't been any huge surprises on the code end. Still solidifying a lot of the tricks to make code work well—the big ones today were different function signatures for creating objects and playing with Enumerable methods, such as Hash.new(0) versus Hash.new{ |h,k| h[k] = [] } or the different ways to call an inject method. Today was much more evolutionary than revolutionary.

  • Week 1 Day 2: The only winning move is not to play

    Today's partner: Zach

    Well, we didn't write Global Thermonuclear War today, but we did write a tic-tac-toe game, and the way we set it up we were able to have the computer play against itself. Fitting.

    First, meta-stuff: Not having caffeine in the morning is brutal. I need to leave the house a half hour earlier in order to make sure I can hit the coffee place before 8:45. I'm thinking it will probably be a good idea to get to aA around 8:00—first, to avoid peak commuting hours, and second to be able to settle in and find my bearings and re-read the day's assignments before class starts.

    I still haven't settled into the apartment, which is just killer. Every night this week, I've come home and there's been another issue (tonight, the cable company un-provisioned my router. Yay). If I were talking to a student who was accepted to aA but hadn't started yet, I would suggest they leave at least a week (preferably two) between the end of their previous job/the beginning of their lease and the beginning of the program. I have a workspace set up at home, but not much else—I haven't even had time to get groceries, which is playing havoc with my blood sugar.

    Because the progress page was down last night, we got started 20 minutes late (hence my lack of progress report for yesterday—by the time I signed in today, the report was locked out), and in turn lunch started at 12:45. With no coffee and limited breakfast this morning, and my partner in a similar condition, we were struggling all the way to lunch. We progressed at about half the speed we should have been because our brains just weren't cooperating: we were dropping state and getting destroyed by simple tasks all morning.

    The period after lunch was a completely different story. With a full belly and an equatorial nation's worth of caffeine streaming through my system, I was on point from 2 pm until 7. Much different than yesterday!

    So, lessons learned: do everything you need to to get ready for the course well in advance, so you have no other concerns distracting you; eat breakfast every day; make sure you have what you need (i.e. coffee) to stay focused; get plenty of sleep every night… and I'm sure I'll want to be exercising regularly in a bit here. I can see all this focus on eating to maintain energy being a big blow to my health in even the medium term.

    I think my life is going to get very regimented out of necessity.

    As for the coding: I kind of appreciated that we didn't see much of the instructors today. We sat down, logged in, had our little lecture until 10:20 (Sennacy is a good name for a cat, it seems), and then just worked.

    It's a revelation, really: pair programming continues to be amazing, and I can't say I understand the ire it draws in certain corners on the 'webs. Having a partner with you makes sure you're not going down a rabbit hole of stupid, allows you to rubber duck constantly, and helps you circumvent really stupid errors, like forgetting that you named your instance variable @foos and not @foo.

    I can't even really say what we worked on, for the most part. I have it all here beside me, but Tic-Tac-Toe was the part of the day I was most focused on and for, and the rest of the assignments are just a bunch of tiny vignettes in retrospect. I know more than I did this morning, but it's the kind of thing where I don't know if I'll be able to look back and point to a certain moment that I learned X.

    Certainly, I've been filling in a ton of details in how the language behaves, and sharing what I've learned from one person with the next partner, but it's already disappearing into the background in favor of high-level design principles.

    The readings on coding style were really good, and one topic that I'm sure made an impact. There's a world of difference between my coding style from a week ago and my coding style today, and in six months I'm sure I'll think me today is total crap. Breaking functions into really small chunks and treating DRY as religious dogma has turned my coding style on its head. It physically pains me when I can't figure out a way to get a function under 20 lines, and when the best way to solve a problem appears to be a five-position case statement I want to cry (a little bit).

    I've had a lot of thoughts on pedagogy related to the course, but I'm still kind of digesting them and waiting to put them together in a separate post. Maybe over the weekend.

  • w1d1 addendum

    The most notable moment in the day was when my partner and I were elbows-deep in a particularly tricky algorithm, and the instructor came along to look over our shoulders, and we were so engaged with what we were doing we basically didn't have time for him. When 6:00 pm rolled around, we actually kept going to try to work out some last kinks in the program before admitting that we were just too exhausted.

  • Week 1 Day 1

    Today's partner: Cihangir

    So. Good stuff.

    It's been busy this week, which isn't germane to the appAcademy experience per se, but has certainly made it more interesting. Getting situated close to campus and investing in a good working space was a great idea because it's rapidly become clear that there will be. no. time. for anything else the next twelve weeks.

    In preparation for this course, I spoke with a alumnus friend, and mentioned that this is my time to really focus on something. I think the next two or three years are just going to be a constant push to improve, and it all starts here, in twelve weeks of pushing myself as much as possible.

    I tend to reflect a lot on how things run, and I don't mean to come off as negative, but I try to see the good and the bad. I don't expect anyone skimming this tumblr will come so far down that they'll see this disclaimer, but basically I don't generally whitewash things, but when I say something positive you can be pretty sure i mean it.

    In no particular order, then:

    • The whole experience so far has felt bootstrapped. Like, everyone is so concerned with making the best possible programmers with the most recent technology and the least possible overhead that sometimes things break. The facility is nowhere near as polished as I expected—for comparison, I've visited General Assembly in New York and they seemed clean but sterile. An acquaintance is starting their bootcamp in a week, and I'm curious if their polish comes at the cost of some flexibility.
    • Random errors: the appacademy.io DNS entry was invalid for a day a couple weeks ago. The progress tracker is down now. Before I tried refreshing it, it was showing that I have a fine for coming in late to class tomorrow. What.
    • Everyone is super positive and super excited to be there, or at least we're all faking it really well. :)
    • I have never been so tired from working. Day one, where most of the material is review from the course prepwork, felt like the roughest study session I ever had in college times two, no joke. My brain doesn't hurt the way it did when I had to take a math test for a class I wasn't prepared for in a language I was just beginning to understand (long story), but by 4:30 I was just drained. I'm going to have to invest in blood glucose—snacks to keep in a cubby, coffee (with sugar?), juice, something, to get through the afternoons, but even this might not be enough.
    • Pair programming is intense, in a super good way. Especially in the morning when we were fresh, I felt like my partner and I were really getting a lot out of it. He was really practiced in a lot of the nuance of some of the commands, whereas I rely much more on the documentation and learning as I go. I was able to offer I think some expertise in the choice and use of algorithms, which means that we balanced each other out in a lot of ways.
    • I do wonder what the coming days will be like. Again, my partner seemed really sharp, and I wonder if that's typical of the quality of the students here. I joke (but not really) that 90% of Harvard's work educating students is done by the time they get through the admissions process, but I do wonder how true that is at aA. If my partner is a typical student… man, they run a tight ship. And the students at the cusp of admission must just be above average ;)

    All in all, it was a productive day. There's almost too much to process in one go, so I'm just letting it all sink in and not stressing too much. I figure things will just click into place in time as long as I keep pushing.

    I'm really not sure what these things are supposed to feel like or if there's a length requirement, so that's all for now.

< prev 18 Nov 2014 to 11 Nov 2014 next >