Nothing beats Dash for quickly checking dev documentation

Dash is an incredibly useful Mac app that I’d highly recommend all developers check out. It lets you instantly search developer documentation (devdocs) straight from your computer:

Dash.gif

You can configure it to check only the devdocs you use on a regular basis. For example, I have Dash configured to search the devdocs for SaaS, Rails 4, jQuery, HTML, jQuery UI, PHP, MySQL, CSS, JavaScript, Ruby, WordPress, Node.js, Lo-Dash, R, and D3.js. It supports over 150+ sets of documentation and also lets you generate your own. Dash also keeps the documentation automatically up to date as it changes.

If you want to constrain your search to a specific set of devdocs, you can prefix your search such as ruby:gsub and it will only check the Ruby docs.

I also set Cmd+Shift+D to load Dash so that I can pull it up while I’m coding, perform a search, and Alt+Tab back to Sublime without ever touching the mouse.

It’s free to try and $24.99 to buy. Give it a shot and rejoice that you’ll never again have to Google for documentation.

Using the ESLint Gem in Rails

ESLint is a popular linting utility for JavaScript. In this post I’ll show you how I use it in a Ruby on Rails app.

A quick intro to ESLint

ESLint lets  you specify how you want to style your JavaScript and it will then check your code and report any issues. For example, if you use the quotes rule to specify that you want to use single quotes everywhere, ESLint will check whether that’s true and report back anywhere you accidentally used double quotes.

Whether you’re a part of a team or working on a project by yourself, ESLint is a great way to ensure clean, consistent code and identify bugs before they ever make their way into production.

The ESLint Gem

Jon Kessler and Justin Force created a handy ESLint gem for Rails. You simplify create a configuration file in config/eslint.json, execute rake eslint:run, and it will check your application.js file for any issues.

If you’re looking for a solid eslint config file, check out the one we at Automattic use for Calypso.

Customing the workflow

I wound up customizing how I use the the gem for two reasons:

  1. The gem checks application.js which concatenates all of your JavaScript assets based on the manifest file. If your assets include third party scripts like jQuery, ESLint will wind up linting those as well which you probably don’t care about.
  2. Similarly, because all of your JavaScript files are concatenated in application.js, the line numbers that ESLint spits out in its report don’t correspond to the line numbers in the individual files, making it difficult to pinpoint the offending lines of code.

To account for this, I first moved all of the third party JavaScript files out of app/assets/javascripts and into app/assets/javascripts/lib. With them moved out of the javascripts directory, I then wrote a new Rake task that takes advantage of the gem’s ability to lint a single file:

With this in place, you can run rake lint:run and it will iterate over each of your JavaScript files within the javascripts directory and execute ESLint on each one:

$ rake lint:run

account.js
48:5 low indent Expected indentation of 3 tab chrs but found 4
49:5 low indent Expected indentation of 3 tab chrs but found 4
50:5 low indent Expected indentation of 3 tab chrs but found 4

interface.js
612:3 slow quote-props Unnecessarily quoted property `class` found
613:28 low quote-props Unnecessarily quoted property `class` found
915:1 low valid-jsdoc Missing JSDoc parameter type for 'reason'

If you also use ESLint in your Rails project, I’d love to hear more about your setup.

A Ruby script to download a backup of your Heroku app’s Postgres database

A little over 5 years ago I shared a script that I had written to download a local backup of a Heroku app. Heroku’s CLI and its capabilities have changed a lot since then so I want to share an updated version for anyone who might find it useful.

You can check it out on Github: Heroku Postgres Backup Downloader.

For example, I have a cron job set up to generate a daily backup of Lean Domain Search that uses it:

$ ruby heroku-pgbackup-downloader.rb leandomainsearch "/Users/matt/Projects/LeanDomainSearch/Heroku Backups/"
Running backup script for leandomainsearch...
 Capturing a new backup...
  New backup id: b282
 Downloading new backup...
Done

Screen Shot 2015-11-27 at 9.16.28 AM.png

I’ve never had to use the backups and hopefully never will, but having them provides an extra layer of protection in case any of my sites are compromised and the data winds up corrupted or lost.

If you have a different backup strategy for your Heroku apps, I’d love to learn more – drop me a note or leave a comment below. Thanks!

TetriNET Bot Source Code Published on Github

A few years ago I wrote about a bot I built in high school to play an online multiplayer Tetris game called TetriNET. The tl;dr is that I got into TetriNET with some friends, built a bot to automate the play, and eventually entered my school’s science fair with it and wound up making it to internationals. As you can imagine, I was pretty cool in high school…

Anyway, when I wrote the post Github was just getting off the ground and it didn’t even occur to me at the time to open source the code there; instead I just zipped up the Visual Basic Project (go VB6!) and linked to it from the post.

Happily, I have gained a little bit more experience with Git and Github since then so I took some to clean up the code (converting CRLF line endings to LF, spaces to tabs, etc) and finally published it.

You can check it out here if you’re curious: https://github.com/mattm/tetrinet-bot.

On that note, this is pretty much exactly what I looked like while checking out out my old code so keep in mind it was a long time ago :)…

A Simple Genetic Algorithm Written in Ruby

I recently started making my way through An Introduction to Genetic Algorithms by Melanie Mitchell. I’m not too far into it yet but I’ve been pleasantly surprised by how clearly the author explains each concept.

In the first chapter she outlines a simple algorithm that is the basis for most applications of genetic algorithms. There isn’t any code in the book so I decided to implement it on my own in Ruby to understand it better:

The algorithm as described in the book is quoted below with my comments following each section.

1. Start with a randomly generated population of n l-bit chromosomes (candidate solutions to a problem).

In this code, n is represented by the POPULATION_SIZE constant and l by NUM_BITS. The initial randomly generated population is created using the Population’s seed! method.

2. Calculate the fitness f(x) of each chromosome x in the population.

The fitness of a Chromosome can be calculated by its fitness method. In this example, the fitness is simply the number of 1’s that the chromosome contains.

3. Repeat the following steps until n offspring have been created:

a. Select a pair of parent chromosomes from the current population, the probability of selection being an increasing function of fitness. Selection is done “with replacement,” meaning that the same chromosome can be selected more than once to become a parent.

A chromosome is chosen from the population using the Population’s select method. This method implements fitness-proportionate selection using roulette-wheel sampling which is conceptually equivalent to giving each individual a slice of a circular roulette wheel equal in area to the individual’s fitness. The roulette wheel is spun, the ball comes to resent on one wedge-shaped slice, and the corresponding individual is selected.

b. With probability Pc (the “crossover probability” or “crossover rate”), cross over the pair at a randomly chosen point (chosen with uniform probability) to form two offspring. If no crossover takes place, form two offspring that are exact copies of their respective parents.

The crossover probability is defined by CROSSOVER_RATE. The crossover is performed by the Chromosome’s bitwise AND (&) operator which I overloaded for this class.

c. Mutate the two offspring at each locus with probability Pm (the mutation probability or mutation rate), and place the resulting chromosomes in the new population. If n is odd, one new population member can be discarded at random.

The mutation rate is defined by the MUTATION_RATE constant. The mutation is performed by the Chromosome’s mutate! method.

4. Replace the current population with the new population.

5. Go to step 2.

Here are the results for 1,000 generations where the population is 24, the number of bits per chromosome is 64, the mutation rate is 0.001, and the crossover rate is 0.7. Pay attention to the average value over time:

Generation 1 - Average: 32 - Max: 40
Generation 2 - Average: 33 - Max: 38
Generation 3 - Average: 34 - Max: 41
Generation 4 - Average: 34 - Max: 37
Generation 5 - Average: 34 - Max: 41
Generation 6 - Average: 35 - Max: 39
Generation 7 - Average: 34 - Max: 43
Generation 8 - Average: 35 - Max: 45
Generation 9 - Average: 36 - Max: 44
Generation 10 - Average: 37 - Max: 44
...
Generation 990 - Average: 49 - Max: 50
Generation 991 - Average: 49 - Max: 50
Generation 992 - Average: 49 - Max: 51
Generation 993 - Average: 49 - Max: 51
Generation 994 - Average: 49 - Max: 51
Generation 995 - Average: 49 - Max: 50
Generation 996 - Average: 49 - Max: 50
Generation 997 - Average: 48 - Max: 50
Generation 998 - Average: 48 - Max: 50
Generation 999 - Average: 48 - Max: 50
Generation 1000 - Average: 48 - Max: 50

The average fitness of the population increases from 32 initially to 48 by the 1,000th generation, just as you’d expect for a population slowly becoming more fit over time.

If this interests you, I encourage you to try it yourself and experiment with different values for MUTATION_RATE, POPULATION_SIZE, and NUM_BITS.

For example, increasing the mutation rate from 0.001 (1 in 1,000) to 0.01 (1 in 100) has the following effect on the average fitness over time:

Given the impact that the mutation rate has on long term fitness of the population, how can we determine what the optimal mutation rate is? Can the chromosome’s mutation rate change over time? Can different sections of the chromosome evolve to have different mutation rates? What about the number of bits or the population size? These are a few of the things I hope to find out :)

Beware of The Good Idea Fairy

5goodideafairyWhen I was in the Air Force I had one assignment where I worked closely with a lieutenant colonel who was a self-proclaimed “good idea fairy”.

Every time we had a meeting he would interrupt to tell us about some idea he had just thought of that might be able to help with what we were working on.

The conversations would go something like this:

Us: The bus was half an hour late to pick up the technicians today because it had a flat tire and the driver had to go pick up another vehicle.

Him: Every technician should have his own vehicle so that we never have to deal with this again.

Each time he suggested a half thought-out idea, we would have to take time to consider it and the consequences of implementing it.

Us: Does every technician really need his own vehicle?

Us: Do the technicians have a government drivers license so that they can drive the vehicle?

Us: Does transportation have enough vehicles to lend out to one or more of the technicians?

Us: If we give the technicians a vehicle, other teams may want a vehicle of their own as well. Do we really want to go down this route?

And so on and so on. It’s not that his solution was terrible, but that a little bit of extra consideration would have led him to realize that there were a lot of practical problems with it. Instead, we were constantly being side-tracked by discussions about whether or not his ideas had merit. Most of the time, because they were not well thought-out, they didn’t.

He took pride in being a “good idea fairy” and every now and then he did have good solution, but most of the time his poorly considered solutions caused us to waste more time than they saved.

When you are holding a meeting, you want to encourage participation from the attendees and if you are constantly shooting down someone’s ideas, it might discourage others from speaking up in the future. Because of his rank and position and because we didn’t want to discourage people from speaking up, I don’t think anyone ever spoke to him about it, but I’ve always thought back on that when an idea pops into my head in the middle of a discussion.

The question then is how do you encourage creative solutions but also cut down on the number of Good Idea Fairy ideas? I don’t know — maybe you can’t. Maybe in order to discover gems you have to sift through a lot of dirt. Maybe that’s just part of the collaborative problem solving process.

What do you think? Is there a way to cut down on the number of Good Idea Fairy ideas while still encouraging people to speak up when they have a potential solution to a problem?