Week 7 in Review

Didn't get anything (app-wise) presentable to the world out this week. However, I did finish off a bunch of loose-ends at my freelance jobs and such, so I'm feeling pretty good about that. Just a quick round-up. I'll have a longer blog post about other topics soon.

  • made a lot of changes to the library site code... mostly refactorings, but also fixed some bugs
  • another freelance project is coming to the end; it feels good to be in the home stretch
  • SaaS - no homework this week, just a pretty extensive quiz that I didn't do very good on. The topic is design patterns, and I feel like it would be better as a homework assignment so we could actually practice them rather than quiz questions, because patterns are already such abstract concepts, it's hard to answer questions about them without tying them to a real app. I had a lot of trouble with the wording and terminology of many of the questions. I feel like I understood the concepts pretty well, but the wording always gets me to pick the wrong thing. But the bigger picture, that of design patterns, was still very useful, and is one area that I'll need to get better at (both recognizing when to use them and actually implementing them well)
  • My resume. I'm still working on my portfolio site when I can find a spare second, but until it's done this resume will be my face on the job market. It was made in JSON Resume (an open source solution). Fellow #codenewbie Jonathan told me about it, and it's really saved me a lot of time by separating the presentation layer from the content (which is coded in JSON).
  • Rails API + Ember - I worked on following this tutorial which is pretty straight forward, although probably not written for Rails newbies. There were a few things it did where I felt happy that it worked without knowing why it worked. Going back over it, I feel like I understand the main concepts well, but the details would be hard to reproduce in another app without following each step over again.
  • I started a #codenewbie Code Club on making pull requests. Code Club is a great one-hour study session where we tackle a problem (doing a pull request in this case) and teach each other. We went through this helpful article on doing pull requests as well as putting what it said into practice on my Exquisite Source repo on github.

Drop some knowledge!



I was working on my portfolio site last week and playing with the parallax effect when I had the idea of making a CSS shadow that moved as you scrolled to create the illusion of depth and a single source of light (imagine holding the light in front of your monitor and casting a shadow on your divs). Had this effect ever been made into a script? To my surprise, there were very few scripts out there that did this. So I decided to try it on Codepen. It only took me about half an hour to do. I went through several other variations since then, but the basic idea is the same.

The next morning, I couldn't stop thinking about how awesome it would be if I could make it into a plugin. It could be my very first contribution to open source that people would actually use (because let's not kid ourselves, nobody's actually going to use my todo app! haha).

So I started reading about JQuery plugins to see what I'd have to do to my code to make it into a pluggable part that people can just include. I also wanted it to be easily customizable. People can just use data-attributes on their div tags to change the properties of the shadow, how much it blurred, how fast it moved, etc. I definitely didn't want them to have to change my script in order to change the options. It should be like a function, you pass it arguments, and it did its thing.

Making my half hour script into a flexible plugin turned out to take me much longer than writing the basic script itself. But it was a great exercise in writing modifiable code! I had to think a lot about encapsulation and keeping variables inside the plugin separate from everything external. Finally, I had to create a pretty page to show off the capabilities of my plugin. Go visit it now! And let me know if you find it useful.

Future improvements (maybe):

  • text shadows!
  • maybe the blur value can change as you scroll as well?

Drop some knowledge!

Week 6: Unexpected!

Last week was all about being overwhelmed. This week was all about the unexpected.

  • SaaS homework: I did not expect to spend 15 hours (more if you count the fact that I spent another 3 hours refactoring after I was done) on this assignment. It's definitely the most involved homework assignment so far (although there were a few in SaaS 1 that were pretty difficult too). I won't go into it in detail here because I already wrote a blogpost about it.
  • Exquisite Source: I did not expect to write this. But I got inspired by an article on pull requests! And it was a very simple non-ambitious project technically speaking... with a (perhaps too) ambitious idea behind it. So we'll see if it takes off. Hopefully it helps someone. If it doesn't, it was only a couple hours of pretty fun work.
  • My first JQuery plugin? I will write a separate blog post about this soon. But umm... I wrote a JQuery plugin! And it's open source. And it was the last thing I expected to do this week, but I just got caught up in a very small idea that I thought others could re-use. More soon.

Drop some knowledge!

Introducing Exquisite Source!

I had an idea this morning while reading about pull requests: why not have a sandbox-like environment just for people to practice doing pull requests without the fear of messing anything up? And while we're at it, why not make it into a surrealist game, to see what kind of crazy franken-art will come out?

So I went ahead and made it a reality. Introducing Exquisite Source! Please have a look around and make your first pull request!

exquisite source screenshot

Drop some knowledge!

SaaS Legacy Homework 2: Lessons Learned

This week's SaaS homework has been the most elaborate so far. As the instructors explain in the lectures, after teaching the class for a while, they asked some of the top software companies what one thing they wish graduates of computer science programs would learn before entering the workforce. The overwhelming answer was "how to work with legacy code". So even though at first they had no idea how to teach this, they set out to do so in this class. And thus we have legacy homework 1 and 2 (last week and this week).

Instead of working on a new custom app, we are given an existing app (the Typo blog platform) that has a long history, sometimes messy code, and spotty test coverage. Last week we were asked to fix a bug in it. This week, we had to add a new feature!

Our feature in a nutshell: add the ability to merge two articles into one. The body of the new article will be a concatenation of the two previous articles. The title and author will be from one of the two articles. And the comments of all previous articles (if any) will now be comments of this article. Only administrators can merge articles. All other users will not see the option at all.

picture of what the typo merge feature should look like

I spent a LONG time on this homework. Around 15 hours. The hardest part was writing the tests. That shouldn't be a surprise because writing the test is always the hardest part for me! I am still very new to Rspec and TestUnit syntax, and spend so long trying to figure out exactly how to phrase things. But I'm proud to say that I stuck to it this time and wrote all the tests before writing the actual code (except for the view and some skeleton methods so it didn't throw method-not-found errors--basically I had to get it to the point where the tests failed for the right reasons and not because it couldn't find some method).

First I wrote the Cucumber integration tests for the happy path only. Then I wrote the unit test for the controller. It was at this time that I realized I was planning to put way too much logic in the controller. So instead of putting all the tests there, I just wrote a few to make sure the controller was asking the model for that information. Then I had to write a bunch of unit tests for the model. At last I allowed myself to write some actual code, which didn't take long.

Then at the very end I wrote the cucumber integration tests for the sad paths. The one thing that was SUPER helpful was using the debugger gem and plain old rails console (with the --sandbox option) while writing the tests, because it helped me figure out exactly how to get to certain elements in order to test them.

Even though I could have knocked out the homework in probably less than half the time without testing, I really liked the practice. It was hard but satisfying. There isn't a more satisfying and empowering feeling than when you can get all your tests passing AND you haven't even looked at your app in the browser yet with your own eyeballs... but you know it's working! This is so different than the way I used to program.

I also feel like testing frees up my brain from worrying about every little bit of my application. If what I'm doing now will break something else, then I'll know about it soon enough (if I wrote my tests right). So all I have to do now is concentrate on writing whatever little bit I'm working on now, instead of trying to keep the entire app in my head and worry about not breaking anything else.

A few SPECIFIC things I learned:

  • in the controller, the redirect_to method does not redirect immediately. The rest of your method will continue running unless you specifically say "return" after redirecting
  • if you want to redirect inside of a helper method (instead of a main controller action), then set that helper method as a before_filter of your main action method or else it won't redirect (return will just return to your main action method which will continue running)
  • when using Capybara to find the xpath of an input element with a certain id=“name”, use 'input[@id=“name”]' rather than 'input#name'
  • use text_field_tag to create a simple input element with a normal name like merge_with.. I was trying to use the text_field helper method and it kept making names like "merge[with]". This is because text_field is "tailored for accessing a specified attribute (identified by method) on an object assigned to the template" -- so it's really good if you want to create input fields that correspond to your model, but if not, then it may be too complicated for your needs
  • use "tables" to set up a bunch of values in Cucumber. I've used them in previous apps but they always seemed like a mystery to me. But this time I played around with them in the debugger gem. You can find out more here.
  • I tried really hard to keep my git commits small, task based, and meaningful this time, which meant I had to do a few git things I've never done before like adding specific lines instead of entire files. I really like the idea of my git history telling the story of my code. And also having the ability to revert any single change without messing anything else up.
  • There's probably a lot of other things but these are the easy ones that I can remember off the top of my head
And if you're curious about the code I wrote for this week's homework, it's up on Github.

Drop some knowledge!