Posts from November 2014
Today's partner: Ed
Today was our first exposure to Real Rails™. We delved into ActiveRecord and creating relations between our created classes and their associated tables (created via migrations).
Setup is pretty straightforward: specify your database during creation, or edit the .yml file to specify your database because you're dumb and forgot to throw rails the configuration option, then get to writing migrations. It's clear that rails is designed around a fast iteration cycle, either Agile or TDD, because just about every action has an easy way to build up, reload, or rollback.
But that's not really what today was about. Today was about trudging though a lot of examples of the most basic Rails structures, which are superficially similar to their SQL roots and the code that's created when you create raw SQL glued together with Ruby. It's certainly nice, and we learned a lot about the basics of Rails, but it felt kind of like a slog because it never went much of anywhere… yet.
So this weekend, I'm going to try to re-read Hartl's tutorial alongside the pre-readings for next week to try to build some excitement for what Rails can do. I know it's powerful, but I don't feel it yet.
Is it sad that one of the highlights of my night is when the clock rolls over to midnight and I get to sneak a peek at who I'll be working with the following day?
I've completed the readings for tomorrow. I don't understand anything, except that I've added a data point: the higher the level of abstraction, and the less repetition you have, the more confusing a "simple introduction" will be.
I think learning Rails will be aided by having a large bottle of something strong. Thankfully, I picked up a handle of Jim Beam. Me and Jim are going to pair program the fuck out of some Active Records this weekend.
Today's partner: Michael D.
Unpacking, since I can't actually remember what we did today:
I know this isn't the point of appAcademy, but today was the most fun I've had since we started. Michael and I were cracking up about mistakes and ruby/SQL absurdities all day.
Yeah, so we were doing something with SQL… I thought populating the test database would be more onerous than it was, but really it was a couple
INSERTprocedures copied over and over.
Oh, I remember now… so we made basically a tiny reddit clone, using database accesses on an SQLite3 instance. By reddit clone, I mean a class structure with Posts, Users, and Comment trees (
Replys), where we had to write procedures to translate between stored and active objects. It was very educational, but similar to yesterday in that it was a straight walk through the instructions, implementing some calls that were well within our understanding of SQL and Ruby. Certainly nothing earth shattering, but the practice was good.
In not quite unrelated news, I've been meaning to get my financials in a format I can actually do something with… I think I have just enough tools to start doing something interesting with my data. A CSV parser, an SQLite3 instance, and a lot of ruby code, and I could probably do some pretty damned cool stuff :)
Today's partner: Justin
A good day. The assessment started out okay: I got through 90% of the coding in under 30 minutes… then I choked and couldn't scrape together enough bugfixes to make the last test pass before time was called. After crushing the practice assessment over the weekend, it was a bit weird to have such a turn of events this morning, but it just makes it clear that I need to continue practicing: ruby, rspec, and whatever else we're going to be learning. It needs to come easy, and I need to triumph over my demons of both attention, and attention to detail. (Did you know '8' is different than
:eight? Crazy! Crazy eights!)
So I have to do a three-line bug fix and re-submit before 9:00 to get that last point. Hooray?
It's telling that by noon, no one was talking about the assessment anymore. SQL was quite the leap for just about everyone, and even though when I listened around it seemed like we were all on the exact. same. exercise at each moment, it turns out there was a lot of hair-pulling and gnashing of teeth at other tables.
My partner and I didn't have any particularly noteworthy trouble, but there were some hairy
JOINs that took a bit of digesting to grasp. Again, I know that I don't understand SQL completely yet - sometimes it feels like a matrix language, with all the associated transformations; sometimes it feels like a procedural language full of loops—but I can guess out what a statement is going to do if I can access the schema. So, hooray.
I'm actually really excited about tomorrow's SQLite lesson. I keep hearing about SQLite in desktop and mobile app development, and now that SQL doesn't seem such an impenetrable barrier, if I get the hang of things tomorrow, I could theoretically look into learning Obj-C or Swift at some point and actually start making money off development ;)
That is all.
Today's partner: Ron
All the coffee in the world could barely get me through this week. It was fine, in the end; there's been a much more relaxed feeling on the two Fridays we've had so far. (We're 16% through the program already. What the hell.)
Most of the day was about rspec, the main ruby testing framework. It's actually a really nice language: a language for pedantic testing, by pedantic testers. Tommy joked/not joking that they re-write major portions of the syntax every 3-4 months, and I can totally believe it. When you're as steeped in the mindset of testing software as they have to be, your inclination has got to be to make your domain-specific language as polished as you can.
I do wonder what their internal unit tests look like, though.
Other than endless coffee and jokes about writing a test that you yourself are going to be taking, the day/language were interesting. I really like the rspec syntax; once you get used to the grammar, it's actually quite clear to read. It took a mere two hours last night to be able to figure out all I needed to understand to complete the practice assessment. As hard as it was, I got the impression that I understood a bit more this morning than a lot of the other students, so maybe I'm primed to be thinking in the way that the rspec designers do.
We skipped through the practice exercises, basically doing just enough coverage to make sure we were getting the point. We could tell how much clearer it makes problem solving: break something down into discrete parts, then figure out where those parts should live and how they should interact, and 90% of the hardest work is behind you. I really look forward to using the TDD methodology on a more robust project; it's quite clear that, like so many other student projects, the power of the tool we learned today far exceeds the significance of the work we were doing. It's basically like using a sledgehammer to drive a nail into drywall.
A couple things I put together today:
No one I've worked with or talked to so far has nearly the level of paranoia about breaking things that I do. I think Bruce Schneier is right that the security mindset is probably something you mostly can't train.
As I've mentioned, this also makes me a bit overcautious. It might behoove me to look for employers than want careful, deliberate work done, or to force myself to make fast, dumb code, and refactor much faster than I do.
All of a sudden today, I understood what all the comments that I've read about "unit tests" and "integration tests" meant. There was a total "aha" moment when we were talking about mocks where I was like, duh, of course that's a thing, and now the difference between these other things makes perfect sense. Maybe I hadn't thought about it before?
It's ridiculously easy to write code when you are writing tests alongside.
There's a bit of weirdness to crashing your testing framework because of a syntax error. "Okay, which one crashed, and why? Oh, we messed up that syntax, lololol"
It's so much cheaper to make coffee at work, EVEN if you're making coffee for everyone else, too. If I leave the money in the can, I've still come out ahead.
Hoo boy. I can feel stuff stacking up.
Checkers was basically a repeat of chess, but simpler. I thought I had learned a lot, but today was a real learning day.
For background: it was our first solo day, and without anyone next to me who was depending on me to drive/navigate, I was somewhat slow to sink my teeth into the project. I thought I was sticking to the spec, but I spent a long time running off on tangents, trying to get minor methods to do what I needed in order to be able to get printable output as quickly as possible.
This was a mistake.
I've come to suspect that my working memory isn't great, and that that's why I try to recursively abstract problems—I can only manage 5 +/- 1 ideas at a time, and the more high order the chunks are, the bigger the idea I can digest.
So when it comes to seeing how different parts of a multi-class project will fit together, I miss things that become both obvious and painful a couple hours in. (Debugging complex interactions in similarly challenging for essentially the same reason.)
Today's big pain: I misread the spec, in a way. There are basically three general ways to send moves around the core class of the checkers project: as positions ([1,1] to [2,2]), as differences from a starting position (start, [+1,+1]), or as some general class of methods I will refer to by the technical term "totally effing stupid".
Yesterday we generated moves early, and only passed moves around. That worked well; we had a simple wrapper on the class that translated algebraic notation ("b3" = [2,3] = [1,2] in 0 indexed arrays) to the position references we were using, and then we only passed those around.
Today, because I misread things, I started out passing around differences, then I realized that I needed moves, then I tried to simplify things using one of the last methods, and that was, predictably, totally effing stupid.
I got a lot working, but my errors weren't working right on certain literal edge cases, and finally I threw in the towel at 9.
- When doing solo work, pseudocode flowcharting might be necessary for someone like me to avoid super-dumb mistakes
- I need to rubber-duck, either with a human, or with a rubber duck. I think I'm going to put my plush octopus next to the home computer. She needs a name, though, so I can talk to her properly. (Completely serious, by the way.)
- If I'm going to rubber duck on solo work, I need to not be in a place where I'm going to be self-conscious doing so
There's more, I'm sure, but I have a ton of readings to do before 2 am, god willing.
"Am I the one who holds good pairs back?"
Today's partner: Anthony
A cold day in NYC.
Getting more used to the schedule: even though I woke up a bit later than I prefer this morning, I knew what I needed to do to get out of the house and get fed before class, and I knew what we needed to do when I arrived. Coffee was brewed all day, we did our work, the breaks went well… this program is pretty cool.
There's still more to be done with chess, but I have to say that we got to a really good place today. We have a really clean codebase that could be hardened a bit, but the code is about as organized and modular as it needs to be.
I'm mostly done with chess; everything that's left is polish on a solid core. Don't get me wrong - it's good - but there's not a lot of marginal learning value left on this topic. The remainder of the work is the programming equivalent of going to the gym once you've hit your target weight: good practice, but kind of rote and boring.
When I'm not so tired of it, I may come back, but I'd actually prefer to do something else. Perhaps look at the mazesolver/mazebuilder that I started skeletoning earlier this week: that should provide some interesting problem solving.
My partner and I worked well today. I was still domineering, sort of, because I didn't want to have to finish chess after class tonight, but he held his own. I hope he learned something from me and didn't hate working with me :)
… are naming things, cache invalidation, and off by one errors.
Today's partner: Anthony
Today was all Chess, all day.
Actually, that's a lie. We did cover error handling in lecture and did a couple exercises (for about ten minutes; we figured that we'd do a proof of concept, then implement more error handling in
chess.rb), but after about 10:30, we were coding the
Chessclass and its subclasses for about eight hours straight.
It went well, in my mind. My partner is learning buckets of things, and he's been a real sport in terms of letting me show him how to do things quicker in Atom, pry, and git. We've been sure to make our code readable as we work, and test as we go - what we have now is readable, functional, and succinct. This is the kind of code I can begin to be proud of; lesson learned from the past couple days.
Strangely, though, all this work results in about 300 lines of code, including whitespace… not a lot, right? Especially for the full-time output of two people. I'm sure that, in time, we'll be faster as a cohort, but this period is very focused on didactic activity: everyone has something to learn, if not from their partner, then from the code or documentation.
The primary virtue of the Chess project, I think, is to see how you can best handle exceptions1, and to see how important it is to have well-defined roles contained in well-defined source files. It also helps to gain experience with
gitin different contexts, but I appreciate the simplicity of git's cognitive model, because basic use demands very little cognitive overhead.
The office is moving over the weekend, to a more convenient location (for me) that is apparently about twice the size of the current place. Neat.
The coffee club is bootstrapping nicely; I'm going to send out a message to the group about a better ruleset.
I got three or four specific positive comments from people on various things I've tried to do to make people's lives easier. Feels good, man. (I mean, it's not why I do these things, but it's nice to know I'm not just emailing into the void.)
I wish I would have enough money to go out to lunch every day; some of the best conversations happen in the combinatoric randomness of lunch groupings.
Instead of looping over input until it's valid, like I might have done in TI-86 BASIC, you embed your calls in a