Skip to content
Aug 1 10

music utility now on github

by Stephen Mann

I’ve completed a music-transcription utility; it’s up on github.

It’s a command-line utility. It works thusly:

$> ./music -r c c eb f#

Finding matches scales for notes c eb f#:
    Eb min: 1.00
    Db min: 1.00
    Db maj: 1.00

Degrees of notes in c:
    c  : r
    eb : b3
    f# : #11

In this example I ask the program to analyse C, Eb, and F# in the context of the key of C. It returns that those notes, together, are in exactly 3 scales. It also tells me what degrees of the key of C those notes represent.

The code itself, in my opinion, is very clean. TDD followed; 100% code coverage; lots of small, well-defined classes; short methods; some amount of documentation; open-source.

Check it out, it’s all online.

Jul 17 10

Official move from Vim to Netbeans

by Stephen Mann

The better you know me the more shocked you will be to learn this: I am officially switching my primary programming environment from Vim to Netbeans.

And it’s all Martin Fowler’s fault.

Background

First, a bit of background. I currently use Vim for everything. Everything. I’m writing this post in it right now. It is, and will probably always continue to be, the best text editing environment ever devised. I will certainly continue to use it over ugly hacks like, for example, Word.

Vim is such a good text editor, such a good programmer’s text editor, that it has been able to meet all my programming and customization needs for the last year or so. I use it at home, and at work as my IDE.

Then, as I said, Martin Fowler stepped in.

The Problem

Problems began when I picked up his book, Refactoring. Being the excellent book it is, it naturally led me to want to refactor everything, constantly, and automatically. This led me on a hunt for good refactoring tools, and this led me to modern IDEs — with Netbeans being a fine example.

See, Vim is somewhat aware of syntax, but only on a regex level. For true refactoring assistance, the editor really needs to understand languages on an AST level. To my dismay, Vim does not have comprehensive plugins to solve this problem for every language I regularity use. Further, writing all those plugins would be, I think, more effort than it was worth.

And I so I follow the productivity fairy to Netbeans.

Making the Switch

At first I was tempted to use jVi, the excellent vim plugin for Netbeans. I ran into two — but really only two — problems. First, jVi selection is different from Netbeans selection. It’s irritation, distracting, and time-consuming to be constantly switching between the two types. Second, on a admittedly more emotional level, I wanted to sound Netbeans’ depths. Find out what it could do under its own steam. Be "pure" in my experiment.

So I thought about what it is in Vim that I really like, and boiled it down to two things.

  1. Hands remain on homerow. Now mouse or arrow keys needed.
  2. Quickly accomplish common programming tasks.

As it happed, Netbeans can handle both aspects.

Homerow

The solution was remapping everything, which was surprisingly easy. My currently (and will certainly change) layout on my mac:

CTRL +

shortcut action
h, j, k, l move cursor left, down, up, right (like in vim)
u, o move cursor to the previous, next word
y, p move cursor to beginning, end of line
,, . contract, expand selection
t, b top, bottom of document
e, d scroll screen up, down one line

Adding SHIFT to any combination (except the last) adds messing with the current selection.

Together, this relatively small set of shortcuts nicely solves my homerow problem (and, if I do say so myself, better than emacs solves it). This probably alone gives me 50% of why I like vim so much.

Common Programming Tasks

Vim is largely a generic tool that lets me solve any text editing problem quickly. Netbeans is specialized to solve most common programming tasks quickly. Apparently, when it comes to programming, I perform the same tasks as everybody else.

A quick example:

Programmers often need to rename a variable. Vim makes this easy for me: I select the scope I care about, and fire off a quick regex search-replace to change that word — thereby using generalized tools to solve the problem.

In Netbeans, I CTRL-R on the variable I want to rename, and type in the new name — using a highly specific tool to give me slightly faster and slightly more accurate results.

What I’m giving up

Leaving Vim for Netbeans, there are some things I’ll be giving up. In no particular order:

Speed. Vim is fast. It starts up fast, it runs fast. It waits for you, I’ve never waited for it. Netbeans takes long enough to start up that I get impatient. Also, sometimes it will randomly stop accepting input and start crunching on something behind the scenes that I may or may not have asked for.

Stability. Vim has only ever crashed on me, by which I mean I had to restart it, once — and that was when I was playing around with a broken plugin on several 200MB+ files. Netbeans has out-and-out crashed on me before, and required two restarts just in setting it up this week.

Consistency. Vim’s keybindings haven’t changed in 30 years (or whatever). What I learn on it will apply to every version of vim used by basically anyone anywhere, and for years to come. Netbeans’ interface is not anywhere near so stable. There will be new things to learn — and things to unlearn come every release.

Universality. Vim is installed by default on all OSs that really matter. Netbeans is an enormous, additional install.

One ring to rule them all. With Vim there was only one tool in my toolset: Vim. I learned one tool, and could apply that knowledge to anything I did on a computer. Now, with Netbeans, there are two camps to learn. Now I am master of none.

Customizability. Have a problem with vim? Change it. Between myriad options, remappings, new commands, and an easy-to-use plugin system, there’s really nothing about the editor you can’t change in an hour or two. Heck, I even wrote a typing tutor program in the editor. Netbeans proponents would no doubt argue that the same is true of Netbeans, but I would say that there is an important difference in ease.

No Dialog Boxes. I hate dialog boxes. Vim doesn’t have them. Netbeans has lots.

Aesthetic. When you’ve got a GNU Screen + Vim setup running fullscreen, it looks awesome: ASCII and ASCII alone, as far as the eye can see. With Netbeans, you’re just using an IDE.

Conclusion

Vim is a text-editing machine. Once you’ve mastered it, you can quickly solve text-related tasks no one’s ever thought of.

Netbeans is "just" a programming environment, and not really suited to say, writing blog posts. However, it’s very good at being a programming environment. It’s Extract Method functionality alone is worth making the switch for. When combined with its good custom keybinding functionality, its larger development community (meaning, as just one example, built-in live templates for everything under the sun), and the project’s overall attention-to-detail, I feel confident that I’ve made the right choice.

There will still be plenty of days, though, when I fire up vim to do something Netbeans will never be able to touch.

May 31 10

vim and ruby koans

by Stephen Mann

In this screencast I demonstrate the (okay, "a") vim way to work through the ruby_koans.

The crux of the method is vim’s awesome make command, which runs your makeprg (rake, in this case), hops you to the first error, and displays more information in the QuickFix window.

I can’t imagine a more streamlined system for working through the koans. I make a change, and "seeing if I’m right and moving on to the next assert" is only a single shortcut away (@: repeats the last command; I have it mapped to tab).

ruby_koans is an innovative and fun way to learn the ruby language. I highly recommend trying it out — with vim, of course.

May 21 10

vim: paste yanked text

by Stephen Mann

Vim automatically yanks all text into the "0 register, and deletes all text into the "1"9" registers.

This is handy if you want to yank out some useful text before deleting a section. Later, just "0p to drop the good bit where you want it.

But "0p is pretty awkward to type.

I created these alternate mappings today, which are both easier to type and have better mnemonics.

" put last yanked text
nmap yp "0p
nmap yP "0P
May 15 10

TortoiseTyping vim plugin

by Stephen Mann

I’ve successfully uploaded my first vim plugin! It’s a minimal typing tutor aimed at touch-typists who would like to spend a few minutes a week sharpening their skills. I’ve noticed, for myself, that for less than 10 minutes a week I can increase my average speed from around 50 to 85 WPM, which seems worthwhile.

This script is called TortoiseTyping because with typing its slow, steady, and accurate wins the race.

I enjoy vim so much, it feels good to be able to give something back, however small.

May 7 10

Automatically trim trailing whitespace in vim

by Stephen Mann

Trailing whitespace is never necessary. To remove it automatically every time you save a file, add this to your .vimrc:

" on save any: trim trailing whitespace
autocmd! BufWrite * mark ' | silent! %s/\s\+$// | norm ''

The regular expression should be clear to anyone familiar with regular expressions. The junk immediately before and after ensures that the cursor ends up where it started. The autocmd sets the command to fire on the BufWrite event for all files.

May 6 10

Improve S-expressions with python whitespace

by Stephen Mann

S-expressions are lisp’s great syntactical strength, and death-by-parentheses its greatest weakness. Why not take a page from python’s book and make whitespace significant?

The rules are simple. ( or ) add a newline. ( adds an indentation level, while ) removes one.

example 1

" old way
(a b c d)

" new way
a b c d

example 2

" old way
(a b (c d e (f g)))

" new way
a b
  c d e
    f g

example 3

" old way
(a b (c d (e f) g))

" new way
a b
  c d
    e f
  g

example 4

" some conventional pseudo language
if a == 0 then 1 + 2 else 3 + 4

" S-expression
(if (== a 0) (+ 1 2) (+ 3 4))

" new way
if
  == a 0
  + 1 2
  + 3 4

Even modern languages have extra syntactic junk floating around. Why not get rid of it?

Update: It was brought to my attention that this scheme breaks under some circumstances. Specifically, whenever two or more open parentheses appear in a row — (( — double indenting and ambiguity can occur.

There are two fixes, neither great.

  1. Make the using parentheses optional, so that they can be pulled out in the more complex situations. Haskell’s "on-sides" strategy works like this (though for different reasons), where curly braces and semicolons can be used — though in practice no ones does.
  2. In situations where (( would appear, introduce a place-holding element. Maybe a ., for example, between the two. My understanding of lisp is weak, but I think this might bear some resemblance to its let.

Both cases require disallowing the "((" situation.

May 4 10

PostgreSQL port woes on upgrade

by Stephen Mann

This consumed enough of my time that I thought I’d post something about it.

When I installed Ubuntu 10.04 my postgres bumped from 8.3 to 8.4. In order to avoid stomping on 8.3′s old ports, 8.4 silently moved from port 5432 to 5433 — which is great except for the "silent" part. The only indication I had of the change was everything exploding in my face.

To set 8.4′s port number back to 5432:

  1. create this line in your .bashrc

    export PGPORT=5432
    
  2. and change this line in /etc/postgresql/8.4/main/postgresql.conf

    port = 5432  # (change requires restart)
    
  3. I no longer trust the postgres restart, so restart with

    $ sudo service postgres-8.4 stop
    $ sudo service postgres-8.4 start
    

And, hopefully, your frustrations will end sooner than mine did.

May 1 10

One-line recursive python function

by Stephen Mann

The original challenge posed to me was to create a one-line recursive function in python. To reach this solution I started with this function

def shortAny(n):
  """Return if any of a list of bools are True."""
  if(n):
    if(n[0]):
      return True
    else:
      return shortAny(n[1:])
  else:
    return False

then "simplified" it to this

def shortAny(n): return bool(n) and (n[0] or shortAny(n[1:]))

# basic testing
T = True
f = False
assert shortAny([]) == f
assert shortAny([f]) == f
assert shortAny([T]) == T
assert shortAny([T, T]) == T
assert shortAny([T, f]) == T
assert shortAny([f, T]) == T
assert shortAny([f, f]) == f
assert shortAny([f, f, f]) == f
assert shortAny([T, f, f]) == T
assert shortAny([f, T, f]) == T
assert shortAny([f, f, T]) == T
assert shortAny([f, T, T]) == T
assert shortAny([T, T, f]) == T
assert shortAny([T, f, T]) == T
assert shortAny([T, T, T]) == T

This function would not have been possible without python’s short cutting feature for "and" and "or".

Note that this was an intellectual exercise, and that code like this should never really be written by anyone.

Apr 27 10

Simple python Rubik’s Cube timer

by Stephen Mann

In my quest for the sub-30 Rubik’s Cube solve, I realized that I needed data. To that end, I wrote the following python script. It times how long I take on each step of the solve, and provides depressing statistics afterwards.

Efforts were made to make the code as clear as possible. I received assistance from this guy.

#!/usr/bin/env python

import timeit

"""
Stephen Mann
April 2010

Terminal program for timing Rubik's Cube solves using a
modified Roux method.

Intended to be used as a bash utility.  Run chmod +x on the
file and drop it in your PATH somewhere.  Now the script can
be run from anywhere on the system with just

  $ cuberun

Credits
-------

Editing and suggestions from Adam Colton,

http://adamcolton.net

"""

stages = [
  "inspect",
  "left 2x2 block",
  "left 2x1 block",
  "right 2x2 block",
  "right 2x1 block",
  "permutate corners",
  "orient corners",
  "orient edges",
  "permutate R/L edges",
  "permutate M edges" ]

def wait(message):
  """
  Return how many seconds it takes the user to hit <enter>.
  Display message in meantime.
  """

  cmd = "raw_input('  %s')" % message
  return timeit.Timer(cmd).timeit(1)

print
print "========================================="
print "press <enter> after completing each stage"
print "========================================="

durs  = map(wait, stages)  # durations
nDurs = zip(durs, stages)  # named durations

total   = sum(durs)
slowest = max(nDurs)
fastest = min(nDurs)

print
print "results"
print "======="

for nDur in nDurs:
  print "%4.1f: %s" % nDur

print "total: %.1f seconds" % total
print
print 'slowest stage at %4.1f seconds was "%s"' % slowest
print 'fastest stage at %4.1f seconds was "%s"' % fastest