Bits on Bits on Bits

Using Multiple Chrome Profiles

One of the most beneficial changes I’ve made to my workflow in the past couple years is to use multiple profiles in chrome. Basically what this does is allow you to run chrome for multiple users at the same time.

You may be thinking, “Ok, that’s kind of nice – but I can already sign in to different gmail accounts within the same browser window. So what does this really buy me?” The real advantage to maintaining these profiles is that each profile gives you a separate, isolated chrome environment. That means that all of your bookmarks, history, chrome extensions, saved usernames, etc. all stay within the context of one profile.

As a developer, this is a godsend. I can have one profile linked to my personal email, and one linked to my work email. The work one has an uncluttered list of bookmarks that only pertain to work, remembers my test account usernames, only uses extensions that are relevant to work, and doesn’t auto-typeahead to sites like ‘Pandora’ when I am keying in a url.

Really what you’re doing by setting up multiple profiles is separating your concerns for how your browser experience is organized. By just having one chrome profile, it’s easy for browser data to get out of hand – especially with regard to having too many bookmarks and extensions. Adopting multiple profiles allows you to keep what’s most relevant at hand, without having to open different browsers at the same time.

D3 Lessons Learned: Hover Lock Button

As an exercise in sharpening my d3 skills, I set out to create a button that mimics the kudos widget seen on various blogs.

The idea is to only take action once a user has hovered over the icon for a certain period of time. It’s a nice, animated alternative to simply clicking a ‘Like’ button. Here’s how my version turned out:

You can see the full source code and example here.

Though this example may seem trivial, there are a couple of important principles it demonstrates:

Svg Element Ordering

The z-index css property is ineffective for svg’s. Instead, layers are rendered in the order they are drawn – elements drawn first appear behind elements drawn afterward.

So for my example, drawing the circles goes as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  outerCircle = svg.append('circle')
      .attr('class', 'locked-on-circle')
      .attr('cy', options.outerRadius)
      .attr('cx', options.outerRadius)
      .attr('r', options.outerRadius)
      .style('fill', options.defaultColor)

  whitespaceCircle = svg.append('circle')
      .attr('class', 'locked-on-circle')
      .attr('cy', options.outerRadius)
      .attr('cx', options.outerRadius)
      .attr('r', options.outerRadius - 5)
      .style('fill', '#FFFFFF');

  loadingCircle = svg.append('circle')
    .attr('r', options.startingRadius)
    .attr('cy', options.outerRadius)
    .attr('cx', options.outerRadius)
    .attr('fill', options.defaultColor);

Note that the outer ring is actually 2 circles: a larger one drawn first with a background color, and a slightly smaller white one drawn inside.

Animation Easing

You might have noticed that when you hover over the circles, the middle circle grows a little bit smaller before it gets bigger. The rate and size of this animation is controlled by its easing function.

In this example in particular, I’m using ease('back'). You can use different easing functions to make animations occur at different rates over time. For an excellent interactive demo of easing functions, check out this bl.ock.

Cancelling D3 Animations

If you begin hovering over the circle, but pull the cursor away from it the icon transitions back to its original size and color. Before working on this demo I wasn’t sure if I would have to call something like transition().cancel(), but it turns out that you can simply start a new animation to cancel an existing one.

So in my example, I’m using this animation to grow the middle circle when a user hovers over it:

1
2
3
4
5
6
loadingCircle
  .transition()
  .attr('fill', options.lockedColor)
  .attr('r', options.outerRadius - 10)
  .ease('back')
  .duration(1500)

And to cancel my animation on the mouseleave event, I simply transition back to the original size and color:

1
2
3
4
  loadingCircle
    .transition()
    .attr('r', 15)
    .attr('fill', options.defaultColor);

Animation Callbacks

The last trick I picked up was that animations have a callback which is triggered after they complete. Look at the end event here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  loadingCircle
    .transition()
    .attr('fill', options.lockedColor)
    .attr('r', options.outerRadius - 10)
    .ease('back')
    .duration(1500)
    .each('end', function () {
      isLocked = true;

      outerCircle
        .style('fill', options.lockedColor)

      $('.notification').fadeIn(500);
    });

The end event’s callback only gets executed if the animation completes. This plays out nicely in our example since we only want to display a “done” label if the user hovers for a certain amount of time.

D3 Training Wheels

I’ve been working with d3 quite a bit lately. It’s a subject I’ve been interested in for a while, but never had a passion project to really use it with until I had a project at work that required it. Putting this post together as a reference to some resources I wish I had known about when I first started.

D3 Gallery

Mike Bostock is the creator of d3 – and is basically a visualization god. This page on the d3 wiki is a collection of charts and graphs. It’s a great starting place to see exactly what’s possible, and most of the examples provide source code.

Dashing D3

This tutorial took me from zero to sixty with d3. It does an amazing job at organizing sections into consumable portions. Not only is it the best walkthrough of d3 I’ve come across to date, it’s also one of the best tutorials I’ve ever read, period.

Bl.ocks.org

Another creation from Mike Bostock. I discovered this site by seeing it frequently referenced on StackOverflow. What you do is create a github gist, apply the same path to bl.ocks.org, and the bl.ocks website will automagically display your visualization.

For example, Mike has created a gist at https://gist.github.com/mbostock/1353700. Since this gist has a file named index.html, bl.ocks is smart enough to display a preview of the visualization at http://bl.ocks.org/mbostock/1353700. (Note that /mbostock/1353700/ is the same in both urls.)

I prefer this to jsfiddle/codepen when dealing with d3 examples since it’s easier to read longer bits of code in the longform that bl.ocks displays them in. And because each example is a github gist under the covers, forking and modifying examples in my local dev environment is trivial.

Revisiting an Old Ruby Program

As an exercise in coding, I recently rewrote an old ruby program into a new one. Functionally the code for the new program does the exact same thing as the old one – both programs run simulations for the Monty Hall Problem. But the new one was written with the intention of being easier to read and DRY’er.

The original program was from when I was first learning ruby, and was definitely painful to read at times. Going straight down the program, here’s a self-critique of some of the code.

Complaint #1: lack of inline boolean expressions

This is supposed to read a command line argument, and set it to a boolean true if the argument is the string “true”:

1
show_details_option = false if show_details_option != "true"

The danger in this is that show_details_options would not be set at all if the if condition isn’t met. It doesn’t in this case since it was already initialized on the line before, but there’s no use in taking this risk if it’s perfectly avoidable.

My new version ditches the if statement altogether:

1
show_details = ARGV[1] == 'true'

Complaint #2: using and and or instead of && and ||

and and or are meant for flow control, not to be used as boolean operators.

What can I say? I was young, I was naive, I hadn’t read this blog post by Avdi Grimm.

Complaint #3: not using built in array methods

Example 1

Take this snippet:

1
2
3
4
5
6
possible_open_doors = []
for i in 1..total_number_of_doors
  if i != contestants_guess and i != number_of_door_with_car
    possible_open_doors << i
  end
end

The purpose of this was to build a new array from 1 to total_number_of_doors while excluding specific values, namely contestants_guess and possible_open_doors.

My approach was to build a brand new array, while checking to make sure the new values being appended to the new array were neither contestants_guess nor number_of_door_with_car. That works, but the same effect can be achieved much more concisely with some built in array functions in ruby. The refactored result is much shorter:

1
revealable_doors = (1..total_number_of_doors).to_a - [number_of_door_with_car, contestants_guess]

Note that you can convert a range into an array in ruby (eg – (1..4).to_a becomes [1, 2, 3, 4]). The array difference operator (aka array subtraction) allows us to easily exclude particular values. If I wanted to exclude 1 and 4 from the array of 4 I can say [1, 2, 3, 4] - [1, 4] – which seems trivial with hardcoded values but becomes handy with variable values which need to be excluded.

Example 2

Here I’m selecting a random value from an array:

1
possible_open_doors[rand(0..possible_open_doors.length - 1)]

When Array’s “sample” method already does precisely the same thing:

1
possible_open_doors.sample

Complaint #4: methods that took way too many lines of code

My original method used to run a simulation was 86 lines of code long. Just a few more than Sandi Metz’s five lines per method rule. The body of the revised version is a little closer at 9 lines (excluding whitespace):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def run
  @all_doors = set_up_doors

  contestants_initial_guess = contestants_first_guess
  revealed_door_number = reveal_door(contestants_initial_guess, @door_with_prize)
  final_guess = contestants_second_guess(contestants_initial_guess, revealed_door_number)

  prize_found = @all_doors[final_guess - 1][:value] == :car
  contestant_switched = (contestants_initial_guess != final_guess)
  switching_wouldve_helped = (@door_with_prize != contestants_initial_guess)

  display_game_results(final_guess, @door_with_prize, prize_found, switching_wouldve_helped)
  set_result(prize_found, contestant_switched)
end

Not only is this less lines of code, but also reads a lot better… going down the line of methods being called you see “set_up_doors”, “contestants_first_guess”, “reveal_door”, etc. and can see exactly how the flow of the simulation works.

Conclusion

I was hesitant to even look at my original program because I knew that there would be lots of cringe-worthy moments to be had. But it’s satisfying to be able to quickly identify elegant solutions to problems that used to give me a hassle – I’d recommend it as an exercise to anyone.

Autoloading Sass in Sinatra

You can use style injection when developing sinatra apps, allowing you to see css/sass changes without refreshing your browser.

This is especially helpful when doing responsive design, since you can have different sized browser windows open at the same time and see how each changes affects a particular viewport.

Getting Set Up

  1. Clone and bundle a preconfigured sample application that I created
  2. Install the appropriate livereload browser extension – there’s one for Chrome, Firefox, and Safari
  3. From the public/css directory, run sass --watch style.scss:style.css (this command could change as more sass files are added to the project)
  4. From the project root directory, run guard
  5. From the project root directory, run rackup
  6. You’re done! Now anytime you save a change style.scss, the style.css file gets updated and your browser will show its changes without reloading the page.

There’s a more detailed version of this writeup on the project readme. Special thanks to Matt Brictson’s excellent blog post, without which this tip would not be possible.

Launchctl “Nothing Found to Load”

When you get the error “nothing found to load” after running launchctl load. Example:

1
2
> launchctl load ~/Library/LaunchAgents/org.virtualbox.vboxwebsrv.plist
nothing found to load

First check to make sure the package isn’t listed as disabled in the global overrides file: /private/var/db/launchd.db/com.apple.launchd/overrides.plist

If the package isn’t listed in the overrides file, launchd documentation offers another file it may be located in. First get your user id by running id on the command line:

1
2
> id -u
201

Now look in this file: /var/db/launchd.db/com.apple.launchd.peruser.201/overrides.plist. The override entry should be listed in this file.

In the example given above for virtualbox, you would remove these lines from that overrides.plist file:

1
2
3
4
5
<key>org.virtualbox.vboxwebsvc</key>
<dict>
  <key>Disabled</key>
  <true/>
</dict>

RubyGems Versioning

From the RubyGems guide:

PATCH 0.0.x level changes for implementation level detail changes, such as small bug fixes

MINOR 0.x.0 level changes for any backwards compatible API changes, such as new functionality/features

MAJOR x.0.0 level changes for backwards incompatible API changes, such as changes that will break existing users code if they update

Gmail Snooze

I’m a huge fan of the app Mailbox for IOS. In my opinion, its killer feature is the ability to ‘snooze’ emails, so that they are hidden for the time being, but reappear when they are relevant again.

I wanted to have the same functionality through the Gmail web interface, and while googling I stumbled upon a Gmail blog post that explains just how to do that. It turns out that this has actually been available for quite some time (since 2011).

What surprised me even more is that you can write custom javascript scripts to process your email, and that these scripts can be executed on a recurring basis.

My 4 Stages of Version Control

Version control – it’s great. It’s also amazing how you don’t realize how much better it can be until you use a better tool. Personally, I like to think I’ve gone through 4 main “stages” of version control, each stage being a more useful and effective addition to my workflow than the previous.

Stage 1 – Local Backups

“Hmmmm, I’m planning on making a lot of change to this code, better make a copy of the file hello.cpp. I’ll call it hello2.cpp! I’m a genius!”

Stage 1 is every n00b’s favorite, just making another copy of the file. Something go horribly wrong while you were in that 4am coding frenzy? You’ve always got that copy lying around, assuming you had the foresight to make it.

Stage 2 – Offsite Backups

“Hey (insert programming partner’s name here), we’re going to need to share our code somehow! How about I work on it Friday night, then email you a zip file of my progress? Then you can work on it Saturday!”

Stage 2 is only slightly better than stage 1. As least you (and your partner) have a copy of the code the next time you spill some hot chocolate on your laptop.

Stage 3 – Centralized Version Control

“Wow, svn is really cool! You can make savepoints in your code?! Other people can get your code too, and contribute to it?!”

Using an actual version control system for the first time is mindblowing in the omg-why-didn’t-I-know-about-this-before kind of way. Once you realize how to commit and branch code, there’s no turning back.

Stage 4 – Distributed Version Control

“I don’t really get what the big deal is with git. I mean it’s pretty much the same as – oh wait, oh wait no it’s not. Ok. Yes. This is really cool. LET FREEDOM RING.”

Just when I was telling my friends how great svn is, git came along and changed everthing. Changes are stored extremely efficiently, making the act of pulling changes quick even when there are a lot of files modified. Branches with git are “cheap” in that they are easily mergeable with other branches. With git, life is good. With github, life is great. I’ll go into that more in another post.

Autostarting Homebrew Packages

Homebrew has made my life a lot easier when setting up new mac development environments. To install a new package is as easy as typing brew install mysql on the command line. (Other programs I commonly install with Homebrew are git, mongodb, and postgresql.)

Sometimes you want a program to start a daemon (background) process when you log in. For example, I can start mongodb’s daemon with the mongod command, but it’d be nicer if it just started automatically.

Fortunately Homebrew has a way to do this! Simply type brew info mongo. If mongod isn’t set up to run automatically, the last bit of output will look like this:

To have launchd start mongodb at login:
    ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents
Then to load mongodb now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
Or, if you don't want/need launchctl, you can just run:
    mongod

Note how you not only see how to start mongodb upon login, but also it shows you the name of mongo’s daemon process, mongod.