(Computer) keyboard is my piano
When exercising enough you can teach your fingers to perform certain complex actions in a way that, if you’re really good at it, you don’t feel any complexity anymore when executing them - you don’t even need to think about the movement of your fingers at all. As an example let’s take a guitar play. You don’t need to be an ultra skilled jazzman to play the guitar while enjoying the music more than thinking about and preparing for the moves your hand and your fingers are going to do in a couple of seconds. Briefly, when playing guitar, music is the thing you should concentrate on, not the moves of your fingers.
It’s pretty obvious that similarly as you can “teach” your fingers to play notes on a piano, you can do the same thing with the keyboard - when you are good at it it’s called the art of typewriting. On a piano, the first thing they usually teach you is to play individual notes of some particular scale and play them fast and without a mistake. After some exercising you are able to play some nice albeit simple melody. You can achieve the same thing with the typewriter. You start with a scale (the alphabet) and try to be as fast and error prone as possible when hitting the individual notes (keys).Programming is a conceptual effort, not manual
The business of a musician is to play music. Technique is very important, but it’s not the thing a skilled guitar player has in mind while playing (not practicing). It would disrupt him. It’s very similar with any other human effort that is conceptual rather than tangible in its nature. For example programming. When you program, you shouldn’t think about anything else but the matter of programming. Someone may say that the main concern of programming are computers. After a bit of thinking it’s not very difficult to come to a conclusion that this can’t be the case. If we really want to find any general theme that is common to every programming session, we’ll shortly conclude that concepts are the matter of programming. There is nothing tangible in programming, it’s a pure conceptual effort. At the beginning there is a problem to solve - a conceptual entity. At the end is a program - a conceptual entity - anything in between should be of the same matter. Yes, I know, in the end there’s always some kind of tangible thing, but that’s just because we haven’t taught the computers to read our minds, yet. Writing the program down is just a neccessary mechanic step that we have to undergo in order to see our program working. If you are a real craftsman you problably think ahead and plan your work before writing any code. In any case, the act of writing shouldn’t stay in your way when programming, it shouldn’t break your conceptual flow, so to say. Again, programming is a pure conceptual effort.
With that said, this post isn’t about programming, it’s about writing the programs down. More precisely, it’s about how to do it efficiently.Exploit the muscle memory
When you move your hand while writing with pen, you don’t need to think about all the moves your hand and its parts perform - you just think about the idea you want to write down. It is a natural human ability and really skilled artists just leverage it to their advantage. People often don’t realize it, but there is one particular thing responsible for this ability - it’s called muscle (or motor) memory. As a matter of fact, we all employ the powers of muscle memory from the early days of our lives. The fact that I don’t need to think about all that tiny sub-movements my arm, hand and fingers do when I reach for my cup of coffee, is caused by many and many hours of practice I went through when I was a child and the muscle memories I retained from that training. Although exploiting muscle memory is very natural to all humans as well as other animals only we humans exploit it in a very systematic way. And I’m not talking only about fast touch typing - think about all the sports, martial arts, crafts and all kinds of other activities. In many ways muscle memory is a priceless gift given to us by evolution for free. There are some crucial qualities of muscle memory that make it such a powerful weapon in many situations:
- unconscious - once you store an action in your muscle memory, you don’t need to think about it anymore, it’ll just pop up right when you need to perform it.
- universal - the fact that we have ten fingers on both hands and each of them has its own movement abilities, makes the number of all the possible movements and sequences virtually countless. Not to mention that the basic movements can be combined into more complex ones in an easy way. The same fingers that we employ while typing can be used to play piano or even to kill.
- fast - once you employ it for some action, the actual steps you go through, just vanish - they go out of your way. The path from an intention to its execution is very fast and painless. (In this sense muscle memory works similarly to cache. When one of your brain centers request another one to solve a task that can be solved by using muscle memory, the request doesn’t hit any calculation.)
By now, it should be quite clear what I’m up to here. I’d like to convince you to use the muscle memory for as much of your activities as possible, including the acts of writing computer programs.Ideal human-computer interface
These days, two prevailing kinds of computer UIs are in the use:
- text user interface (TUI) - where you invoke an action by hitting a key or a sequence or a combination of keys
- graphical user interface (GUI) - where you have a set of graphical components and invoke actions by manipulating these components (usually with the use of a computer mouse)
Most of the current UIs are hybrid - most GUI programs provide you with a set of keyboard shortcuts and you can usually take an advantage of a mouse in a TUI program (to some extent). In most people’s minds keyboard shortcuts are often viewed as something secondary, something you really don’t need to care about unless you really want to look like a pro. In fact, it should be the other way around.
The point I would like to state here is this:
You should prefer and try to learn as soon as possible the keyboard-fu (the keyboard shortcuts or text commands) of any application you use on a daily basis and if this application is of the kind you have open most of the day you should look around for its text UI alternative, if there is such a thing.
This rule is more applicable to contexts where the main purpose of the application is to support some kind of conceptual skill. For example programming is a purely conceptual skill, while designing is also visual and can be hardly executed only by hitting keys.
The main reason behind this statemet is that you just can’t exploit your muscle memory to its full extent when using GUIs. Why? When you use GUI and mainly a mouse for invoking some behaviour, you neccessarily have to employ your visual memory (you need to locate the gui component you are about to click), then you have to move your hand to grab the mouse and when moving the mouse, you have to dedicate at least a little bit of your concentration to the mouse cursor since you simply don’t know how to do it blind-folded (you don’t and can’t have any motor memories of this action, so you can’t execute them automatically). I know, all of these things happen very quickly and the gain you’ll get per one action is maybe a fraction of a second. However, think about the amount of time you spend with typing and the amount of such actions you perform every day!
But it’s not just about the time. When using tools that allow you to leverage your muscle memory (such as emacs or vim) the connection between your intention and the result of the action is direct - in psychological terms, your intentional object (the thing which occupies your mind) doesn’t change at all in the course of performing the action - you simply “outsource” the computation and execution of the task to your unsouscious capabilities. Because of this your mind and your workflow remains uninterrupted, which is very important. On the contrary, GUI based applications (or shall I say visual approach to invoking the actions in applications, ie. “find it in menu and click” approach) doesn’t allow you to this. At least not to the same extent. You might not realize it, but your mind has to juggle much much more when using GUI - eg. when using mouse to invoke some action in an application, the mind has to switch its intentional object couple of times.Don’t be afraid to throw away the ladder
I’m not here to argue whether GUIs are better than TUIs or vice versa. That would be just plain stupid as I think that both GUIs and TUIs have their own areas of uses. My point here, as said above, is that you should employ muscle memory whenever possible, since it’s very efficient (although it might not be cheap at the beginning) and can make work with an application much more enjoyable.
So, next time you’ll open up your favourite text editor, just try to think about all the visual UI components such as menus and buttons as if they were only some kind of visual hints that are there to help you to see and grasp all the editor’s features you might need in the future and not for using them forever. As Wittgenstein has put it: it’s a ladder that shold be thrown away once we had climbed up it.
Ruby Float vs. Fixnum gotcha
Be careful when doing some computation with integers (Fixnum in Ruby). If what you want as a result is supposed to be a float (Float) at least one of the operands has to be float as well.
irb> 1/2 => 0 irb> 1.to_f/2 => 0.5 irb> 1/2.to_f => 0.5
Resize images on the command line
Today, I needed to copy a large set of images from one of our servers to another. Beside of that, I wanted all of them to be converted - resized to fit my needs. It would be rather painful if I tried to download the whole thing to my local machine first, batch convert the files with some desktop application and then upload it to another server, since just the downloading part would last for at least four hours with the speed of my internet connection. After some research I came up with this solution:
find . -iname '*.jpg' -print0 | xargs -0 mogrify -resize 800x600\> -monitor -quality 80
With help of the ImageMagick package, this line does all the heavy lifting - it finds all the jpeg images in the directory (and its subdirectories) and then converts them to be no more than 800 by 600 px in size. Mogrify command rewrites the original files, so I needed to make a copy of the images directory.
After that I just used tar and sftp to send the size-reduced image directory to the other server.
Seinfeld Calendar in Google Spreadsheets
The New Year is not that new anymore and the New Year resolutions are slowly but certainly fading out in minds of more and more people, day by day. If you’re not motivated enough or your will is just weak, there are more than enough mind “hacks” to keep yourself motivated or remind you of the goals you have set for yourself to achieve. One of them is a Seinfield Calendar which is based on a simple idea of not breaking the chain of day-by-day achievements of the goal you are supposed to be doing. Just read the article on Life Hacker to get the idea.
What I’m bringing you here is my own implementation of a Seinfeld Calendar in Google Spreadsheets.
Its aim is to be as simple as possible (so, as the whole Seinfeld’s hack). The usage is simple, too. Just write “d” (done) for the day you have done something for your goal or write “f” (failed) for the day you haven’t done anything (or you can leave the field empty, if you like it more that way). For every goal you want to track, create a new sheet (just duplicate the first one) and rename it according the goal.
Now, just keep it green!
How to start writing tests, instantly
I wrote this post as a motivation for anybody trying to start with writing tests for their code but feels some kind of resistance or fear from doing the first steps. Both of these feelings are natural and reasonable. Doing testing right is not an easy task. The whole testing thing with all its terminology, tools, styles, philosophies, metrics etc. can feel a bit overwhelming, at first. And it really is. The good news is, though, that you don’t need to digest it all at once.Start small
As with every big problem there is a way to break it down and start with the small pieces first. At the end, every test is just a piece of code that exercises some other code. Do you feel any big concept in that? I’m sure not. So, how about just starting to write some little piece of code that exercises some other code you wrote? You do it all the time anyway, don’t you?
You don’t need to start with any “big” concepts such as TDD (test-first driven development) from the beginning. If you really want to give testing a shot and are lost (as I was when I started with testing just few months ago), start doing it in small unobtrusive steps. Next time you start working on some application (or just a new feature in an existing one) do the first step as usual - think about the feature you are about to code, code it and try to run it. Write as little code as possible, though. The aim is to have some solid piece of ground to stand on. When done, you can start to cover the code you just wrote with tests. I know, it’s quite difficult to decide what exactly to do when you stare at a blank test file, at first. But don’t fear. Just grab the first testing-belt (whatever testing library you’ll find in your closet) that suits you (which means, the first one you have or you think you can have some clue about) and throw the first little thing you think can have some effect on your code. Try to assert something or just grab something randomly if you think there’s no other way out and fire. It may work. Just do something! You’ll quickly learn to distinguish between good and wrong weapons for particular situations. You’ll be surprised how quickly these tools make sense when you use them actively.
Other great opportunity for doing experiments with testing is when you have some considerable piece of code already written - it may be some old nasty application, running for years - and some trouble strikes. You know it should work, but it doesn’t. So, you find the troublemaker and are about to fix it. Why not fill in some tests now to make sure you have that delicate piece of code under control? It’ll make you more confident, at least.Okay, but where to start anyway?
As for the question which kind of test you should write first (unit, functional, integration or whatever other kinds there are), the same rule applies - do whatever you think you have or can have some clue about. First, try to write for example some unit test. If you fail, just try something else. Maybe it’s best for you to start with some kind of general acceptance tests, like “when I call this url in the browser, I should see my name on the page somewhere.” There are tools and test-belts (eg. webrat for Ruby/Rails) you can use for writing this kind of tests, too. Just choose what makes sense to you. Any piece of code that tests something your application should do, is valuable and will rise your self-confidence about what you have done as well as your positive feelings about testing.Are tests just other stuff I have to write?
You may also think that you are going to do just “one more thing” on the top of all the other things you already do when you code. That is true. On the other hand, testing, when done properly, should minimize some other unpleasant activities you usually do while coding. After you’ll start doing it, you’ll notice eg. that you don’t switch between your editor and the browser that much anymore. You write tests and run them instantly in the background (automation of testing is usually very easy to set up in current testing frameworks) instead of switching between the windows and hiting F5 all the time (if you’re developing mainly for the web). You’ll find out that you don’t need to dig into your code with a debugger that much, anymore. And if you will need to work with your older code, you will find it much more comprehensible with the test code at hand. Your workflow should improve with testing, not break. Write tests only if it makes your life easier. Otherwise, it won’t make any sense. Tests are for you, the developer, in the first place.To sum it up …
Start writing tests whenever you have an opportunity to do it (ie. whenever you write some code). Choose any tool that makes sense to you and write any test that you feel could cover at least some tiny behavior of your application (don’t care about the coverage or any other scary terms from the day one). Don’t be afraid about primitive tests and trivial assertions - you’ll get more confidence as your test coverage will grow and you’ll become more and more happier as you’ll notice that you don’t need to hit F5 that often anymore. Think about testing in other positive terms - the better you are at it, the less time you need to spend with activities you don’t like (watching the spinning refresh icon in the browser, debugging) and more with things you love.